* [PATCH v2 0/8] media: qcom: camss: Add sm8550 support
@ 2024-03-20 14:11 Depeng Shao
2024-03-20 14:11 ` [PATCH v2 1/8] media: qcom: camss: Add CAMSS_8550 enum Depeng Shao
` (8 more replies)
0 siblings, 9 replies; 31+ messages in thread
From: Depeng Shao @ 2024-03-20 14:11 UTC (permalink / raw)
To: rfoss, todor.too, bryan.odonoghue, andersson, konrad.dybcio,
mchehab, quic_yon
Cc: quic_depengs, linux-kernel, linux-media, linux-arm-msm
V2:
- Update some commit messages
Link to V1: https://lore.kernel.org/all/20240320134227.16587-1-quic_depengs@quicinc.com/
V1:
SM8550 is a Qualcomm flagship SoC. This series adds support to
bring up the CSIPHY, CSID, VFE/RDI interfaces in SM8550.
SM8550 provides
- 3 x VFE, 3 RDI per VFE
- 2 x VFE Lite, 4 RDI per VFE
- 3 x CSID
- 2 x CSID Lite
- 8 x CSI PHY
This series is rebased based on:
https://patchew.org/linux/20240222-b4-camss-sc8280xp-v6-0-0e0e6a2f8962@linaro.org/
The changes are verified on SM8550 AIM300 board, the base dts for AIM300 is:
https://patchew.org/linux/20231117101817.4401-1-quic._5Ftengfan@quicinc.com/
Depeng Shao (3):
media: qcom: camss: Add new params for csid_device
media: qcom: camss: Add CSID gen3 driver
media: qcom: camss: Add sm8550 support
Yongsheng Li (5):
media: qcom: camss: Add CAMSS_8550 enum
media: qcom: camss: Add subdev notify support
media: qcom: camss: Add new csiphy driver 2-1-2
media: qcom: camss: Add new VFE driver for SM8550
media: qcom: camss: Add sm8550 resources
drivers/media/platform/qcom/camss/Makefile | 3 +
.../platform/qcom/camss/camss-csid-gen3.c | 639 ++++++++++++++++++
.../platform/qcom/camss/camss-csid-gen3.h | 26 +
.../media/platform/qcom/camss/camss-csid.c | 19 +
.../media/platform/qcom/camss/camss-csid.h | 10 +
.../platform/qcom/camss/camss-csiphy-2-1-2.c | 343 ++++++++++
.../media/platform/qcom/camss/camss-csiphy.c | 1 +
.../media/platform/qcom/camss/camss-csiphy.h | 3 +
.../media/platform/qcom/camss/camss-vfe-780.c | 455 +++++++++++++
drivers/media/platform/qcom/camss/camss-vfe.c | 7 +
drivers/media/platform/qcom/camss/camss-vfe.h | 3 +
.../media/platform/qcom/camss/camss-video.c | 1 +
drivers/media/platform/qcom/camss/camss.c | 395 +++++++++++
drivers/media/platform/qcom/camss/camss.h | 8 +
14 files changed, 1913 insertions(+)
create mode 100644 drivers/media/platform/qcom/camss/camss-csid-gen3.c
create mode 100644 drivers/media/platform/qcom/camss/camss-csid-gen3.h
create mode 100644 drivers/media/platform/qcom/camss/camss-csiphy-2-1-2.c
create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-780.c
--
2.17.1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v2 1/8] media: qcom: camss: Add CAMSS_8550 enum
2024-03-20 14:11 [PATCH v2 0/8] media: qcom: camss: Add sm8550 support Depeng Shao
@ 2024-03-20 14:11 ` Depeng Shao
2024-03-20 14:50 ` Bryan O'Donoghue
2024-03-20 15:51 ` Krzysztof Kozlowski
2024-03-20 14:11 ` [PATCH v2 2/8] media: qcom: camss: Add subdev notify support Depeng Shao
` (7 subsequent siblings)
8 siblings, 2 replies; 31+ messages in thread
From: Depeng Shao @ 2024-03-20 14:11 UTC (permalink / raw)
To: rfoss, todor.too, bryan.odonoghue, andersson, konrad.dybcio,
mchehab, quic_yon
Cc: quic_depengs, linux-kernel, linux-media, linux-arm-msm
From: Yongsheng Li <quic_yon@quicinc.com>
Adds a CAMSS SoC identifier for the sm8550.
Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
---
drivers/media/platform/qcom/camss/camss.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index ac15fe23a702..2f63206a8463 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -78,6 +78,7 @@ enum camss_version {
CAMSS_845,
CAMSS_8250,
CAMSS_8280XP,
+ CAMSS_8550,
};
enum icc_count {
--
2.17.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v2 2/8] media: qcom: camss: Add subdev notify support
2024-03-20 14:11 [PATCH v2 0/8] media: qcom: camss: Add sm8550 support Depeng Shao
2024-03-20 14:11 ` [PATCH v2 1/8] media: qcom: camss: Add CAMSS_8550 enum Depeng Shao
@ 2024-03-20 14:11 ` Depeng Shao
2024-03-20 16:08 ` Bryan O'Donoghue
2024-03-20 14:11 ` [PATCH v2 3/8] media: qcom: camss: Add new csiphy driver 2-1-2 Depeng Shao
` (6 subsequent siblings)
8 siblings, 1 reply; 31+ messages in thread
From: Depeng Shao @ 2024-03-20 14:11 UTC (permalink / raw)
To: rfoss, todor.too, bryan.odonoghue, andersson, konrad.dybcio,
mchehab, quic_yon
Cc: quic_depengs, linux-kernel, linux-media, linux-arm-msm
From: Yongsheng Li <quic_yon@quicinc.com>
The buf done irq and register update register are moved
to CSID in SM8550, so but the write master configuration
in VFE, in case adapt existing code logic. So add buf
done and register related subdev event, and use the notify
interface in the v4l2_device structure to communicate
between CSID and VFE driver.
Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
---
.../media/platform/qcom/camss/camss-csid.h | 7 +++
.../media/platform/qcom/camss/camss-csiphy.h | 2 +
drivers/media/platform/qcom/camss/camss-vfe.h | 2 +
drivers/media/platform/qcom/camss/camss.c | 50 +++++++++++++++++++
drivers/media/platform/qcom/camss/camss.h | 7 +++
5 files changed, 68 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index fddccb69da13..4a9e5a2d1f92 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -147,6 +147,13 @@ struct csid_hw_ops {
* @csid: CSID device
*/
void (*subdev_init)(struct csid_device *csid);
+
+ /*
+ * event - receive event from parent v4l2 device
+ * @csid: CSID device
+ */
+ void (*event)(struct csid_device *csid,
+ unsigned int evt_type, void *arg);
};
struct csid_device {
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
index c9b7fe82b1f0..ffe1b95eea98 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.h
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
@@ -61,6 +61,8 @@ struct csiphy_hw_ops {
void (*lanes_disable)(struct csiphy_device *csiphy,
struct csiphy_config *cfg);
irqreturn_t (*isr)(int irq, void *dev);
+ void (*event)(struct csiphy_device *csiphy,
+ unsigned int evt_type, void *arg);
};
struct csiphy_device {
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index 0572c9b08e11..9919fe0ff101 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -115,6 +115,8 @@ struct vfe_hw_ops {
int (*vfe_halt)(struct vfe_device *vfe);
void (*violation_read)(struct vfe_device *vfe);
void (*vfe_wm_stop)(struct vfe_device *vfe, u8 wm);
+ void (*event)(struct vfe_device *vfe,
+ unsigned int evt_type, void *arg);
};
struct vfe_isr_ops {
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 1923615f0eea..b57cd25bf6c7 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1904,6 +1904,55 @@ static void camss_genpd_cleanup(struct camss *camss)
dev_pm_domain_detach(camss->genpd, true);
}
+static void camss_v4l2_subdev_notify(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ struct v4l2_device *v4l2_dev = sd->v4l2_dev;
+ struct camss *camss = to_camss(v4l2_dev);
+ struct vfe_device *vfe;
+ struct vfe_line *vfe_line;
+ struct csid_device *csid;
+ int evt_data = *(int *)arg;
+
+ if (camss->res->version != CAMSS_8550)
+ return;
+
+ switch (cmd) {
+ case NOTIFY_BUF_DONE:
+ csid = v4l2_get_subdevdata(sd);
+ vfe = &(camss->vfe[csid->id]);
+ if (vfe->ops->event)
+ vfe->ops->event(vfe,
+ NOTIFY_BUF_DONE, (void *)&evt_data);
+ break;
+
+ case NOTIFY_RUP:
+ vfe_line = v4l2_get_subdevdata(sd);
+ vfe = to_vfe(vfe_line);
+ csid = &(camss->csid[vfe->id]);
+
+ if (csid->ops->event)
+ csid->ops->event(csid,
+ NOTIFY_RUP, (void *)&evt_data);
+ break;
+
+ case NOTIFY_RUP_CLEAR:
+ vfe_line = v4l2_get_subdevdata(sd);
+ vfe = to_vfe(vfe_line);
+ csid = &(camss->csid[vfe->id]);
+
+ if (csid->ops->event)
+ csid->ops->event(csid,
+ NOTIFY_RUP_CLEAR, (void *)&evt_data);
+
+ break;
+
+ default:
+ dev_err(camss->dev, "Not supported evt type\n");
+ break;
+ }
+}
+
/*
* camss_probe - Probe CAMSS platform device
* @pdev: Pointer to CAMSS platform device
@@ -1974,6 +2023,7 @@ static int camss_probe(struct platform_device *pdev)
media_device_init(&camss->media_dev);
camss->v4l2_dev.mdev = &camss->media_dev;
+ camss->v4l2_dev.notify = camss_v4l2_subdev_notify;
ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);
if (ret < 0) {
dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index 2f63206a8463..f1fe68dedd9e 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -86,6 +86,13 @@ enum icc_count {
ICC_SM8250_COUNT = 4,
};
+enum subdev_notify_evt {
+ NOTIFY_BUF_DONE = 0,
+ NOTIFY_RUP,
+ NOTIFY_RUP_CLEAR,
+ NOTIFY_MAX,
+};
+
struct camss_resources {
enum camss_version version;
const char *pd_name;
--
2.17.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v2 3/8] media: qcom: camss: Add new csiphy driver 2-1-2
2024-03-20 14:11 [PATCH v2 0/8] media: qcom: camss: Add sm8550 support Depeng Shao
2024-03-20 14:11 ` [PATCH v2 1/8] media: qcom: camss: Add CAMSS_8550 enum Depeng Shao
2024-03-20 14:11 ` [PATCH v2 2/8] media: qcom: camss: Add subdev notify support Depeng Shao
@ 2024-03-20 14:11 ` Depeng Shao
2024-03-20 15:21 ` Bryan O'Donoghue
2024-03-20 14:11 ` [PATCH v2 4/8] media: qcom: camss: Add new params for csid_device Depeng Shao
` (5 subsequent siblings)
8 siblings, 1 reply; 31+ messages in thread
From: Depeng Shao @ 2024-03-20 14:11 UTC (permalink / raw)
To: rfoss, todor.too, bryan.odonoghue, andersson, konrad.dybcio,
mchehab, quic_yon
Cc: quic_depengs, linux-kernel, linux-media, linux-arm-msm
From: Yongsheng Li <quic_yon@quicinc.com>
The CSIPHY register offset of SM8550 is different with
SM8250, so add a new driver for the SM8550 platform.
Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
Co-developed-by: Depeng Shao <depengs@qti.qualcomm.com>
Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
---
drivers/media/platform/qcom/camss/Makefile | 1 +
.../platform/qcom/camss/camss-csiphy-2-1-2.c | 343 ++++++++++++++++++
.../media/platform/qcom/camss/camss-csiphy.h | 1 +
3 files changed, 345 insertions(+)
create mode 100644 drivers/media/platform/qcom/camss/camss-csiphy-2-1-2.c
diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
index 0d4389ab312d..28eba4bf3e38 100644
--- a/drivers/media/platform/qcom/camss/Makefile
+++ b/drivers/media/platform/qcom/camss/Makefile
@@ -9,6 +9,7 @@ qcom-camss-objs += \
camss-csid-gen2.o \
camss-csiphy-2ph-1-0.o \
camss-csiphy-3ph-1-0.o \
+ camss-csiphy-2-1-2.o \
camss-csiphy.o \
camss-ispif.o \
camss-vfe-4-1.o \
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-2-1-2.c b/drivers/media/platform/qcom/camss/camss-csiphy-2-1-2.c
new file mode 100644
index 000000000000..df7860d7a4f4
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-csiphy-2-1-2.c
@@ -0,0 +1,343 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-csiphy-2-1-2.c
+ *
+ * Qualcomm MSM Camera Subsystem - CSIPHY Module 3phase v2.0
+ *
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "camss.h"
+#include "camss-csiphy.h"
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+
+#define CSIPHY_CMN_CSI_COMMON_CTRLn(n) (0x1000 + 0x4 * (n))
+#define CSIPHY_CMN_CSI_COMMON_CTRL5_CLK_ENABLE BIT(7)
+#define CSIPHY_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B BIT(0)
+#define CSIPHY_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID BIT(1)
+#define CSIPHY_CMN_CSI_COMMON_CTRL7_CONTROL 0x7A
+#define CSIPHY_CMN_CSI_COMMON_CTRL0_PHY_SW_RESET BIT(0)
+#define CSIPHY_CMN_CSI_COMMON_CTRL0_SWI_ENABLE_LANESYNC BIT(1)
+#define CSIPHY_CMN_CSI_COMMON_STATUSn(n) (0x10B0 + 0x4 * (n))
+
+#define CSIPHY_DEFAULT_PARAMS 0
+#define CSIPHY_LANE_ENABLE 1
+#define CSIPHY_SETTLE_CNT_LOWER_BYTE 2
+#define CSIPHY_SETTLE_CNT_HIGHER_BYTE 3
+#define CSIPHY_DNP_PARAMS 4
+#define CSIPHY_2PH_REGS 5
+#define CSIPHY_3PH_REGS 6
+
+struct csiphy_reg_t {
+ s32 reg_addr;
+ s32 reg_data;
+ s32 delay;
+ u32 csiphy_param_type;
+};
+
+/* 2.1.2 2PH */
+static const struct
+csiphy_reg_t lane_regs_sm8550[5][20] = {
+ {
+ {0x0E90, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0E98, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0E94, 0x07, 0x01, CSIPHY_DEFAULT_PARAMS},
+ {0x00A0, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0090, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0098, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0094, 0x07, 0x01, 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, 0x01, 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, 0x01, 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, 0x01, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0E10, 0x52, 0x00, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0010, 0x52, 0x00, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0410, 0x52, 0x00, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0810, 0x52, 0x00, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0C10, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0094, 0xD7, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x005C, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0060, 0xBD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0064, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0494, 0xD7, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x045C, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0460, 0xBD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0464, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0894, 0xD7, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x085C, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0860, 0xBD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0864, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0C94, 0xD7, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0C5C, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0C60, 0xBD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0C64, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ }
+};
+
+static void csiphy_hw_version_read(struct csiphy_device *csiphy,
+ struct device *dev)
+{
+ u32 hw_version;
+
+ writel(CSIPHY_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID,
+ csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(6));
+
+ hw_version = readl_relaxed(csiphy->base +
+ CSIPHY_CMN_CSI_COMMON_STATUSn(12));
+ hw_version |= readl_relaxed(csiphy->base +
+ CSIPHY_CMN_CSI_COMMON_STATUSn(13)) << 8;
+ hw_version |= readl_relaxed(csiphy->base +
+ CSIPHY_CMN_CSI_COMMON_STATUSn(14)) << 16;
+ hw_version |= readl_relaxed(csiphy->base +
+ CSIPHY_CMN_CSI_COMMON_STATUSn(15)) << 24;
+
+ dev_info(dev, "CSIPHY 3PH HW Version = 0x%08x\n", hw_version);
+}
+
+/*
+ * csiphy_reset - Perform software reset on CSIPHY module
+ * @csiphy: CSIPHY device
+ */
+static void csiphy_reset(struct csiphy_device *csiphy)
+{
+ writel_relaxed(0x1, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(0));
+ usleep_range(5000, 8000);
+ writel_relaxed(0x0, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(0));
+}
+
+static irqreturn_t csiphy_isr(int irq, void *dev)
+{
+ struct csiphy_device *csiphy = dev;
+ int i;
+
+ for (i = 0; i < 11; i++) {
+ int c = i + 22;
+ u8 val = readl_relaxed(csiphy->base +
+ CSIPHY_CMN_CSI_COMMON_STATUSn(i));
+
+ writel_relaxed(val, csiphy->base +
+ CSIPHY_CMN_CSI_COMMON_CTRLn(c));
+ }
+
+ writel_relaxed(0x1, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(10));
+ writel_relaxed(0x0, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(10));
+
+ for (i = 22; i < 33; i++)
+ writel_relaxed(0x0, csiphy->base +
+ CSIPHY_CMN_CSI_COMMON_CTRLn(i));
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * csiphy_settle_cnt_calc - Calculate settle count value
+ *
+ * Helper function to calculate settle count value. This is
+ * based on the CSI2 T_hs_settle parameter which in turn
+ * is calculated based on the CSI2 transmitter link frequency.
+ *
+ * Return settle count value or 0 if the CSI2 link frequency
+ * is not available
+ */
+static u8 csiphy_settle_cnt_calc(s64 link_freq, u32 timer_clk_rate)
+{
+ u32 ui; /* ps */
+ u32 timer_period; /* ps */
+ u32 t_hs_prepare_max; /* ps */
+ u32 t_hs_settle; /* ps */
+ u8 settle_cnt;
+
+ if (link_freq <= 0)
+ return 0;
+
+ ui = div_u64(1000000000000LL, link_freq);
+ ui /= 2;
+ t_hs_prepare_max = 85000 + 6 * ui;
+ t_hs_settle = t_hs_prepare_max;
+
+ timer_period = div_u64(1000000000000LL, timer_clk_rate);
+ settle_cnt = t_hs_settle / timer_period - 6;
+
+ return settle_cnt;
+}
+
+static void csiphy_config_lanes(struct csiphy_device *csiphy,
+ u8 settle_cnt)
+{
+ const struct csiphy_reg_t *r;
+ int i, l, array_size;
+ u32 val;
+
+ switch (csiphy->camss->res->version) {
+ case CAMSS_8550:
+ r = &lane_regs_sm8550[0][0];
+ array_size = ARRAY_SIZE(lane_regs_sm8550[0]);
+ break;
+ default:
+ WARN(1, "unknown csi version\n");
+ return;
+ }
+
+ for (l = 0; l < 5; l++) {
+ for (i = 0; i < array_size; i++, r++) {
+ switch (r->csiphy_param_type) {
+ case CSIPHY_SETTLE_CNT_LOWER_BYTE:
+ val = settle_cnt & 0xff;
+ break;
+ case CSIPHY_DNP_PARAMS:
+ continue;
+ default:
+ val = r->reg_data;
+ break;
+ }
+ writel_relaxed(val, csiphy->base + r->reg_addr);
+
+ if (r->delay > 0)
+ udelay(r->delay);
+ }
+ }
+}
+
+static u8 csiphy_get_lane_mask(struct csiphy_lanes_cfg *lane_cfg)
+{
+ u8 lane_mask;
+ int i;
+
+ for (i = 0; i < lane_cfg->num_data; i++)
+ lane_mask |= 1 << lane_cfg->data[i].pos;
+
+ return lane_mask;
+}
+
+static void csiphy_lanes_enable(struct csiphy_device *csiphy,
+ struct csiphy_config *cfg,
+ s64 link_freq, u8 lane_mask)
+{
+ struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg;
+ u8 settle_cnt;
+ u8 val = 0;
+ int i;
+
+ settle_cnt = csiphy_settle_cnt_calc(link_freq, csiphy->timer_clk_rate);
+
+ val = CSIPHY_CMN_CSI_COMMON_CTRL5_CLK_ENABLE;
+ for (i = 0; i < c->num_data; i++)
+ val |= BIT(c->data[i].pos * 2);
+
+ writel_relaxed(val, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(5));
+
+ val = CSIPHY_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B;
+ writel_relaxed(val, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(6));
+
+ val = 0x2;
+ writel_relaxed(val, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(7));
+
+ val = 0x0;
+ writel_relaxed(val, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(0));
+
+ csiphy_config_lanes(csiphy, settle_cnt);
+
+ /* IRQ_MASK registers - disable all interrupts */
+ for (i = 11; i < 22; i++)
+ writel_relaxed(0, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(i));
+}
+
+static void csiphy_lanes_disable(struct csiphy_device *csiphy,
+ struct csiphy_config *cfg)
+{
+ writel_relaxed(0, csiphy->base +
+ CSIPHY_CMN_CSI_COMMON_CTRLn(5));
+
+ writel_relaxed(0, csiphy->base +
+ CSIPHY_CMN_CSI_COMMON_CTRLn(6));
+}
+
+const struct csiphy_hw_ops csiphy_ops_2_1_2 = {
+ .get_lane_mask = csiphy_get_lane_mask,
+ .hw_version_read = csiphy_hw_version_read,
+ .reset = csiphy_reset,
+ .lanes_enable = csiphy_lanes_enable,
+ .lanes_disable = csiphy_lanes_disable,
+ .isr = csiphy_isr,
+ .event = NULL,
+};
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
index ffe1b95eea98..286fdb9f4fdf 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.h
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
@@ -98,5 +98,6 @@ void msm_csiphy_unregister_entity(struct csiphy_device *csiphy);
extern const struct csiphy_hw_ops csiphy_ops_2ph_1_0;
extern const struct csiphy_hw_ops csiphy_ops_3ph_1_0;
+extern const struct csiphy_hw_ops csiphy_ops_2_1_2;
#endif /* QC_MSM_CAMSS_CSIPHY_H */
--
2.17.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v2 4/8] media: qcom: camss: Add new params for csid_device
2024-03-20 14:11 [PATCH v2 0/8] media: qcom: camss: Add sm8550 support Depeng Shao
` (2 preceding siblings ...)
2024-03-20 14:11 ` [PATCH v2 3/8] media: qcom: camss: Add new csiphy driver 2-1-2 Depeng Shao
@ 2024-03-20 14:11 ` Depeng Shao
2024-03-20 15:26 ` Bryan O'Donoghue
2024-03-20 15:53 ` Krzysztof Kozlowski
2024-03-20 14:11 ` [PATCH v2 5/8] media: qcom: camss: Add CSID gen3 driver Depeng Shao
` (4 subsequent siblings)
8 siblings, 2 replies; 31+ messages in thread
From: Depeng Shao @ 2024-03-20 14:11 UTC (permalink / raw)
To: rfoss, todor.too, bryan.odonoghue, andersson, konrad.dybcio,
mchehab, quic_yon
Cc: quic_depengs, linux-kernel, linux-media, linux-arm-msm
CSID gen3 has a new register block which is named as
CSID top, it controls the output of CSID, since the
CSID can connect to SFE or original VFE in CSID gen3.
The register update is moved to CSID from VFE in CSID
gen3.
So, adding top_base and reg_update variables in csid
device structure for CSID gen3.
Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
---
drivers/media/platform/qcom/camss/camss-csid.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index 4a9e5a2d1f92..ca654b007441 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -162,7 +162,9 @@ struct csid_device {
struct v4l2_subdev subdev;
struct media_pad pads[MSM_CSID_PADS_NUM];
void __iomem *base;
+ void __iomem *top_base;
u32 irq;
+ u32 reg_update;
char irq_name[30];
struct camss_clock *clock;
int nclocks;
--
2.17.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v2 5/8] media: qcom: camss: Add CSID gen3 driver
2024-03-20 14:11 [PATCH v2 0/8] media: qcom: camss: Add sm8550 support Depeng Shao
` (3 preceding siblings ...)
2024-03-20 14:11 ` [PATCH v2 4/8] media: qcom: camss: Add new params for csid_device Depeng Shao
@ 2024-03-20 14:11 ` Depeng Shao
2024-03-20 15:40 ` Bryan O'Donoghue
2024-03-20 14:11 ` [PATCH v2 6/8] media: qcom: camss: Add new VFE driver for SM8550 Depeng Shao
` (3 subsequent siblings)
8 siblings, 1 reply; 31+ messages in thread
From: Depeng Shao @ 2024-03-20 14:11 UTC (permalink / raw)
To: rfoss, todor.too, bryan.odonoghue, andersson, konrad.dybcio,
mchehab, quic_yon
Cc: quic_depengs, linux-kernel, linux-media, linux-arm-msm
The CSID in SM8550 is gen3, it has new register
offset and new functionality, the buf done irq,
register update and reset is moved to CSID gen3.
Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
Co-developed-by: Yongsheng Li <quic_yon@quicinc.com>
Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
---
drivers/media/platform/qcom/camss/Makefile | 1 +
.../platform/qcom/camss/camss-csid-gen3.c | 639 ++++++++++++++++++
.../platform/qcom/camss/camss-csid-gen3.h | 26 +
.../media/platform/qcom/camss/camss-csid.h | 1 +
4 files changed, 667 insertions(+)
create mode 100644 drivers/media/platform/qcom/camss/camss-csid-gen3.c
create mode 100644 drivers/media/platform/qcom/camss/camss-csid-gen3.h
diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
index 28eba4bf3e38..c5fcd6eec0f2 100644
--- a/drivers/media/platform/qcom/camss/Makefile
+++ b/drivers/media/platform/qcom/camss/Makefile
@@ -7,6 +7,7 @@ qcom-camss-objs += \
camss-csid-4-1.o \
camss-csid-4-7.o \
camss-csid-gen2.o \
+ camss-csid-gen3.o \
camss-csiphy-2ph-1-0.o \
camss-csiphy-3ph-1-0.o \
camss-csiphy-2-1-2.o \
diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen3.c b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
new file mode 100644
index 000000000000..b97005f7065d
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
@@ -0,0 +1,639 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-csid-gen3.c
+ *
+ * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
+ *
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/delay.h>
+
+
+#include "camss-csid.h"
+#include "camss-csid-gen3.h"
+#include "camss.h"
+
+
+#define CSID_TOP_IO_PATH_CFG0(csid) (0x4 * (csid))
+#define OUTPUT_IFE_EN 0x100
+#define INTERNAL_CSID 1
+
+#define CSID_HW_VERSION 0x0
+#define HW_VERSION_STEPPING 0
+#define HW_VERSION_REVISION 16
+#define HW_VERSION_GENERATION 28
+
+#define CSID_RST_CFG 0xC
+#define RST_MODE 0
+#define RST_LOCATION 4
+
+#define CSID_RST_CMD 0x10
+#define SELECT_HW_RST 0
+#define SELECT_SW_RST 1
+#define SELECT_IRQ_RST 2
+
+#define CSID_CSI2_RX_IRQ_STATUS 0x9C
+#define CSID_CSI2_RX_IRQ_MASK 0xA0
+#define CSID_CSI2_RX_IRQ_CLEAR 0xA4
+#define CSID_CSI2_RX_IRQ_SET 0xA8
+
+#define CSID_CSI2_RDIN_IRQ_STATUS(rdi) (0xEC + 0x10 * (rdi))
+#define CSID_CSI2_RDIN_IRQ_MASK(rdi) (0xF0 + 0x10 * (rdi))
+#define CSID_CSI2_RDIN_INFO_FIFO_FULL 2
+#define CSID_CSI2_RDIN_INFO_CAMIF_EOF 3
+#define CSID_CSI2_RDIN_INFO_CAMIF_SOF 4
+#define CSID_CSI2_RDIN_INFO_INPUT_EOF 9
+#define CSID_CSI2_RDIN_INFO_INPUT_SOF 12
+#define CSID_CSI2_RDIN_ERROR_REC_FRAME_DROP 18
+#define CSID_CSI2_RDIN_ERROR_REC_OVERFLOW_IRQ 19
+#define CSID_CSI2_RDIN_ERROR_REC_CCIF_VIOLATION 20
+#define CSID_CSI2_RDIN_EPOCH0 21
+#define CSID_CSI2_RDIN_EPOCH1 22
+#define CSID_CSI2_RDIN_RUP_DONE 23
+#define CSID_CSI2_RDIN_CCIF_VIOLATION 29
+
+#define CSID_CSI2_RDIN_IRQ_CLEAR(rdi) (0xF4 + 0x10 * (rdi))
+#define CSID_CSI2_RDIN_IRQ_SET(rdi) (0xF8 + 0x10 * (rdi))
+
+#define CSID_TOP_IRQ_STATUS 0x7C
+#define TOP_IRQ_STATUS_RESET_DONE 0
+#define CSID_TOP_IRQ_MASK 0x80
+#define CSID_TOP_IRQ_CLEAR 0x84
+#define CSID_TOP_IRQ_SET 0x88
+#define CSID_IRQ_CMD 0x14
+#define IRQ_CMD_CLEAR 0
+#define IRQ_CMD_SET 4
+
+#define CSID_BUF_DONE_IRQ_STATUS 0x8C
+#define BUF_DONE_IRQ_STATUS_RDI_OFFSET (csid_is_lite(csid) ? 1 : 14)
+#define CSID_BUF_DONE_IRQ_MASK 0x90
+#define CSID_BUF_DONE_IRQ_CLEAR 0x94
+#define CSID_BUF_DONE_IRQ_SET 0x98
+
+#define CSID_CSI2_RX_CFG0 0x200
+#define CSI2_RX_CFG0_NUM_ACTIVE_LANES 0
+#define CSI2_RX_CFG0_DL0_INPUT_SEL 4
+#define CSI2_RX_CFG0_DL1_INPUT_SEL 8
+#define CSI2_RX_CFG0_DL2_INPUT_SEL 12
+#define CSI2_RX_CFG0_DL3_INPUT_SEL 16
+#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 27
+#define CSI2_RX_CFG0_TPG_NUM_SEL 28
+
+#define CSID_CSI2_RX_CFG1 0x204
+#define CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN 0
+#define CSI2_RX_CFG1_DE_SCRAMBLE_EN 1
+#define CSI2_RX_CFG1_VC_MODE 2
+#define CSI2_RX_CFG1_COMPLETE_STREAM_EN 4
+#define CSI2_RX_CFG1_COMPLETE_STREAM_FRAME_TIMING 5
+#define CSI2_RX_CFG1_MISR_EN 6
+#define CSI2_RX_CFG1_PHY_BIST_EN 7
+#define CSI2_RX_CFG1_EPD_MODE 8
+#define CSI2_RX_CFG1_EOTP_EN 9
+#define CSI2_RX_CFG1_DYN_SWITCH_EN 10
+#define CSI2_RX_CFG1_RUP_AUP_LATCH_DIS 11
+
+#define CSID_CSI2_RX_CAPTURE_CTRL 0x208
+#define CSI2_RX_CAPTURE_CTRL_LONG_PKT_CAPTURE_EN 0
+#define CSI2_RX_CAPTURE_CTRL_SHORT_PKT_CAPTURE_EN 1
+#define CSI2_RX_CAPTURE_CTRL_CPHY_PKT_CAPTURE_EN 3
+#define CSI2_RX_CAPTURE_CTRL_LONG_PKT_CAPTURE_DT 4
+#define CSI2_RX_CAPTURE_CTRL_LONG_PKT_CAPTURE_VC 10
+#define CSI2_RX_CAPTURE_CTRL_SHORT_PKT_CAPTURE_VC 15
+#define CSI2_RX_CAPTURE_CTRL_CPHY_PKT_CAPTURE_DT 20
+#define CSI2_RX_CAPTURE_CTRL_CPHY_PKT_CAPTURE_VC 26
+
+#define CSID_RDI_CFG0(rdi) (0x500 + 0x100 * (rdi))
+#define RDI_CFG0_VFR_EN 0
+#define RDI_CFG0_FRAME_ID_DEC_EN 1
+#define RDI_CFG0_RETIME_DIS 5
+#define RDI_CFG0_TIMESTAMP_EN 6
+#define RDI_CFG0_TIMESTAMP_STB_SEL 8
+#define RDI_CFG0_DECODE_FORMAT 12
+#define RDI_CFG0_DT 16
+#define RDI_CFG0_VC 22
+#define RDI_CFG0_DT_ID 27
+#define RDI_CFG0_EN 31
+
+#define CSID_RDI_CFG1(rdi) (0x510 + 0x100 * (rdi))
+#define RDI_CFG1_BYTE_CNTR_EN 2
+#define RDI_CFG1_DROP_H_EN 5
+#define RDI_CFG1_DROP_V_EN 6
+#define RDI_CFG1_CROP_H_EN 7
+#define RDI_CFG1_CROP_V_EN 8
+#define RDI_CFG1_MISR_EN 9
+#define RDI_CFG1_PIX_STORE 10
+#define RDI_CFG1_PLAIN_ALIGNMENT 11
+#define RDI_CFG1_PLAIN_FORMAT 12
+#define RDI_CFG1_EARLY_EOF_EN 14
+#define RDI_CFG1_PACKING_FORMAT 15
+
+#define CSID_RDI_CTRL(rdi) (0x504 + 0x100 * (rdi))
+#define RDI_CTRL_START_CMD 0
+#define RDI_CTRL_START_MODE 2
+
+#define CSID_RDI_EPOCH_IRQ_CFG(rdi) (0x52C + 0x100 * (rdi))
+
+#define CSID_RDI_FRM_DROP_PATTERN(rdi) (0x540 + 0x100 * (rdi))
+#define CSID_RDI_FRM_DROP_PERIOD(rdi) (0x544 + 0x100 * (rdi))
+#define CSID_RDI_IRQ_SUBSAMPLE_PATTERN(rdi) (0x548 + 0x100 * (rdi))
+#define CSID_RDI_IRQ_SUBSAMPLE_PERIOD(rdi) (0x54C + 0x100 * (rdi))
+#define CSID_RDI_RPP_PIX_DROP_PATTERN(rdi) (0x558 + 0x100 * (rdi))
+#define CSID_RDI_RPP_PIX_DROP_PERIOD(rdi) (0x55C + 0x100 * (rdi))
+#define CSID_RDI_RPP_LINE_DROP_PATTERN(rdi) (0x560 + 0x100 * (rdi))
+#define CSID_RDI_RPP_LINE_DROP_PERIOD(rdi) (0x564 + 0x100 * (rdi))
+
+#define CSID_RDI_RPP_HCROP(rdi) (0x550 + 0x100 * (rdi))
+#define CSID_RDI_RPP_VCROP(rdi) (0x554 + 0x100 * (rdi))
+
+#define CSID_RDI_ERROR_RECOVERY_CFG0(rdi) (0x514 + 0x100 * (rdi))
+
+#define CSID_DISCARD_FRAMES 4
+
+#define CSID_REG_UPDATE_CMD 0x18
+static inline int reg_update_rdi(struct csid_device *csid, int n)
+{
+ return BIT(n + 4) + BIT(20 + n);
+}
+
+#define REG_UPDATE_RDI reg_update_rdi
+
+static const struct csid_format csid_formats[] = {
+ {
+ MEDIA_BUS_FMT_UYVY8_1X16,
+ DATA_TYPE_YUV422_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 2,
+ },
+ {
+ MEDIA_BUS_FMT_VYUY8_1X16,
+ DATA_TYPE_YUV422_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 2,
+ },
+ {
+ MEDIA_BUS_FMT_YUYV8_1X16,
+ DATA_TYPE_YUV422_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 2,
+ },
+ {
+ MEDIA_BUS_FMT_YVYU8_1X16,
+ DATA_TYPE_YUV422_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 2,
+ },
+ {
+ MEDIA_BUS_FMT_SBGGR8_1X8,
+ DATA_TYPE_RAW_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGBRG8_1X8,
+ DATA_TYPE_RAW_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGRBG8_1X8,
+ DATA_TYPE_RAW_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SRGGB8_1X8,
+ DATA_TYPE_RAW_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SBGGR10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGBRG10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGRBG10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SRGGB10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_Y8_1X8,
+ DATA_TYPE_RAW_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_Y10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SBGGR12_1X12,
+ DATA_TYPE_RAW_12BIT,
+ DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+ 12,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGBRG12_1X12,
+ DATA_TYPE_RAW_12BIT,
+ DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+ 12,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGRBG12_1X12,
+ DATA_TYPE_RAW_12BIT,
+ DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+ 12,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SRGGB12_1X12,
+ DATA_TYPE_RAW_12BIT,
+ DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+ 12,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SBGGR14_1X14,
+ DATA_TYPE_RAW_14BIT,
+ DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+ 14,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGBRG14_1X14,
+ DATA_TYPE_RAW_14BIT,
+ DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+ 14,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGRBG14_1X14,
+ DATA_TYPE_RAW_14BIT,
+ DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+ 14,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SRGGB14_1X14,
+ DATA_TYPE_RAW_14BIT,
+ DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+ 14,
+ 1,
+ },
+};
+
+static void __csid_configure_rx(struct csid_device *csid,
+ struct csid_phy_config *phy, int vc)
+{
+ int val;
+
+ 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;
+
+ writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG0);
+
+ val = 1 << CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN;
+ if (vc > 3)
+ val |= 1 << CSI2_RX_CFG1_VC_MODE;
+ writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1);
+}
+
+static void __csid_ctrl_rdi(struct csid_device *csid, int enable, u8 rdi)
+{
+ int val;
+
+ if (enable)
+ val = 1 << RDI_CTRL_START_CMD;
+ else
+ val = 0 << RDI_CTRL_START_CMD;
+ writel_relaxed(val, csid->base + CSID_RDI_CTRL(rdi));
+}
+
+static void __csid_configure_top(struct csid_device *csid)
+{
+ u32 val;
+
+ if (csid->top_base) {
+ val = OUTPUT_IFE_EN | INTERNAL_CSID;
+ writel_relaxed(val, csid->top_base + CSID_TOP_IO_PATH_CFG0(csid->id));
+ }
+}
+
+static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8 vc)
+{
+ u32 val;
+ u8 lane_cnt = csid->phy.lane_cnt;
+ /* Source pads matching RDI channels on hardware. Pad 1 -> RDI0, Pad 2 -> RDI1, etc. */
+ struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + vc];
+ const struct csid_format *format = csid_get_fmt_entry(csid->formats, csid->nformats,
+ input_format->code);
+
+ if (!lane_cnt)
+ lane_cnt = 4;
+
+ val = 0;
+ writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PERIOD(vc));
+
+ /*
+ * DT_ID is a two bit bitfield that is concatenated with
+ * the four least significant bits of the five bit VC
+ * bitfield to generate an internal CID value.
+ *
+ * CSID_RDI_CFG0(vc)
+ * DT_ID : 28:27
+ * VC : 26:22
+ * DT : 21:16
+ *
+ * CID : VC 3:0 << 2 | DT_ID 1:0
+ */
+ u8 dt_id = vc & 0x03;
+
+ val = 1 << RDI_CFG0_TIMESTAMP_EN;
+ val |= 2 << RDI_CFG0_TIMESTAMP_STB_SEL;
+ /* note: for non-RDI path, this should be format->decode_format */
+ val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT;
+ val |= vc << RDI_CFG0_VC;
+ val |= format->data_type << RDI_CFG0_DT;
+ val |= dt_id << RDI_CFG0_DT_ID;
+
+ writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc));
+
+ val = 1 << RDI_CFG1_PACKING_FORMAT;
+ val |= 1 << RDI_CFG1_PIX_STORE;
+ val |= 1 << RDI_CFG1_DROP_H_EN;
+ val |= 1 << RDI_CFG1_DROP_V_EN;
+ val |= 1 << RDI_CFG1_CROP_H_EN;
+ val |= 1 << RDI_CFG1_CROP_V_EN;
+ val |= RDI_CFG1_EARLY_EOF_EN;
+
+ writel_relaxed(val, csid->base + CSID_RDI_CFG1(vc));
+
+ val = 0;
+ writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PERIOD(vc));
+
+ val = 1;
+ writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PATTERN(vc));
+
+ val = 0;
+ writel_relaxed(val, csid->base + CSID_RDI_CTRL(vc));
+
+ val = readl_relaxed(csid->base + CSID_RDI_CFG0(vc));
+ val |= enable << RDI_CFG0_EN;
+ writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc));
+}
+
+static void csid_configure_stream(struct csid_device *csid, u8 enable)
+{
+ u8 i;
+
+ /* Loop through all enabled VCs and configure stream for each */
+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
+ if (csid->phy.en_vc & BIT(i)) {
+ __csid_configure_top(csid);
+ __csid_configure_rdi_stream(csid, enable, i);
+ __csid_configure_rx(csid, &csid->phy, i);
+ __csid_ctrl_rdi(csid, enable, i);
+ }
+}
+
+static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val)
+{
+ if (val > 0 && val <= csid->testgen.nmodes)
+ csid->testgen.mode = val;
+
+ return 0;
+}
+
+/*
+ * csid_hw_version - CSID hardware version query
+ * @csid: CSID device
+ *
+ * Return HW version or error
+ */
+static u32 csid_hw_version(struct csid_device *csid)
+{
+ u32 hw_version;
+ u32 hw_gen;
+ u32 hw_rev;
+ u32 hw_step;
+
+ hw_version = readl_relaxed(csid->base + CSID_HW_VERSION);
+ hw_gen = (hw_version >> HW_VERSION_GENERATION) & 0xF;
+ hw_rev = (hw_version >> HW_VERSION_REVISION) & 0xFFF;
+ hw_step = (hw_version >> HW_VERSION_STEPPING) & 0xFFFF;
+ dev_info(csid->camss->dev, "CSID HW Version = %u.%u.%u\n",
+ hw_gen, hw_rev, hw_step);
+
+ return hw_version;
+}
+
+static void csid_reg_update(struct csid_device *csid, int port_id)
+{
+ csid->reg_update |= REG_UPDATE_RDI(csid, port_id);
+ writel_relaxed(csid->reg_update, csid->base + CSID_REG_UPDATE_CMD);
+}
+
+static inline void csid_reg_update_clear(struct csid_device *csid,
+ int port_id)
+{
+ csid->reg_update &= ~REG_UPDATE_RDI(csid, port_id);
+}
+
+
+/*
+ * csid_isr - CSID module interrupt service routine
+ * @irq: Interrupt line
+ * @dev: CSID device
+ *
+ * Return IRQ_HANDLED on success
+ */
+static irqreturn_t csid_isr(int irq, void *dev)
+{
+ struct csid_device *csid = dev;
+ u32 val, buf_done_val;
+ u8 reset_done;
+ int i;
+
+ val = readl_relaxed(csid->base + CSID_TOP_IRQ_STATUS);
+ writel_relaxed(val, csid->base + CSID_TOP_IRQ_CLEAR);
+ reset_done = val & BIT(TOP_IRQ_STATUS_RESET_DONE);
+
+ val = readl_relaxed(csid->base + CSID_CSI2_RX_IRQ_STATUS);
+ writel_relaxed(val, csid->base + CSID_CSI2_RX_IRQ_CLEAR);
+
+ buf_done_val = readl_relaxed(csid->base + CSID_BUF_DONE_IRQ_STATUS);
+ writel_relaxed(buf_done_val, csid->base + CSID_BUF_DONE_IRQ_CLEAR);
+
+ /* Read and clear IRQ status for each enabled RDI channel */
+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
+ if (csid->phy.en_vc & BIT(i)) {
+ val = readl_relaxed(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i));
+ writel_relaxed(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
+
+ if (buf_done_val & BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i)) {
+ dev_dbg(csid->camss->dev, "RDI%d BUF DONE", i);
+ v4l2_subdev_notify(&csid->subdev, NOTIFY_BUF_DONE, (void *)&i);
+ }
+ }
+
+ val = 1 << IRQ_CMD_CLEAR;
+ writel_relaxed(val, csid->base + CSID_IRQ_CMD);
+
+ if (reset_done)
+ complete(&csid->reset_complete);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * csid_reset - Trigger reset on CSID module and wait to complete
+ * @csid: CSID device
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int csid_reset(struct csid_device *csid)
+{
+ unsigned long time;
+ u32 val;
+ int i;
+
+ reinit_completion(&csid->reset_complete);
+
+ writel_relaxed(1, csid->base + CSID_TOP_IRQ_CLEAR);
+ writel_relaxed(1, csid->base + CSID_IRQ_CMD);
+ writel_relaxed(1, csid->base + CSID_TOP_IRQ_MASK);
+
+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
+ if (csid->phy.en_vc & BIT(i)) {
+ writel_relaxed(BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i),
+ csid->base + CSID_BUF_DONE_IRQ_CLEAR);
+ writel_relaxed(0x1 << IRQ_CMD_CLEAR, csid->base + CSID_IRQ_CMD);
+ writel_relaxed(BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i),
+ csid->base + CSID_BUF_DONE_IRQ_MASK);
+ }
+
+ /* preserve registers */
+ val = (0x1 << RST_LOCATION) | (0x1 << RST_MODE);
+ writel_relaxed(val, csid->base + CSID_RST_CFG);
+
+ val = (0x1 << SELECT_HW_RST) | (0x1 << SELECT_IRQ_RST);
+ writel_relaxed(val, csid->base + CSID_RST_CMD);
+
+ time = wait_for_completion_timeout(&csid->reset_complete,
+ msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
+ if (!time) {
+ dev_err(csid->camss->dev, "CSID reset timeout\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
+ unsigned int match_format_idx, u32 match_code)
+{
+ switch (sink_code) {
+ case MEDIA_BUS_FMT_SBGGR10_1X10:
+ {
+ u32 src_code[] = {
+ MEDIA_BUS_FMT_SBGGR10_1X10,
+ MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE,
+ };
+
+ return csid_find_code(src_code, ARRAY_SIZE(src_code),
+ match_format_idx, match_code);
+ }
+ case MEDIA_BUS_FMT_Y10_1X10:
+ {
+ u32 src_code[] = {
+ MEDIA_BUS_FMT_Y10_1X10,
+ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE,
+ };
+
+ return csid_find_code(src_code, ARRAY_SIZE(src_code),
+ match_format_idx, match_code);
+ }
+ default:
+ if (match_format_idx > 0)
+ return 0;
+
+ return sink_code;
+ }
+}
+
+static void csid_subdev_init(struct csid_device *csid)
+{
+ csid->formats = csid_formats;
+ csid->nformats = ARRAY_SIZE(csid_formats);
+ csid->testgen.modes = csid_testgen_modes;
+ csid->testgen.nmodes = CSID_PAYLOAD_MODE_NUM_SUPPORTED_GEN2;
+}
+
+static void csid_subdev_event(struct csid_device *csid, unsigned int evt_type, void *arg)
+{
+ int evt_data = *(int *)arg;
+
+ switch (evt_type) {
+ case NOTIFY_RUP:
+ csid_reg_update(csid, evt_data);
+ break;
+ case NOTIFY_RUP_CLEAR:
+ csid_reg_update_clear(csid, evt_data);
+ break;
+ default:
+ dev_err(csid->camss->dev, "NOT Supported EVT Type\n");
+ break;
+ }
+}
+
+const struct csid_hw_ops csid_ops_gen3 = {
+ .configure_stream = csid_configure_stream,
+ .configure_testgen_pattern = csid_configure_testgen_pattern,
+ .hw_version = csid_hw_version,
+ .isr = csid_isr,
+ .reset = csid_reset,
+ .src_pad_code = csid_src_pad_code,
+ .subdev_init = csid_subdev_init,
+ .event = csid_subdev_event,
+};
diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen3.h b/drivers/media/platform/qcom/camss/camss-csid-gen3.h
new file mode 100644
index 000000000000..aa5bd5f2fec5
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-csid-gen3.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * camss-csid-gen3.h
+ *
+ * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module Generation 1
+ *
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef QC_MSM_CAMSS_CSID_GEN3_H
+#define QC_MSM_CAMSS_CSID_GEN3_H
+
+#define DECODE_FORMAT_UNCOMPRESSED_8_BIT 0x1
+#define DECODE_FORMAT_UNCOMPRESSED_10_BIT 0x2
+#define DECODE_FORMAT_UNCOMPRESSED_12_BIT 0x3
+#define DECODE_FORMAT_UNCOMPRESSED_14_BIT 0x4
+#define DECODE_FORMAT_UNCOMPRESSED_16_BIT 0x5
+#define DECODE_FORMAT_UNCOMPRESSED_20_BIT 0x6
+#define DECODE_FORMAT_UNCOMPRESSED_24_BIT 0x7
+#define DECODE_FORMAT_PAYLOAD_ONLY 0xf
+
+
+#define PLAIN_FORMAT_PLAIN8 0x0 /* supports DPCM, UNCOMPRESSED_6/8_BIT */
+#define PLAIN_FORMAT_PLAIN16 0x1 /* supports DPCM, UNCOMPRESSED_10/16_BIT */
+#define PLAIN_FORMAT_PLAIN32 0x2 /* supports UNCOMPRESSED_20_BIT */
+
+#endif /* QC_MSM_CAMSS_CSID_GEN3_H */
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index ca654b007441..c1d061f91b78 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -223,6 +223,7 @@ extern const char * const csid_testgen_modes[];
extern const struct csid_hw_ops csid_ops_4_1;
extern const struct csid_hw_ops csid_ops_4_7;
extern const struct csid_hw_ops csid_ops_gen2;
+extern const struct csid_hw_ops csid_ops_gen3;
/*
* csid_is_lite - Check if CSID is CSID lite.
--
2.17.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v2 6/8] media: qcom: camss: Add new VFE driver for SM8550
2024-03-20 14:11 [PATCH v2 0/8] media: qcom: camss: Add sm8550 support Depeng Shao
` (4 preceding siblings ...)
2024-03-20 14:11 ` [PATCH v2 5/8] media: qcom: camss: Add CSID gen3 driver Depeng Shao
@ 2024-03-20 14:11 ` Depeng Shao
2024-03-20 15:57 ` Bryan O'Donoghue
2024-04-09 13:39 ` Bryan O'Donoghue
2024-03-20 14:11 ` [PATCH v2 7/8] media: qcom: camss: Add sm8550 resources Depeng Shao
` (2 subsequent siblings)
8 siblings, 2 replies; 31+ messages in thread
From: Depeng Shao @ 2024-03-20 14:11 UTC (permalink / raw)
To: rfoss, todor.too, bryan.odonoghue, andersson, konrad.dybcio,
mchehab, quic_yon
Cc: quic_depengs, linux-kernel, linux-media, linux-arm-msm
From: Yongsheng Li <quic_yon@quicinc.com>
Add IFE driver for SM8550, the main difference with
old HW is register offset is different, register
update, reset and buf done is moved to CSID. And
the image address support 36 bits, so need to right
shift the image address when configuring the write
master.
Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
Co-developed-by: Depeng Shao <quic_depengs@quicinc.com>
Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
---
drivers/media/platform/qcom/camss/Makefile | 1 +
.../media/platform/qcom/camss/camss-vfe-780.c | 455 ++++++++++++++++++
drivers/media/platform/qcom/camss/camss-vfe.h | 1 +
3 files changed, 457 insertions(+)
create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-780.c
diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
index c5fcd6eec0f2..ac40bbab18a3 100644
--- a/drivers/media/platform/qcom/camss/Makefile
+++ b/drivers/media/platform/qcom/camss/Makefile
@@ -18,6 +18,7 @@ qcom-camss-objs += \
camss-vfe-4-8.o \
camss-vfe-17x.o \
camss-vfe-480.o \
+ camss-vfe-780.o \
camss-vfe-gen1.o \
camss-vfe.o \
camss-video.o \
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-780.c b/drivers/media/platform/qcom/camss/camss-vfe-780.c
new file mode 100644
index 000000000000..a78647f23c8c
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-vfe-780.c
@@ -0,0 +1,455 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-vfe-780.c
+ *
+ * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v780 (SM8550)
+ *
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+#include "camss.h"
+#include "camss-vfe.h"
+
+#define VFE_HW_VERSION (vfe_is_lite(vfe) ? 0x1000 : 0x0)
+
+#define VFE_IRQ_CMD (vfe_is_lite(vfe) ? 0x1038 : 0x30)
+#define IRQ_CMD_GLOBAL_CLEAR BIT(0)
+
+#define VFE_IRQ_MASK(n) ((vfe_is_lite(vfe) ? 0x1024 : 0x34) + (n) * 4)
+#define IRQ_MASK_0_BUS_TOP_IRQ (vfe_is_lite(vfe) ? BIT(0) | BIT(1) | BIT(2) : \
+ BIT(0) | BIT(4) | BIT(18))
+#define IRQ_MASK_1_BUS_TOP_IRQ(n) (vfe_is_lite(vfe) ? BIT(2 * n + 2) | BIT(2 * n + 3) : \
+ BIT(2 * n + 8) | BIT(2 * n + 9))
+#define VFE_IRQ_CLEAR(n) ((vfe_is_lite(vfe) ? 0x102C : 0x3C) + (n) * 4)
+#define VFE_IRQ_STATUS(n) ((vfe_is_lite(vfe) ? 0x101C : 0x44) + (n) * 4)
+
+#define BUS_REG_BASE (vfe_is_lite(vfe) ? 0x1200 : 0xC00)
+
+#define VFE_BUS_WM_CGC_OVERRIDE (BUS_REG_BASE + 0x08)
+#define WM_CGC_OVERRIDE_ALL (0x7FFFFFF)
+
+#define VFE_BUS_WM_TEST_BUS_CTRL (BUS_REG_BASE + 0xdc)
+
+#define VFE_BUS_WM_CFG(n) (BUS_REG_BASE + 0x200 + (n) * 0x100)
+#define WM_CFG_EN (0)
+#define WM_VIR_FRM_EN (1)
+#define WM_CFG_MODE (16)
+#define MODE_QCOM_PLAIN (0)
+#define MODE_MIPI_RAW (1)
+#define VFE_BUS_WM_IMAGE_ADDR(n) (BUS_REG_BASE + 0x204 + (n) * 0x100)
+#define VFE_BUS_WM_FRAME_INCR(n) (BUS_REG_BASE + 0x208 + (n) * 0x100)
+#define VFE_BUS_WM_IMAGE_CFG_0(n) (BUS_REG_BASE + 0x20c + (n) * 0x100)
+#define WM_IMAGE_CFG_0_DEFAULT_WIDTH (0xFFFF)
+#define VFE_BUS_WM_IMAGE_CFG_1(n) (BUS_REG_BASE + 0x210 + (n) * 0x100)
+#define VFE_BUS_WM_IMAGE_CFG_2(n) (BUS_REG_BASE + 0x214 + (n) * 0x100)
+#define WM_IMAGE_CFG_2_DEFAULT_STRIDE (0xFFFF)
+#define VFE_BUS_WM_PACKER_CFG(n) (BUS_REG_BASE + 0x218 + (n) * 0x100)
+#define VFE_BUS_WM_HEADER_ADDR(n) (BUS_REG_BASE + 0x220 + (n) * 0x100)
+#define VFE_BUS_WM_HEADER_INCR(n) (BUS_REG_BASE + 0x224 + (n) * 0x100)
+#define VFE_BUS_WM_HEADER_CFG(n) (BUS_REG_BASE + 0x228 + (n) * 0x100)
+
+#define VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(n) (BUS_REG_BASE + 0x230 + (n) * 0x100)
+#define VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(n) (BUS_REG_BASE + 0x234 + (n) * 0x100)
+#define VFE_BUS_WM_FRAMEDROP_PERIOD(n) (BUS_REG_BASE + 0x238 + (n) * 0x100)
+#define VFE_BUS_WM_FRAMEDROP_PATTERN(n) (BUS_REG_BASE + 0x23c + (n) * 0x100)
+
+#define VFE_BUS_WM_MMU_PREFETCH_CFG(n) (BUS_REG_BASE + 0x260 + (n) * 0x100)
+#define VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(n) (BUS_REG_BASE + 0x264 + (n) * 0x100)
+#define VFE_BUS_WM_SYSTEM_CACHE_CFG(n) (BUS_REG_BASE + 0x268 + (n) * 0x100)
+
+
+/* for titan 780, each bus client is hardcoded to a specific path */
+#define RDI_WM(n) ((vfe_is_lite(vfe) ? 0 : 23) + (n))
+
+#define MAX_VFE_OUTPUT_LINES 4
+#define MAX_VFE_ACT_BUF 1
+
+static u32 vfe_hw_version(struct vfe_device *vfe)
+{
+ u32 hw_version = readl_relaxed(vfe->base + VFE_HW_VERSION);
+
+ u32 gen = (hw_version >> 28) & 0xF;
+ u32 rev = (hw_version >> 16) & 0xFFF;
+ u32 step = hw_version & 0xFFFF;
+
+ dev_info(vfe->camss->dev, "VFE HW Version = %u.%u.%u\n", gen, rev, step);
+
+ return hw_version;
+}
+
+static void vfe_global_reset(struct vfe_device *vfe)
+{
+}
+
+static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line)
+{
+ struct v4l2_pix_format_mplane *pix =
+ &line->video_out.active_fmt.fmt.pix_mp;
+
+ wm = RDI_WM(wm); /* map to actual WM used (from wm=RDI index) */
+
+ /* no clock gating at bus input */
+ writel_relaxed(0, vfe->base + VFE_BUS_WM_CGC_OVERRIDE);
+
+ writel_relaxed(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL);
+
+ writel_relaxed(ALIGN(pix->plane_fmt[0].bytesperline, 16) * pix->height >> 8,
+ vfe->base + VFE_BUS_WM_FRAME_INCR(wm));
+ writel_relaxed((WM_IMAGE_CFG_0_DEFAULT_WIDTH & 0xFFFF),
+ vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm));
+ writel_relaxed(WM_IMAGE_CFG_2_DEFAULT_STRIDE,
+ vfe->base + VFE_BUS_WM_IMAGE_CFG_2(wm));
+ writel_relaxed(0, vfe->base + VFE_BUS_WM_PACKER_CFG(wm));
+
+ /* no dropped frames, one irq per frame */
+ writel_relaxed(0, vfe->base + VFE_BUS_WM_FRAMEDROP_PERIOD(wm));
+ writel_relaxed(1, vfe->base + VFE_BUS_WM_FRAMEDROP_PATTERN(wm));
+ writel_relaxed(0, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(wm));
+ writel_relaxed(1, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(wm));
+
+ writel_relaxed(1, vfe->base + VFE_BUS_WM_MMU_PREFETCH_CFG(wm));
+ writel_relaxed(0xFFFFFFFF, vfe->base + VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(wm));
+
+ writel_relaxed(1 << WM_CFG_EN | MODE_MIPI_RAW << WM_CFG_MODE,
+ vfe->base + VFE_BUS_WM_CFG(wm));
+}
+
+static void vfe_wm_stop(struct vfe_device *vfe, u8 wm)
+{
+ wm = RDI_WM(wm); /* map to actual WM used (from wm=RDI index) */
+ writel_relaxed(0, vfe->base + VFE_BUS_WM_CFG(wm));
+}
+
+static void vfe_wm_update(struct vfe_device *vfe, u8 wm, u64 addr,
+ struct vfe_line *line)
+{
+ wm = RDI_WM(wm); /* map to actual WM used (from wm=RDI index) */
+ writel_relaxed((addr >> 8) & 0xFFFFFFFF, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
+
+ dev_dbg(vfe->camss->dev, "wm:%d, image buf addr:0x%llx\n",
+ wm, addr);
+}
+
+static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+ int port_id = line_id;
+
+ v4l2_subdev_notify(&vfe->line[line_id].subdev, NOTIFY_RUP, (void *)&port_id);
+}
+
+static inline void vfe_reg_update_clear(struct vfe_device *vfe,
+ enum vfe_line_id line_id)
+{
+ int port_id = line_id;
+
+ v4l2_subdev_notify(&vfe->line[line_id].subdev, NOTIFY_RUP_CLEAR, (void *)&port_id);
+}
+
+static void vfe_enable_irq_common(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+ int port_id = line_id;
+
+ /* enable top BUS status IRQ */
+ writel_relaxed(IRQ_MASK_0_BUS_TOP_IRQ,
+ vfe->base + VFE_IRQ_MASK(0));
+
+ writel_relaxed(IRQ_MASK_1_BUS_TOP_IRQ(port_id),
+ vfe->base + VFE_IRQ_MASK(1));
+}
+
+/*
+ * vfe_isr - VFE module interrupt handler
+ * @irq: Interrupt line
+ * @dev: VFE device
+ *
+ * Return IRQ_HANDLED on success
+ */
+static irqreturn_t vfe_isr(int irq, void *dev)
+{
+ struct vfe_device *vfe = dev;
+ u32 status;
+
+ status = readl_relaxed(vfe->base + VFE_IRQ_STATUS(0));
+ writel_relaxed(status, vfe->base + VFE_IRQ_CLEAR(0));
+ writel_relaxed(IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD);
+
+ if (status)
+ dev_dbg(vfe->camss->dev, "Top Status_0:0x%x\n", status);
+
+ status = readl_relaxed(vfe->base + VFE_IRQ_STATUS(1));
+ writel_relaxed(status, vfe->base + VFE_IRQ_CLEAR(1));
+ writel_relaxed(IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD);
+
+ if (status)
+ dev_dbg(vfe->camss->dev, "Top Status_1:0x%x\n", status);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * vfe_halt - Trigger halt on VFE module and wait to complete
+ * @vfe: VFE device
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int vfe_halt(struct vfe_device *vfe)
+{
+ /* rely on vfe_disable_output() to stop the VFE */
+ return 0;
+}
+
+static int vfe_get_output(struct vfe_line *line)
+{
+ struct vfe_device *vfe = to_vfe(line);
+ struct vfe_output *output;
+ unsigned long flags;
+
+ spin_lock_irqsave(&vfe->output_lock, flags);
+
+ output = &line->output;
+ if (output->state > VFE_OUTPUT_RESERVED) {
+ dev_err(vfe->camss->dev, "Output is running\n");
+ goto error;
+ }
+
+ output->wm_num = 1;
+
+ /* Correspondence between VFE line number and WM number.
+ * line 0 -> RDI 0, line 1 -> RDI1, line 2 -> RDI2, line 3 -> PIX/RDI3
+ * Note this 1:1 mapping will not work for PIX streams.
+ */
+ output->wm_idx[0] = line->id;
+ vfe->wm_output_map[line->id] = line->id;
+
+ output->drop_update_idx = 0;
+
+ spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+ return 0;
+
+error:
+ spin_unlock_irqrestore(&vfe->output_lock, flags);
+ output->state = VFE_OUTPUT_OFF;
+
+ return -EINVAL;
+}
+
+static int vfe_enable_output(struct vfe_line *line)
+{
+ struct vfe_device *vfe = to_vfe(line);
+ struct vfe_output *output = &line->output;
+ unsigned long flags;
+ unsigned int i;
+
+ spin_lock_irqsave(&vfe->output_lock, flags);
+
+ vfe_reg_update_clear(vfe, line->id);
+
+ if (output->state > VFE_OUTPUT_RESERVED) {
+ dev_err(vfe->camss->dev, "Output is not in reserved state %d\n",
+ output->state);
+ spin_unlock_irqrestore(&vfe->output_lock, flags);
+ return -EINVAL;
+ }
+
+ WARN_ON(output->gen2.active_num);
+
+ output->state = VFE_OUTPUT_ON;
+
+ output->sequence = 0;
+
+ vfe_wm_start(vfe, output->wm_idx[0], line);
+
+ for (i = 0; i < MAX_VFE_ACT_BUF; i++) {
+ output->buf[i] = vfe_buf_get_pending(output);
+ if (!output->buf[i])
+ break;
+ output->gen2.active_num++;
+ vfe_wm_update(vfe, output->wm_idx[0], output->buf[i]->addr[0], line);
+
+ vfe_reg_update(vfe, line->id);
+ }
+
+ spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+ return 0;
+}
+
+/*
+ * vfe_enable - Enable streaming on VFE line
+ * @line: VFE line
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int vfe_enable(struct vfe_line *line)
+{
+ struct vfe_device *vfe = to_vfe(line);
+ int ret;
+
+ mutex_lock(&vfe->stream_lock);
+
+ if (!vfe->stream_count)
+ vfe_enable_irq_common(vfe, line->id);
+
+ vfe->stream_count++;
+
+ mutex_unlock(&vfe->stream_lock);
+
+ ret = vfe_get_output(line);
+ if (ret < 0)
+ goto error_get_output;
+
+ ret = vfe_enable_output(line);
+ if (ret < 0)
+ goto error_enable_output;
+
+ vfe->was_streaming = 1;
+
+ return 0;
+
+error_enable_output:
+ vfe_put_output(line);
+
+error_get_output:
+ mutex_lock(&vfe->stream_lock);
+
+ vfe->stream_count--;
+
+ mutex_unlock(&vfe->stream_lock);
+
+ return ret;
+}
+
+/*
+ * vfe_buf_done - Process write master done interrupt
+ * @vfe: VFE Device
+ * @wm: Write master id
+ */
+static void vfe_buf_done(struct vfe_device *vfe, int wm)
+{
+ struct vfe_line *line = &vfe->line[vfe->wm_output_map[wm]];
+ struct camss_buffer *ready_buf;
+ struct vfe_output *output;
+ unsigned long flags;
+ u32 index;
+ u64 ts = ktime_get_ns();
+
+ spin_lock_irqsave(&vfe->output_lock, flags);
+
+ if (vfe->wm_output_map[wm] == VFE_LINE_NONE) {
+ dev_err_ratelimited(vfe->camss->dev,
+ "Received wm done for unmapped index\n");
+ goto out_unlock;
+ }
+ output = &vfe->line[vfe->wm_output_map[wm]].output;
+
+ ready_buf = output->buf[0];
+ if (!ready_buf) {
+ dev_err_ratelimited(vfe->camss->dev,
+ "Missing ready buf %d!\n", output->state);
+ goto out_unlock;
+ }
+
+ ready_buf->vb.vb2_buf.timestamp = ts;
+ ready_buf->vb.sequence = output->sequence++;
+
+ index = 0;
+ output->buf[0] = output->buf[1];
+ if (output->buf[0])
+ index = 1;
+
+ output->buf[index] = vfe_buf_get_pending(output);
+
+ if (output->buf[index]) {
+ vfe_wm_update(vfe, output->wm_idx[0], output->buf[index]->addr[0], line);
+ vfe_reg_update(vfe, line->id);
+ } else
+ output->gen2.active_num--;
+
+ spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+ vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+ return;
+
+out_unlock:
+ spin_unlock_irqrestore(&vfe->output_lock, flags);
+}
+
+/*
+ * vfe_queue_buffer - Add empty buffer
+ * @vid: Video device structure
+ * @buf: Buffer to be enqueued
+ *
+ * Add an empty buffer - depending on the current number of buffers it will be
+ * put in pending buffer queue or directly given to the hardware to be filled.
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int vfe_queue_buffer(struct camss_video *vid,
+ struct camss_buffer *buf)
+{
+ struct vfe_line *line = container_of(vid, struct vfe_line, video_out);
+ struct vfe_device *vfe = to_vfe(line);
+ struct vfe_output *output;
+ unsigned long flags;
+
+ output = &line->output;
+
+ spin_lock_irqsave(&vfe->output_lock, flags);
+
+ if (output->state == VFE_OUTPUT_ON &&
+ output->gen2.active_num < MAX_VFE_ACT_BUF) {
+ output->buf[output->gen2.active_num++] = buf;
+ vfe_wm_update(vfe, output->wm_idx[0], buf->addr[0], line);
+ vfe_reg_update(vfe, line->id);
+ } else {
+ vfe_buf_add_pending(output, buf);
+ }
+
+ spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+ return 0;
+}
+
+static const struct camss_video_ops vfe_video_ops_780 = {
+ .queue_buffer = vfe_queue_buffer,
+ .flush_buffers = vfe_flush_buffers,
+};
+
+static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
+{
+ vfe->video_ops = vfe_video_ops_780;
+}
+
+static void vfe_subdev_event(struct vfe_device *vfe, unsigned int evt_type, void *arg)
+{
+ int port_id = *(int *)arg;
+
+ switch (evt_type) {
+ case NOTIFY_BUF_DONE:
+ vfe_buf_done(vfe, port_id);
+ break;
+
+ default:
+ break;
+ }
+}
+
+const struct vfe_hw_ops vfe_ops_780 = {
+ .global_reset = vfe_global_reset,
+ .hw_version = vfe_hw_version,
+ .isr = vfe_isr,
+ .pm_domain_off = vfe_pm_domain_off,
+ .pm_domain_on = vfe_pm_domain_on,
+ .subdev_init = vfe_subdev_init,
+ .vfe_disable = vfe_disable,
+ .vfe_enable = vfe_enable,
+ .vfe_halt = vfe_halt,
+ .vfe_wm_stop = vfe_wm_stop,
+ .event = vfe_subdev_event,
+};
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index 9919fe0ff101..150ea0b31fb1 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -224,6 +224,7 @@ extern const struct vfe_hw_ops vfe_ops_4_7;
extern const struct vfe_hw_ops vfe_ops_4_8;
extern const struct vfe_hw_ops vfe_ops_170;
extern const struct vfe_hw_ops vfe_ops_480;
+extern const struct vfe_hw_ops vfe_ops_780;
int vfe_get(struct vfe_device *vfe);
void vfe_put(struct vfe_device *vfe);
--
2.17.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v2 7/8] media: qcom: camss: Add sm8550 resources
2024-03-20 14:11 [PATCH v2 0/8] media: qcom: camss: Add sm8550 support Depeng Shao
` (5 preceding siblings ...)
2024-03-20 14:11 ` [PATCH v2 6/8] media: qcom: camss: Add new VFE driver for SM8550 Depeng Shao
@ 2024-03-20 14:11 ` Depeng Shao
2024-03-20 15:50 ` Krzysztof Kozlowski
2024-03-20 14:11 ` [PATCH v2 8/8] media: qcom: camss: Add sm8550 support Depeng Shao
2024-03-20 15:08 ` [PATCH v2 0/8] " Bryan O'Donoghue
8 siblings, 1 reply; 31+ messages in thread
From: Depeng Shao @ 2024-03-20 14:11 UTC (permalink / raw)
To: rfoss, todor.too, bryan.odonoghue, andersson, konrad.dybcio,
mchehab, quic_yon
Cc: quic_depengs, linux-kernel, linux-media, linux-arm-msm
From: Yongsheng Li <quic_yon@quicinc.com>
Add sm8550 resources
- 3 x VFE, 3 RDI per VFE
- 2 x VFE Lite, 4 RDI per VFE
- 3 x CSID
- 2 x CSID Lite
- 8 x CSI PHY
Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
---
drivers/media/platform/qcom/camss/camss.c | 345 ++++++++++++++++++++++
1 file changed, 345 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index b57cd25bf6c7..f43c957de49e 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1233,6 +1233,337 @@ static const struct resources_icc icc_res_sc8280xp[] = {
},
};
+static const struct camss_subdev_resources csiphy_res_8550[] = {
+ /* CSIPHY0 */
+ {
+ .regulators = {},
+ .clock = {
+ "csiphy0",
+ "csiphy0_timer" },
+ .clock_rate = {
+ { 300000000, 400000000, 400000000, 400000000, 400000000 },
+ { 300000000, 400000000, 400000000, 400000000, 400000000 } },
+ .reg = { "csiphy0" },
+ .interrupt = { "csiphy0" },
+ .ops = &csiphy_ops_2_1_2,
+ },
+ /* CSIPHY1 */
+ {
+ .regulators = {},
+ .clock = {
+ "csiphy1",
+ "csiphy1_timer" },
+ .clock_rate = {
+ { 300000000, 400000000, 400000000, 400000000, 400000000 },
+ { 300000000, 400000000, 400000000, 400000000, 400000000 } },
+ .reg = { "csiphy1" },
+ .interrupt = { "csiphy1" },
+ .ops = &csiphy_ops_2_1_2,
+ },
+ /* CSIPHY2 */
+ {
+ .regulators = {},
+ .clock = {
+ "csiphy2",
+ "csiphy2_timer" },
+ .clock_rate = {
+ { 300000000, 400000000, 400000000, 400000000, 400000000 },
+ { 300000000, 400000000, 400000000, 400000000, 400000000 } },
+ .reg = { "csiphy2" },
+ .interrupt = { "csiphy2" },
+ .ops = &csiphy_ops_2_1_2,
+ },
+ /* CSIPHY3 */
+ {
+ .regulators = {},
+ .clock = {
+ "csiphy3",
+ "csiphy3_timer" },
+ .clock_rate = {
+ { 300000000, 400000000, 400000000, 400000000, 400000000 },
+ { 300000000, 400000000, 400000000, 400000000, 400000000 } },
+ .reg = { "csiphy3" },
+ .interrupt = { "csiphy3" },
+ .ops = &csiphy_ops_2_1_2,
+ },
+ /* CSIPHY4 */
+ {
+ .regulators = {},
+ .clock = {
+ "csiphy4",
+ "csiphy4_timer" },
+ .clock_rate = {
+ { 300000000, 400000000, 400000000, 400000000, 400000000 },
+ { 300000000, 400000000, 400000000, 400000000, 400000000 } },
+ .reg = { "csiphy4" },
+ .interrupt = { "csiphy4" },
+ .ops = &csiphy_ops_2_1_2,
+ },
+ /* CSIPHY5 */
+ {
+ .regulators = {},
+ .clock = {
+ "csiphy5",
+ "csiphy5_timer" },
+ .clock_rate = {
+ { 300000000, 400000000, 400000000, 400000000, 400000000 },
+ { 300000000, 400000000, 400000000, 400000000, 400000000 } },
+ .reg = { "csiphy5" },
+ .interrupt = { "csiphy5" },
+ .ops = &csiphy_ops_2_1_2,
+ },
+ /* CSIPHY6 */
+ {
+ .regulators = {},
+ .clock = {
+ "csiphy6",
+ "csiphy6_timer" },
+ .clock_rate = {
+ { 300000000, 400000000, 400000000, 400000000, 400000000 },
+ { 300000000, 400000000, 400000000, 400000000, 400000000 } },
+ .reg = { "csiphy6" },
+ .interrupt = { "csiphy6" },
+ .ops = &csiphy_ops_2_1_2,
+ },
+ /* CSIPHY7 */
+ {
+ .regulators = {},
+ .clock = {
+ "csiphy7",
+ "csiphy7_timer" },
+ .clock_rate = {
+ { 300000000, 400000000, 400000000, 400000000, 400000000 },
+ { 300000000, 400000000, 400000000, 400000000, 400000000 } },
+ .reg = { "csiphy7" },
+ .interrupt = { "csiphy7" },
+ .ops = &csiphy_ops_2_1_2,
+ }
+};
+
+static const struct camss_subdev_resources csid_res_8550[] = {
+ /* CSID0 */
+ {
+ .regulators = { "vdda-phy", "vdda-pll" },
+ .clock = {
+ "csid",
+ "csiphy_rx" },
+ .clock_rate = {
+ { 400000000, 480000000, 480000000, 480000000, 480000000 },
+ { 400000000, 480000000, 480000000, 480000000, 480000000 } },
+ .reg = { "csid0", "csid_top" },
+ .interrupt = { "csid0" },
+ .ops = &csid_ops_gen3,
+ },
+ /* CSID1 */
+ {
+ .regulators = { "vdda-phy", "vdda-pll" },
+ .clock = { "csid", "csiphy_rx" },
+ .clock_rate = {
+ { 400000000, 480000000, 480000000, 480000000, 480000000 },
+ { 400000000, 480000000, 480000000, 480000000, 480000000 } },
+ .reg = { "csid1", "csid_top" },
+ .interrupt = { "csid1" },
+ .ops = &csid_ops_gen3,
+ },
+ /* CSID2 */
+ {
+ .regulators = { "vdda-phy", "vdda-pll" },
+ .clock = { "csid", "csiphy_rx" },
+ .clock_rate = {
+ { 400000000, 480000000, 480000000, 480000000, 480000000 },
+ { 400000000, 480000000, 480000000, 480000000, 480000000 } },
+ .reg = { "csid2", "csid_top" },
+ .interrupt = { "csid2" },
+ .ops = &csid_ops_gen3,
+ },
+ /* CSID3 */
+ {
+ .regulators = { "vdda-phy", "vdda-pll" },
+ .clock = { "vfe_lite_csid",
+ "vfe_lite_cphy_rx" },
+ .clock_rate = {
+ { 400000000, 480000000, 480000000, 480000000, 480000000 },
+ { 400000000, 480000000, 480000000, 480000000, 480000000 } },
+ .reg = { "csid_lite0" },
+ .interrupt = { "csid_lite0" },
+ .ops = &csid_ops_gen3,
+ },
+ /* CSID4 */
+ {
+ .regulators = { "vdda-phy", "vdda-pll" },
+ .clock = { "vfe_lite_csid",
+ "vfe_lite_cphy_rx" },
+ .clock_rate = {
+ { 400000000, 480000000, 480000000, 480000000, 480000000 },
+ { 400000000, 480000000, 480000000, 480000000, 480000000 } },
+ .reg = { "csid_lite1" },
+ .interrupt = { "csid_lite1" },
+ .ops = &csid_ops_gen3,
+ }
+};
+
+static const struct camss_subdev_resources vfe_res_8550[] = {
+ /* VFE0 */
+ {
+ .regulators = {},
+ .clock = {
+ "cam_hf_axi",
+ "cpas_ahb",
+ "cpas_fast_ahb_clk",
+ "vfe0_fast_ahb",
+ "vfe0",
+ "cpas_vfe0",
+ "camnoc_axi"},
+ .clock_rate = {
+ { 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 80000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 466000000, 594000000, 675000000, 785000000, 785000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 }
+ },
+ .reg = { "vfe0" },
+ .interrupt = { "vfe0" },
+ .line_num = 3,
+ .is_lite = false,
+ .has_pd = true,
+ .pd_name = "ife0",
+ .ops = &vfe_ops_780,
+ },
+ /* VFE1 */
+ {
+ .regulators = {},
+ .clock = {
+ "cam_hf_axi",
+ "cpas_ahb",
+ "cpas_fast_ahb_clk",
+ "vfe1_fast_ahb",
+ "vfe1",
+ "cpas_vfe1",
+ "camnoc_axi"},
+ .clock_rate = {
+ { 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 80000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 466000000, 594000000, 675000000, 785000000, 785000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 }
+ },
+ .reg = { "vfe1" },
+ .interrupt = { "vfe1" },
+ .line_num = 3,
+ .is_lite = false,
+ .has_pd = true,
+ .pd_name = "ife1",
+ .ops = &vfe_ops_780,
+ },
+ /* VFE2 */
+ {
+ .regulators = {},
+ .clock = {
+ "cam_hf_axi",
+ "cpas_ahb",
+ "cpas_fast_ahb_clk",
+ "vfe2_fast_ahb",
+ "vfe2",
+ "cpas_vfe2",
+ "camnoc_axi"},
+ .clock_rate = {
+ { 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 80000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 466000000, 594000000, 675000000, 785000000, 785000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 }
+ },
+ .reg = { "vfe2" },
+ .interrupt = { "vfe2" },
+ .line_num = 3,
+ .is_lite = false,
+ .has_pd = true,
+ .pd_name = "ife2",
+ .ops = &vfe_ops_780,
+ },
+ /* VFE3 (lite) */
+ {
+ .regulators = {},
+ .clock = {
+ "cam_hf_axi",
+ "cpas_ahb",
+ "cpas_fast_ahb_clk",
+ "vfe_lite_ahb",
+ "vfe_lite",
+ "cpas_ife_lite",
+ "camnoc_axi"},
+ .clock_rate = {
+ { 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 80000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 400000000, 480000000, 480000000, 480000000, 480000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 }
+ },
+ .reg = { "vfe_lite0" },
+ .interrupt = { "vfe_lite0" },
+ .line_num = 4,
+ .is_lite = true,
+ .ops = &vfe_ops_780,
+ },
+ /* VFE4 (lite) */
+ {
+ .regulators = {},
+ .clock = {
+ "cam_hf_axi",
+ "cpas_ahb",
+ "cpas_fast_ahb_clk",
+ "vfe_lite_ahb",
+ "vfe_lite",
+ "cpas_ife_lite",
+ "camnoc_axi"},
+ .clock_rate = {
+ { 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 80000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 400000000, 480000000, 480000000, 480000000, 480000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 },
+ { 300000000, 300000000, 400000000, 400000000, 400000000 }
+ },
+ .reg = { "vfe_lite1" },
+ .interrupt = { "vfe_lite1" },
+ .line_num = 4,
+ .is_lite = true,
+ .ops = &vfe_ops_780,
+ },
+};
+
+static const struct resources_icc icc_res_sm8550[] = {
+ {
+ .name = "cam_ahb",
+ .icc_bw_tbl.avg = 2097152,
+ .icc_bw_tbl.peak = 2097152,
+ },
+ {
+ .name = "cam_hf_0_mnoc",
+ .icc_bw_tbl.avg = 2097152,
+ .icc_bw_tbl.peak = 2097152,
+ },
+ {
+ .name = "cam_sf_0_mnoc",
+ .icc_bw_tbl.avg = 2097152,
+ .icc_bw_tbl.peak = 2097152,
+ },
+ {
+ .name = "cam_sf_icp_mnoc",
+ .icc_bw_tbl.avg = 2097152,
+ .icc_bw_tbl.peak = 2097152,
+ },
+};
+
/*
* camss_add_clock_margin - Add margin to clock frequency rate
* @rate: Clock frequency rate
@@ -2182,6 +2513,19 @@ static const struct camss_resources sc8280xp_resources = {
.vfe_num = ARRAY_SIZE(vfe_res_sc8280xp),
};
+static const struct camss_resources sm8550_resources = {
+ .version = CAMSS_8550,
+ .pd_name = "top",
+ .csiphy_res = csiphy_res_8550,
+ .csid_res = csid_res_8550,
+ .vfe_res = vfe_res_8550,
+ .icc_res = icc_res_sm8550,
+ .icc_path_num = ARRAY_SIZE(icc_res_sm8550),
+ .csiphy_num = ARRAY_SIZE(csiphy_res_8550),
+ .csid_num = ARRAY_SIZE(csid_res_8550),
+ .vfe_num = ARRAY_SIZE(vfe_res_8550),
+};
+
static const struct of_device_id camss_dt_match[] = {
{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
{ .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
@@ -2189,6 +2533,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,sc8280xp-camss", .data = &sc8280xp_resources },
+ { .compatible = "qcom,sm8550-camss", .data = &sm8550_resources },
{ }
};
--
2.17.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v2 8/8] media: qcom: camss: Add sm8550 support
2024-03-20 14:11 [PATCH v2 0/8] media: qcom: camss: Add sm8550 support Depeng Shao
` (6 preceding siblings ...)
2024-03-20 14:11 ` [PATCH v2 7/8] media: qcom: camss: Add sm8550 resources Depeng Shao
@ 2024-03-20 14:11 ` Depeng Shao
2024-03-20 16:01 ` Bryan O'Donoghue
2024-03-20 15:08 ` [PATCH v2 0/8] " Bryan O'Donoghue
8 siblings, 1 reply; 31+ messages in thread
From: Depeng Shao @ 2024-03-20 14:11 UTC (permalink / raw)
To: rfoss, todor.too, bryan.odonoghue, andersson, konrad.dybcio,
mchehab, quic_yon
Cc: quic_depengs, linux-kernel, linux-media, linux-arm-msm
Add in functional logic throughout the code to support the SM8550.
Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
---
.../media/platform/qcom/camss/camss-csid.c | 19 +++++++++++++++++++
.../media/platform/qcom/camss/camss-csiphy.c | 1 +
drivers/media/platform/qcom/camss/camss-vfe.c | 7 +++++++
.../media/platform/qcom/camss/camss-video.c | 1 +
4 files changed, 28 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index eb27d69e89a1..e9203dc15798 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -590,6 +590,25 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
csid->base = camss->vfe[id].base + VFE_480_LITE_CSID_OFFSET;
else
csid->base = camss->vfe[id].base + VFE_480_CSID_OFFSET;
+ } else if (camss->res->version == CAMSS_8550) {
+ /* for titan 780, CSID lite registers are inside the VFE lite region,
+ * between the VFE "top" and "bus" registers. this requires
+ * VFE to be initialized before CSID
+ */
+ if (id >= 2)
+ csid->base = camss->vfe[id].base;
+ else {
+ csid->base =
+ devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
+ if (id != 0)
+ csid->top_base = camss->csid[0].top_base;
+ else
+ csid->top_base =
+ devm_platform_ioremap_resource_byname(pdev, res->reg[1]);
+ }
+
+ if (IS_ERR(csid->base))
+ return PTR_ERR(csid->base);
} else {
csid->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
if (IS_ERR(csid->base))
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
index 45b3a8e5dea4..f35af0dd2147 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -579,6 +579,7 @@ int msm_csiphy_subdev_init(struct camss *camss,
case CAMSS_845:
case CAMSS_8250:
case CAMSS_8280XP:
+ case CAMSS_8550:
csiphy->formats = csiphy_formats_sdm845;
csiphy->nformats = ARRAY_SIZE(csiphy_formats_sdm845);
break;
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index d875237cf244..ff115c5521c6 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -226,6 +226,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
case CAMSS_845:
case CAMSS_8250:
case CAMSS_8280XP:
+ case CAMSS_8550:
switch (sink_code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
{
@@ -296,6 +297,10 @@ int vfe_reset(struct vfe_device *vfe)
reinit_completion(&vfe->reset_complete);
+ // The reset has been moved to csid in 8550
+ if (vfe->camss->res->version == CAMSS_8550)
+ return 0;
+
vfe->ops->global_reset(vfe);
time = wait_for_completion_timeout(&vfe->reset_complete,
@@ -1520,6 +1525,7 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
case CAMSS_845:
case CAMSS_8250:
case CAMSS_8280XP:
+ case CAMSS_8550:
l->formats = formats_rdi_845;
l->nformats = ARRAY_SIZE(formats_rdi_845);
break;
@@ -1605,6 +1611,7 @@ static int vfe_bpl_align(struct vfe_device *vfe)
case CAMSS_845:
case CAMSS_8250:
case CAMSS_8280XP:
+ case CAMSS_8550:
ret = 16;
break;
default:
diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
index 54cd82f74115..78a746be952c 100644
--- a/drivers/media/platform/qcom/camss/camss-video.c
+++ b/drivers/media/platform/qcom/camss/camss-video.c
@@ -1029,6 +1029,7 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
case CAMSS_845:
case CAMSS_8250:
case CAMSS_8280XP:
+ case CAMSS_8550:
video->formats = formats_rdi_845;
video->nformats = ARRAY_SIZE(formats_rdi_845);
break;
--
2.17.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [PATCH v2 1/8] media: qcom: camss: Add CAMSS_8550 enum
2024-03-20 14:11 ` [PATCH v2 1/8] media: qcom: camss: Add CAMSS_8550 enum Depeng Shao
@ 2024-03-20 14:50 ` Bryan O'Donoghue
2024-03-20 15:51 ` Krzysztof Kozlowski
1 sibling, 0 replies; 31+ messages in thread
From: Bryan O'Donoghue @ 2024-03-20 14:50 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, bryan.odonoghue, andersson,
konrad.dybcio, mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 14:11, Depeng Shao wrote:
> From: Yongsheng Li <quic_yon@quicinc.com>
>
> Adds a CAMSS SoC identifier for the sm8550.
>
> Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
> ---
> drivers/media/platform/qcom/camss/camss.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
> index ac15fe23a702..2f63206a8463 100644
> --- a/drivers/media/platform/qcom/camss/camss.h
> +++ b/drivers/media/platform/qcom/camss/camss.h
> @@ -78,6 +78,7 @@ enum camss_version {
> CAMSS_845,
> CAMSS_8250,
> CAMSS_8280XP,
> + CAMSS_8550,
> };
>
> enum icc_count {
Acked-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 0/8] media: qcom: camss: Add sm8550 support
2024-03-20 14:11 [PATCH v2 0/8] media: qcom: camss: Add sm8550 support Depeng Shao
` (7 preceding siblings ...)
2024-03-20 14:11 ` [PATCH v2 8/8] media: qcom: camss: Add sm8550 support Depeng Shao
@ 2024-03-20 15:08 ` Bryan O'Donoghue
8 siblings, 0 replies; 31+ messages in thread
From: Bryan O'Donoghue @ 2024-03-20 15:08 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, andersson, konrad.dybcio, mchehab,
quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 14:11, Depeng Shao wrote:
> V2:
> - Update some commit messages
> Link to V1: https://lore.kernel.org/all/20240320134227.16587-1-quic_depengs@quicinc.com/
Here's your first problem, doesn't apply.
Please rebase on - at a minimum linux-next or on top of this branch
https://git.codelinaro.org/bryan.odonoghue/kernel/-/tree/b4/camss-sc8280xp-v6?ref_type=heads
and indicate which branch you've done the work against.
deckard@sagittarius-a:~/Development/qualcomm/qlt-kernel$ git fetch
linux-next
remote: Enumerating objects: 1907, done.
remote: Counting objects: 100% (1860/1860), done.
remote: Compressing objects: 100% (491/491), done.
remote: Total 1907 (delta 1432), reused 1759 (delta 1367), pack-reused 47
Receiving objects: 100% (1907/1907), 1.16 MiB | 8.24 MiB/s, done.
Resolving deltas: 100% (1461/1461), completed with 263 local objects.
From git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next
+ 226d3c72fcde1...72fb52fb0ac44 master -> linux-next/master
(forced update)
+ 00fe0619c6bef...ad58b0c356a01 pending-fixes ->
linux-next/pending-fixes (forced update)
bf3a69c6861ff..78c3925c048c7 stable -> linux-next/stable
* [new tag] next-20240320 -> next-20240320
deckard@sagittarius-a:~/Development/qualcomm/qlt-kernel$ git checkout -b
linux-next-24-03-20-sm8550 linux-next/master
Updating files: 100% (18508/18508), done.
branch 'linux-next-24-03-20-sm8550' set up to track 'linux-next/master'.
Switched to a new branch 'linux-next-24-03-20-sm8550'
deckard@sagittarius-a:~/Development/qualcomm/qlt-kernel$ b4 shazam
20240320141136.26827-1-quic_depengs@quicinc.com
Grabbing thread from
lore.kernel.org/all/20240320141136.26827-1-quic_depengs@quicinc.com/t.mbox.gz
Checking for newer revisions
Grabbing search results from lore.kernel.org
Analyzing 10 messages in the thread
Checking attestation on all messages, may take a moment...
---
[PATCH v2 1/8] media: qcom: camss: Add CAMSS_8550 enum
+ Acked-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
[PATCH v2 2/8] media: qcom: camss: Add subdev notify support
[PATCH v2 3/8] media: qcom: camss: Add new csiphy driver 2-1-2
[PATCH v2 4/8] media: qcom: camss: Add new params for csid_device
[PATCH v2 5/8] media: qcom: camss: Add CSID gen3 driver
[PATCH v2 6/8] media: qcom: camss: Add new VFE driver for SM8550
[PATCH v2 7/8] media: qcom: camss: Add sm8550 resources
[PATCH v2 8/8] media: qcom: camss: Add sm8550 support
---
NOTE: install dkimpy for DKIM signature verification
---
Total patches: 8
---
Applying: media: qcom: camss: Add CAMSS_8550 enum
Patch failed at 0001 media: qcom: camss: Add CAMSS_8550 enum
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
error: patch failed: drivers/media/platform/qcom/camss/camss.h:78
error: drivers/media/platform/qcom/camss/camss.h: patch does not apply
hint: Use 'git am --show-current-patch=diff' to see the failed patch
---
bod
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 3/8] media: qcom: camss: Add new csiphy driver 2-1-2
2024-03-20 14:11 ` [PATCH v2 3/8] media: qcom: camss: Add new csiphy driver 2-1-2 Depeng Shao
@ 2024-03-20 15:21 ` Bryan O'Donoghue
2024-03-25 12:15 ` Depeng Shao
0 siblings, 1 reply; 31+ messages in thread
From: Bryan O'Donoghue @ 2024-03-20 15:21 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, bryan.odonoghue, andersson,
konrad.dybcio, mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 14:11, Depeng Shao wrote:
> From: Yongsheng Li <quic_yon@quicinc.com>
>
> The CSIPHY register offset of SM8550 is different with
> SM8250, so add a new driver for the SM8550 platform.
>
> Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
> Co-developed-by: Depeng Shao <depengs@qti.qualcomm.com>
You're listing yourself ? Twice with a different CD and SOB.
Shouldn't this be
Co-developed-by: Depeng Shao <quic_depengs@quicinc.com>
?
> Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
> ---
> drivers/media/platform/qcom/camss/Makefile | 1 +
> .../platform/qcom/camss/camss-csiphy-2-1-2.c | 343 ++++++++++++++++++
> .../media/platform/qcom/camss/camss-csiphy.h | 1 +
> 3 files changed, 345 insertions(+)
> create mode 100644 drivers/media/platform/qcom/camss/camss-csiphy-2-1-2.c
>
> diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
> index 0d4389ab312d..28eba4bf3e38 100644
> --- a/drivers/media/platform/qcom/camss/Makefile
> +++ b/drivers/media/platform/qcom/camss/Makefile
> @@ -9,6 +9,7 @@ qcom-camss-objs += \
> camss-csid-gen2.o \
> camss-csiphy-2ph-1-0.o \
> camss-csiphy-3ph-1-0.o \
> + camss-csiphy-2-1-2.o \
File name here is incorrect camss-csiphy-3ph-1-2.o this is a 3 phase
capable PHY right ? So both the filename and the commit title need to
reflect that.
I thought we had discussed offline using an offset instead of a new file ?
https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/6dc8f49ef7c6ca69783aa02bdca81c77e66ecc0d
Then just set the offset
https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/022a837257d9e1fa8070f0dfa2f683e903111aa0
> camss-csiphy.o \
> camss-ispif.o \
> camss-vfe-4-1.o \
> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-2-1-2.c b/drivers/media/platform/qcom/camss/camss-csiphy-2-1-2.c
> new file mode 100644
> index 000000000000..df7860d7a4f4
> --- /dev/null
> +++ b/drivers/media/platform/qcom/camss/camss-csiphy-2-1-2.c
> @@ -0,0 +1,343 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * camss-csiphy-2-1-2.c
> + *
> + * Qualcomm MSM Camera Subsystem - CSIPHY Module 3phase v2.0
> + *
> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#include "camss.h"
> +#include "camss-csiphy.h"
> +
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +
> +
> +#define CSIPHY_CMN_CSI_COMMON_CTRLn(n) (0x1000 + 0x4 * (n))
> +#define CSIPHY_CMN_CSI_COMMON_CTRL5_CLK_ENABLE BIT(7)
> +#define CSIPHY_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B BIT(0)
> +#define CSIPHY_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID BIT(1)
> +#define CSIPHY_CMN_CSI_COMMON_CTRL7_CONTROL 0x7A
> +#define CSIPHY_CMN_CSI_COMMON_CTRL0_PHY_SW_RESET BIT(0)
> +#define CSIPHY_CMN_CSI_COMMON_CTRL0_SWI_ENABLE_LANESYNC BIT(1)
> +#define CSIPHY_CMN_CSI_COMMON_STATUSn(n) (0x10B0 + 0x4 * (n))
> +
> +#define CSIPHY_DEFAULT_PARAMS 0
> +#define CSIPHY_LANE_ENABLE 1
> +#define CSIPHY_SETTLE_CNT_LOWER_BYTE 2
> +#define CSIPHY_SETTLE_CNT_HIGHER_BYTE 3
> +#define CSIPHY_DNP_PARAMS 4
> +#define CSIPHY_2PH_REGS 5
> +#define CSIPHY_3PH_REGS 6
> +
> +struct csiphy_reg_t {
> + s32 reg_addr;
> + s32 reg_data;
> + s32 delay;
> + u32 csiphy_param_type;
> +};
> +
> +/* 2.1.2 2PH */
> +static const struct
> +csiphy_reg_t lane_regs_sm8550[5][20] = {
So per the tree I shared with you..
https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/fa666c241eb530a08aa6b391e15b018296e93f66
We don't need to break this up into a multi-dimensional array
its just a straight write of values
> + {
> + {0x0E90, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0E98, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0E94, 0x07, 0x01, CSIPHY_DEFAULT_PARAMS},
> + {0x00A0, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0090, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0098, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0094, 0x07, 0x01, 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, 0x01, 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, 0x01, 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, 0x01, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
> + {0x0E10, 0x52, 0x00, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
> + {0x0010, 0x52, 0x00, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
> + {0x0410, 0x52, 0x00, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
> + {0x0810, 0x52, 0x00, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
> + {0x0C10, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0094, 0xD7, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x005C, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0060, 0xBD, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0064, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0494, 0xD7, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x045C, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0460, 0xBD, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0464, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0894, 0xD7, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x085C, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0860, 0xBD, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0864, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0C94, 0xD7, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0C5C, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0C60, 0xBD, 0x00, CSIPHY_DEFAULT_PARAMS},
> + {0x0C64, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
> + }
> +};
> +
> +static void csiphy_hw_version_read(struct csiphy_device *csiphy,
> + struct device *dev)
> +{
> + u32 hw_version;
> +
> + writel(CSIPHY_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID,
> + csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(6));
> +
> + hw_version = readl_relaxed(csiphy->base +
> + CSIPHY_CMN_CSI_COMMON_STATUSn(12));
> + hw_version |= readl_relaxed(csiphy->base +
> + CSIPHY_CMN_CSI_COMMON_STATUSn(13)) << 8;
> + hw_version |= readl_relaxed(csiphy->base +
> + CSIPHY_CMN_CSI_COMMON_STATUSn(14)) << 16;
> + hw_version |= readl_relaxed(csiphy->base +
> + CSIPHY_CMN_CSI_COMMON_STATUSn(15)) << 24;
> +
> + dev_info(dev, "CSIPHY 3PH HW Version = 0x%08x\n", hw_version);
> +}
> +
> +/*
> + * csiphy_reset - Perform software reset on CSIPHY module
> + * @csiphy: CSIPHY device
> + */
> +static void csiphy_reset(struct csiphy_device *csiphy)
> +{
> + writel_relaxed(0x1, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(0));
> + usleep_range(5000, 8000);
> + writel_relaxed(0x0, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(0));
> +}
> +
> +static irqreturn_t csiphy_isr(int irq, void *dev)
> +{
> + struct csiphy_device *csiphy = dev;
> + int i;
> +
> + for (i = 0; i < 11; i++) {
> + int c = i + 22;
> + u8 val = readl_relaxed(csiphy->base +
> + CSIPHY_CMN_CSI_COMMON_STATUSn(i));
> +
> + writel_relaxed(val, csiphy->base +
> + CSIPHY_CMN_CSI_COMMON_CTRLn(c));
> + }
> +
> + writel_relaxed(0x1, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(10));
> + writel_relaxed(0x0, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(10));
> +
> + for (i = 22; i < 33; i++)
> + writel_relaxed(0x0, csiphy->base +
> + CSIPHY_CMN_CSI_COMMON_CTRLn(i));
> +
> + return IRQ_HANDLED;
> +}
> +
> +/*
> + * csiphy_settle_cnt_calc - Calculate settle count value
> + *
> + * Helper function to calculate settle count value. This is
> + * based on the CSI2 T_hs_settle parameter which in turn
> + * is calculated based on the CSI2 transmitter link frequency.
> + *
> + * Return settle count value or 0 if the CSI2 link frequency
> + * is not available
> + */
> +static u8 csiphy_settle_cnt_calc(s64 link_freq, u32 timer_clk_rate)
> +{
> + u32 ui; /* ps */
> + u32 timer_period; /* ps */
> + u32 t_hs_prepare_max; /* ps */
> + u32 t_hs_settle; /* ps */
> + u8 settle_cnt;
> +
> + if (link_freq <= 0)
> + return 0;
> +
> + ui = div_u64(1000000000000LL, link_freq);
> + ui /= 2;
> + t_hs_prepare_max = 85000 + 6 * ui;
> + t_hs_settle = t_hs_prepare_max;
> +
> + timer_period = div_u64(1000000000000LL, timer_clk_rate);
> + settle_cnt = t_hs_settle / timer_period - 6;
> +
> + return settle_cnt;
> +}
Yep this is all literal copy/paste of existing code.
Please try taking
https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/aa27ac8e1ffedd48c5ef6ac0f75f1f15716fe296
https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/fa666c241eb530a08aa6b391e15b018296e93f66
https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/e9e99dee4e723755274e6430bb43adfbf77d2a1a
https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/5dc53c39b96eb22bdfe47554f047e6b63ddb25c0
https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/36655b353fa71269812cff0e695341ff12042546
https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/6dc8f49ef7c6ca69783aa02bdca81c77e66ecc0d
and
https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/042ec64867d43e014c2b369db3b92b4f5432497f
into your tree
it works for me on sm8250 and is WIP for x1e80100
Point being we need to make an effort to unify/reuse/fix init sequences
upstream not to copy/paste from one file to another.
> +
> +static void csiphy_config_lanes(struct csiphy_device *csiphy,
> + u8 settle_cnt)
> +{
> + const struct csiphy_reg_t *r;
> + int i, l, array_size;
> + u32 val;
> +
> + switch (csiphy->camss->res->version) {
> + case CAMSS_8550:
> + r = &lane_regs_sm8550[0][0];
> + array_size = ARRAY_SIZE(lane_regs_sm8550[0]);
> + break;
> + default:
> + WARN(1, "unknown csi version\n");
> + return;
> + }
> +
> + for (l = 0; l < 5; l++) {
These hard-coded values in control loops must be done away with upstream.
---
bod
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 4/8] media: qcom: camss: Add new params for csid_device
2024-03-20 14:11 ` [PATCH v2 4/8] media: qcom: camss: Add new params for csid_device Depeng Shao
@ 2024-03-20 15:26 ` Bryan O'Donoghue
2024-03-20 15:53 ` Krzysztof Kozlowski
1 sibling, 0 replies; 31+ messages in thread
From: Bryan O'Donoghue @ 2024-03-20 15:26 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, andersson, konrad.dybcio, mchehab,
quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 14:11, Depeng Shao wrote:
> CSID gen3 has a new register block which is named as
> CSID top, it controls the output of CSID, since the
> CSID can connect to SFE or original VFE in CSID gen3.
> The register update is moved to CSID from VFE in CSID
> gen3.
> So, adding top_base and reg_update variables in csid
> device structure for CSID gen3.
You need to define three letter acronyms (TLAs) - within reason - the
first time you use them.
There is no concept of an "SFE" upstream - please define what the SFE is
in the commit log "to the Sensor Front End (SFE)" then you can refer
back to the acronym liberally.
---
bod
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 5/8] media: qcom: camss: Add CSID gen3 driver
2024-03-20 14:11 ` [PATCH v2 5/8] media: qcom: camss: Add CSID gen3 driver Depeng Shao
@ 2024-03-20 15:40 ` Bryan O'Donoghue
2024-03-20 16:12 ` Bryan O'Donoghue
2024-03-25 13:38 ` Depeng Shao
0 siblings, 2 replies; 31+ messages in thread
From: Bryan O'Donoghue @ 2024-03-20 15:40 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, andersson, konrad.dybcio, mchehab,
quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 14:11, Depeng Shao wrote:
> The CSID in SM8550 is gen3, it has new register
> offset and new functionality, the buf done irq,
> register update and reset is moved to CSID gen3.
>
> Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
> Co-developed-by: Yongsheng Li <quic_yon@quicinc.com>
> Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
> ---
> drivers/media/platform/qcom/camss/Makefile | 1 +
> .../platform/qcom/camss/camss-csid-gen3.c | 639 ++++++++++++++++++
> .../platform/qcom/camss/camss-csid-gen3.h | 26 +
> .../media/platform/qcom/camss/camss-csid.h | 1 +
> 4 files changed, 667 insertions(+)
> create mode 100644 drivers/media/platform/qcom/camss/camss-csid-gen3.c
> create mode 100644 drivers/media/platform/qcom/camss/camss-csid-gen3.h
>
> diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
> index 28eba4bf3e38..c5fcd6eec0f2 100644
> --- a/drivers/media/platform/qcom/camss/Makefile
> +++ b/drivers/media/platform/qcom/camss/Makefile
> @@ -7,6 +7,7 @@ qcom-camss-objs += \
> camss-csid-4-1.o \
> camss-csid-4-7.o \
> camss-csid-gen2.o \
> + camss-csid-gen3.o \
> camss-csiphy-2ph-1-0.o \
> camss-csiphy-3ph-1-0.o \
> camss-csiphy-2-1-2.o \
> diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen3.c b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
> new file mode 100644
> index 000000000000..b97005f7065d
> --- /dev/null
> +++ b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
> @@ -0,0 +1,639 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * camss-csid-gen3.c
> + *
> + * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
> + *
> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +#include <linux/completion.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/of.h>
> +#include <linux/delay.h>
Please alphanumerically sort your include list.
> +
> +
> +#include "camss-csid.h"
> +#include "camss-csid-gen3.h"
> +#include "camss.h"
and here.
> +
> +#define CSID_TOP_IO_PATH_CFG0(csid) (0x4 * (csid))
> +#define OUTPUT_IFE_EN 0x100
> +#define INTERNAL_CSID 1
> +
> +#define CSID_HW_VERSION 0x0
> +#define HW_VERSION_STEPPING 0
> +#define HW_VERSION_REVISION 16
> +#define HW_VERSION_GENERATION 28
> +
> +#define CSID_RST_CFG 0xC
> +#define RST_MODE 0
> +#define RST_LOCATION 4
> +
> +#define CSID_RST_CMD 0x10
> +#define SELECT_HW_RST 0
> +#define SELECT_SW_RST 1
> +#define SELECT_IRQ_RST 2
> +
> +#define CSID_CSI2_RX_IRQ_STATUS 0x9C
> +#define CSID_CSI2_RX_IRQ_MASK 0xA0
> +#define CSID_CSI2_RX_IRQ_CLEAR 0xA4
> +#define CSID_CSI2_RX_IRQ_SET 0xA8
> +
> +#define CSID_CSI2_RDIN_IRQ_STATUS(rdi) (0xEC + 0x10 * (rdi))
> +#define CSID_CSI2_RDIN_IRQ_MASK(rdi) (0xF0 + 0x10 * (rdi))
> +#define CSID_CSI2_RDIN_INFO_FIFO_FULL 2
> +#define CSID_CSI2_RDIN_INFO_CAMIF_EOF 3
> +#define CSID_CSI2_RDIN_INFO_CAMIF_SOF 4
> +#define CSID_CSI2_RDIN_INFO_INPUT_EOF 9
> +#define CSID_CSI2_RDIN_INFO_INPUT_SOF 12
> +#define CSID_CSI2_RDIN_ERROR_REC_FRAME_DROP 18
> +#define CSID_CSI2_RDIN_ERROR_REC_OVERFLOW_IRQ 19
> +#define CSID_CSI2_RDIN_ERROR_REC_CCIF_VIOLATION 20
> +#define CSID_CSI2_RDIN_EPOCH0 21
> +#define CSID_CSI2_RDIN_EPOCH1 22
> +#define CSID_CSI2_RDIN_RUP_DONE 23
> +#define CSID_CSI2_RDIN_CCIF_VIOLATION 29
> +
> +#define CSID_CSI2_RDIN_IRQ_CLEAR(rdi) (0xF4 + 0x10 * (rdi))
> +#define CSID_CSI2_RDIN_IRQ_SET(rdi) (0xF8 + 0x10 * (rdi))
> +
> +#define CSID_TOP_IRQ_STATUS 0x7C
> +#define TOP_IRQ_STATUS_RESET_DONE 0
> +#define CSID_TOP_IRQ_MASK 0x80
> +#define CSID_TOP_IRQ_CLEAR 0x84
> +#define CSID_TOP_IRQ_SET 0x88
> +#define CSID_IRQ_CMD 0x14
> +#define IRQ_CMD_CLEAR 0
> +#define IRQ_CMD_SET 4
> +
> +#define CSID_BUF_DONE_IRQ_STATUS 0x8C
> +#define BUF_DONE_IRQ_STATUS_RDI_OFFSET (csid_is_lite(csid) ? 1 : 14)
Stick with hex please 0x01 : 0x0e
> +#define CSID_BUF_DONE_IRQ_MASK 0x90
> +#define CSID_BUF_DONE_IRQ_CLEAR 0x94
> +#define CSID_BUF_DONE_IRQ_SET 0x98
> +
> +#define CSID_CSI2_RX_CFG0 0x200
> +#define CSI2_RX_CFG0_NUM_ACTIVE_LANES 0
> +#define CSI2_RX_CFG0_DL0_INPUT_SEL 4
> +#define CSI2_RX_CFG0_DL1_INPUT_SEL 8
> +#define CSI2_RX_CFG0_DL2_INPUT_SEL 12
> +#define CSI2_RX_CFG0_DL3_INPUT_SEL 16
> +#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 27
> +#define CSI2_RX_CFG0_TPG_NUM_SEL 28
> +
> +#define CSID_CSI2_RX_CFG1 0x204
> +#define CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN 0
> +#define CSI2_RX_CFG1_DE_SCRAMBLE_EN 1
> +#define CSI2_RX_CFG1_VC_MODE 2
> +#define CSI2_RX_CFG1_COMPLETE_STREAM_EN 4
> +#define CSI2_RX_CFG1_COMPLETE_STREAM_FRAME_TIMING 5
> +#define CSI2_RX_CFG1_MISR_EN 6
> +#define CSI2_RX_CFG1_PHY_BIST_EN 7
> +#define CSI2_RX_CFG1_EPD_MODE 8
> +#define CSI2_RX_CFG1_EOTP_EN 9
> +#define CSI2_RX_CFG1_DYN_SWITCH_EN 10
> +#define CSI2_RX_CFG1_RUP_AUP_LATCH_DIS 11
> +
> +#define CSID_CSI2_RX_CAPTURE_CTRL 0x208
> +#define CSI2_RX_CAPTURE_CTRL_LONG_PKT_CAPTURE_EN 0
> +#define CSI2_RX_CAPTURE_CTRL_SHORT_PKT_CAPTURE_EN 1
> +#define CSI2_RX_CAPTURE_CTRL_CPHY_PKT_CAPTURE_EN 3
> +#define CSI2_RX_CAPTURE_CTRL_LONG_PKT_CAPTURE_DT 4
> +#define CSI2_RX_CAPTURE_CTRL_LONG_PKT_CAPTURE_VC 10
> +#define CSI2_RX_CAPTURE_CTRL_SHORT_PKT_CAPTURE_VC 15
> +#define CSI2_RX_CAPTURE_CTRL_CPHY_PKT_CAPTURE_DT 20
> +#define CSI2_RX_CAPTURE_CTRL_CPHY_PKT_CAPTURE_VC 26
> +
> +#define CSID_RDI_CFG0(rdi) (0x500 + 0x100 * (rdi))
> +#define RDI_CFG0_VFR_EN 0
> +#define RDI_CFG0_FRAME_ID_DEC_EN 1
> +#define RDI_CFG0_RETIME_DIS 5
> +#define RDI_CFG0_TIMESTAMP_EN 6
> +#define RDI_CFG0_TIMESTAMP_STB_SEL 8
> +#define RDI_CFG0_DECODE_FORMAT 12
> +#define RDI_CFG0_DT 16
> +#define RDI_CFG0_VC 22
> +#define RDI_CFG0_DT_ID 27
> +#define RDI_CFG0_EN 31
> +
> +#define CSID_RDI_CFG1(rdi) (0x510 + 0x100 * (rdi))
> +#define RDI_CFG1_BYTE_CNTR_EN 2
> +#define RDI_CFG1_DROP_H_EN 5
> +#define RDI_CFG1_DROP_V_EN 6
> +#define RDI_CFG1_CROP_H_EN 7
> +#define RDI_CFG1_CROP_V_EN 8
> +#define RDI_CFG1_MISR_EN 9
> +#define RDI_CFG1_PIX_STORE 10
> +#define RDI_CFG1_PLAIN_ALIGNMENT 11
> +#define RDI_CFG1_PLAIN_FORMAT 12
> +#define RDI_CFG1_EARLY_EOF_EN 14
> +#define RDI_CFG1_PACKING_FORMAT 15
> +
> +#define CSID_RDI_CTRL(rdi) (0x504 + 0x100 * (rdi))
> +#define RDI_CTRL_START_CMD 0
> +#define RDI_CTRL_START_MODE 2
> +
> +#define CSID_RDI_EPOCH_IRQ_CFG(rdi) (0x52C + 0x100 * (rdi))
> +
> +#define CSID_RDI_FRM_DROP_PATTERN(rdi) (0x540 + 0x100 * (rdi))
> +#define CSID_RDI_FRM_DROP_PERIOD(rdi) (0x544 + 0x100 * (rdi))
> +#define CSID_RDI_IRQ_SUBSAMPLE_PATTERN(rdi) (0x548 + 0x100 * (rdi))
> +#define CSID_RDI_IRQ_SUBSAMPLE_PERIOD(rdi) (0x54C + 0x100 * (rdi))
> +#define CSID_RDI_RPP_PIX_DROP_PATTERN(rdi) (0x558 + 0x100 * (rdi))
> +#define CSID_RDI_RPP_PIX_DROP_PERIOD(rdi) (0x55C + 0x100 * (rdi))
> +#define CSID_RDI_RPP_LINE_DROP_PATTERN(rdi) (0x560 + 0x100 * (rdi))
> +#define CSID_RDI_RPP_LINE_DROP_PERIOD(rdi) (0x564 + 0x100 * (rdi))
> +
> +#define CSID_RDI_RPP_HCROP(rdi) (0x550 + 0x100 * (rdi))
> +#define CSID_RDI_RPP_VCROP(rdi) (0x554 + 0x100 * (rdi))
> +
> +#define CSID_RDI_ERROR_RECOVERY_CFG0(rdi) (0x514 + 0x100 * (rdi))
> +
> +#define CSID_DISCARD_FRAMES 4
> +
> +#define CSID_REG_UPDATE_CMD 0x18
> +static inline int reg_update_rdi(struct csid_device *csid, int n)
> +{
> + return BIT(n + 4) + BIT(20 + n);
> +}
> +
> +#define REG_UPDATE_RDI reg_update_rdi
> +
> +static const struct csid_format csid_formats[] = {
> + {
> + MEDIA_BUS_FMT_UYVY8_1X16,
> + DATA_TYPE_YUV422_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 2,
> + },
> + {
> + MEDIA_BUS_FMT_VYUY8_1X16,
> + DATA_TYPE_YUV422_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 2,
> + },
> + {
> + MEDIA_BUS_FMT_YUYV8_1X16,
> + DATA_TYPE_YUV422_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 2,
> + },
> + {
> + MEDIA_BUS_FMT_YVYU8_1X16,
> + DATA_TYPE_YUV422_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 2,
> + },
> + {
> + MEDIA_BUS_FMT_SBGGR8_1X8,
> + DATA_TYPE_RAW_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGBRG8_1X8,
> + DATA_TYPE_RAW_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGRBG8_1X8,
> + DATA_TYPE_RAW_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SRGGB8_1X8,
> + DATA_TYPE_RAW_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SBGGR10_1X10,
> + DATA_TYPE_RAW_10BIT,
> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> + 10,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGBRG10_1X10,
> + DATA_TYPE_RAW_10BIT,
> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> + 10,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGRBG10_1X10,
> + DATA_TYPE_RAW_10BIT,
> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> + 10,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SRGGB10_1X10,
> + DATA_TYPE_RAW_10BIT,
> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> + 10,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_Y8_1X8,
> + DATA_TYPE_RAW_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_Y10_1X10,
> + DATA_TYPE_RAW_10BIT,
> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> + 10,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SBGGR12_1X12,
> + DATA_TYPE_RAW_12BIT,
> + DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> + 12,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGBRG12_1X12,
> + DATA_TYPE_RAW_12BIT,
> + DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> + 12,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGRBG12_1X12,
> + DATA_TYPE_RAW_12BIT,
> + DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> + 12,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SRGGB12_1X12,
> + DATA_TYPE_RAW_12BIT,
> + DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> + 12,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SBGGR14_1X14,
> + DATA_TYPE_RAW_14BIT,
> + DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> + 14,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGBRG14_1X14,
> + DATA_TYPE_RAW_14BIT,
> + DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> + 14,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGRBG14_1X14,
> + DATA_TYPE_RAW_14BIT,
> + DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> + 14,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SRGGB14_1X14,
> + DATA_TYPE_RAW_14BIT,
> + DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> + 14,
> + 1,
> + },
> +};
> +
> +static void __csid_configure_rx(struct csid_device *csid,
> + struct csid_phy_config *phy, int vc)
> +{
> + int val;
> +
> + 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;
> +
> + writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG0);
> +
> + val = 1 << CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN;
> + if (vc > 3)
> + val |= 1 << CSI2_RX_CFG1_VC_MODE;
> + writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1);
> +}
> +
> +static void __csid_ctrl_rdi(struct csid_device *csid, int enable, u8 rdi)
> +{
> + int val;
> +
> + if (enable)
> + val = 1 << RDI_CTRL_START_CMD;
> + else
> + val = 0 << RDI_CTRL_START_CMD;
> + writel_relaxed(val, csid->base + CSID_RDI_CTRL(rdi));
> +}
> +
> +static void __csid_configure_top(struct csid_device *csid)
> +{
> + u32 val;
> +
> + if (csid->top_base) {
> + val = OUTPUT_IFE_EN | INTERNAL_CSID;
> + writel_relaxed(val, csid->top_base + CSID_TOP_IO_PATH_CFG0(csid->id));
> + }
> +}
> +
> +static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8 vc)
> +{
> + u32 val;
> + u8 lane_cnt = csid->phy.lane_cnt;
> + /* Source pads matching RDI channels on hardware. Pad 1 -> RDI0, Pad 2 -> RDI1, etc. */
> + struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + vc];
> + const struct csid_format *format = csid_get_fmt_entry(csid->formats, csid->nformats,
> + input_format->code);
> +
> + if (!lane_cnt)
> + lane_cnt = 4;
> +
> + val = 0;
> + writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PERIOD(vc));
> +
> + /*
> + * DT_ID is a two bit bitfield that is concatenated with
> + * the four least significant bits of the five bit VC
> + * bitfield to generate an internal CID value.
> + *
> + * CSID_RDI_CFG0(vc)
> + * DT_ID : 28:27
> + * VC : 26:22
> + * DT : 21:16
> + *
> + * CID : VC 3:0 << 2 | DT_ID 1:0
> + */
> + u8 dt_id = vc & 0x03;
> +
> + val = 1 << RDI_CFG0_TIMESTAMP_EN;
> + val |= 2 << RDI_CFG0_TIMESTAMP_STB_SEL;
> + /* note: for non-RDI path, this should be format->decode_format */
> + val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT;
> + val |= vc << RDI_CFG0_VC;
> + val |= format->data_type << RDI_CFG0_DT;
> + val |= dt_id << RDI_CFG0_DT_ID;
> +
> + writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc));
> +
> + val = 1 << RDI_CFG1_PACKING_FORMAT;
> + val |= 1 << RDI_CFG1_PIX_STORE;
> + val |= 1 << RDI_CFG1_DROP_H_EN;
> + val |= 1 << RDI_CFG1_DROP_V_EN;
> + val |= 1 << RDI_CFG1_CROP_H_EN;
> + val |= 1 << RDI_CFG1_CROP_V_EN;
> + val |= RDI_CFG1_EARLY_EOF_EN;
> +
> + writel_relaxed(val, csid->base + CSID_RDI_CFG1(vc));
> +
> + val = 0;
> + writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PERIOD(vc));
> +
> + val = 1;
> + writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PATTERN(vc));
> +
> + val = 0;
> + writel_relaxed(val, csid->base + CSID_RDI_CTRL(vc));
> +
> + val = readl_relaxed(csid->base + CSID_RDI_CFG0(vc));
> + val |= enable << RDI_CFG0_EN;
> + writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc));
> +}
Hmm.
So I think 90% of the code here can be moved into a shared file -
ideally instantiated in gen2.c and then reused here rather than
copy/paste from one file to the other.
Lets sync up and try to get a unified tree for x1e80100 and sm8550 for
that purpose.
I think the code you have here is slightly further along that the
CSID/VFE stuff I've been working with.
But still - reductio ad absurdum - we need to functionally decompose and
not replicate code.
> +
> +static void csid_configure_stream(struct csid_device *csid, u8 enable)
> +{
> + u8 i;
> +
> + /* Loop through all enabled VCs and configure stream for each */
> + for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
> + if (csid->phy.en_vc & BIT(i)) {
> + __csid_configure_top(csid);
> + __csid_configure_rdi_stream(csid, enable, i);
> + __csid_configure_rx(csid, &csid->phy, i);
> + __csid_ctrl_rdi(csid, enable, i);
> + }
> +}
Another example, straight copy/paste - we need to zap all of that.
---
bod
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 7/8] media: qcom: camss: Add sm8550 resources
2024-03-20 14:11 ` [PATCH v2 7/8] media: qcom: camss: Add sm8550 resources Depeng Shao
@ 2024-03-20 15:50 ` Krzysztof Kozlowski
0 siblings, 0 replies; 31+ messages in thread
From: Krzysztof Kozlowski @ 2024-03-20 15:50 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, bryan.odonoghue, andersson,
konrad.dybcio, mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 15:11, Depeng Shao wrote:
>
> +static const struct camss_resources sm8550_resources = {
> + .version = CAMSS_8550,
> + .pd_name = "top",
> + .csiphy_res = csiphy_res_8550,
> + .csid_res = csid_res_8550,
> + .vfe_res = vfe_res_8550,
> + .icc_res = icc_res_sm8550,
> + .icc_path_num = ARRAY_SIZE(icc_res_sm8550),
> + .csiphy_num = ARRAY_SIZE(csiphy_res_8550),
> + .csid_num = ARRAY_SIZE(csid_res_8550),
> + .vfe_num = ARRAY_SIZE(vfe_res_8550),
> +};
> +
> static const struct of_device_id camss_dt_match[] = {
> { .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
> { .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
> @@ -2189,6 +2533,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,sc8280xp-camss", .data = &sc8280xp_resources },
> + { .compatible = "qcom,sm8550-camss", .data = &sm8550_resources },
Please run scripts/checkpatch.pl and fix reported warnings. Some
warnings can be ignored, but the code here looks like it needs a fix.
Feel free to get in touch if the warning is not clear.
Do not ignore checkpatch warnings.
Also, because you did not post bindings, I am afraid of sneaking here
stuff which is not accepted upstream. Therefore please post DTS in
separate patchset, for public review.
> { }
> };
>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 1/8] media: qcom: camss: Add CAMSS_8550 enum
2024-03-20 14:11 ` [PATCH v2 1/8] media: qcom: camss: Add CAMSS_8550 enum Depeng Shao
2024-03-20 14:50 ` Bryan O'Donoghue
@ 2024-03-20 15:51 ` Krzysztof Kozlowski
2024-03-20 15:53 ` Bryan O'Donoghue
1 sibling, 1 reply; 31+ messages in thread
From: Krzysztof Kozlowski @ 2024-03-20 15:51 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, bryan.odonoghue, andersson,
konrad.dybcio, mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 15:11, Depeng Shao wrote:
> From: Yongsheng Li <quic_yon@quicinc.com>
>
> Adds a CAMSS SoC identifier for the sm8550.
Why?
>
> Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
> ---
> drivers/media/platform/qcom/camss/camss.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
> index ac15fe23a702..2f63206a8463 100644
> --- a/drivers/media/platform/qcom/camss/camss.h
> +++ b/drivers/media/platform/qcom/camss/camss.h
> @@ -78,6 +78,7 @@ enum camss_version {
> CAMSS_845,
> CAMSS_8250,
> CAMSS_8280XP,
> + CAMSS_8550,
> };
What is the point of this patch alone? What does it change? Why adding
enum? In the next patch, are you going to add one line to some
kerneldoc? Another patch, one function?
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 4/8] media: qcom: camss: Add new params for csid_device
2024-03-20 14:11 ` [PATCH v2 4/8] media: qcom: camss: Add new params for csid_device Depeng Shao
2024-03-20 15:26 ` Bryan O'Donoghue
@ 2024-03-20 15:53 ` Krzysztof Kozlowski
2024-03-25 12:30 ` Depeng Shao
1 sibling, 1 reply; 31+ messages in thread
From: Krzysztof Kozlowski @ 2024-03-20 15:53 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, bryan.odonoghue, andersson,
konrad.dybcio, mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 15:11, Depeng Shao wrote:
> CSID gen3 has a new register block which is named as
> CSID top, it controls the output of CSID, since the
> CSID can connect to SFE or original VFE in CSID gen3.
> The register update is moved to CSID from VFE in CSID
> gen3.
> So, adding top_base and reg_update variables in csid
> device structure for CSID gen3.
Please wrap commit message according to Linux coding style / submission
process (neither too early nor over the limit):
https://elixir.bootlin.com/linux/v6.4-rc1/source/Documentation/process/submitting-patches.rst#L597
>
> Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
> ---
> drivers/media/platform/qcom/camss/camss-csid.h | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
> index 4a9e5a2d1f92..ca654b007441 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.h
> +++ b/drivers/media/platform/qcom/camss/camss-csid.h
> @@ -162,7 +162,9 @@ struct csid_device {
> struct v4l2_subdev subdev;
> struct media_pad pads[MSM_CSID_PADS_NUM];
> void __iomem *base;
> + void __iomem *top_base;
> u32 irq;
> + u32 reg_update;
> char irq_name[30];
This is pointless. The are no users of this!
Sorry, don't add random code here or there without concept.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 1/8] media: qcom: camss: Add CAMSS_8550 enum
2024-03-20 15:51 ` Krzysztof Kozlowski
@ 2024-03-20 15:53 ` Bryan O'Donoghue
2024-03-20 15:59 ` Krzysztof Kozlowski
0 siblings, 1 reply; 31+ messages in thread
From: Bryan O'Donoghue @ 2024-03-20 15:53 UTC (permalink / raw)
To: Krzysztof Kozlowski, Depeng Shao, rfoss, todor.too, andersson,
konrad.dybcio, mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 15:51, Krzysztof Kozlowski wrote:
> On 20/03/2024 15:11, Depeng Shao wrote:
>> From: Yongsheng Li <quic_yon@quicinc.com>
>>
>> Adds a CAMSS SoC identifier for the sm8550.
>
> Why?
>
>>
>> Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
>> ---
>> drivers/media/platform/qcom/camss/camss.h | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
>> index ac15fe23a702..2f63206a8463 100644
>> --- a/drivers/media/platform/qcom/camss/camss.h
>> +++ b/drivers/media/platform/qcom/camss/camss.h
>> @@ -78,6 +78,7 @@ enum camss_version {
>> CAMSS_845,
>> CAMSS_8250,
>> CAMSS_8280XP,
>> + CAMSS_8550,
>> };
>
> What is the point of this patch alone? What does it change? Why adding
> enum? In the next patch, are you going to add one line to some
> kerneldoc? Another patch, one function?
>
> Best regards,
> Krzysztof
>
Yeah true enough, you could also add this enum where you use it..
---
bod
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 6/8] media: qcom: camss: Add new VFE driver for SM8550
2024-03-20 14:11 ` [PATCH v2 6/8] media: qcom: camss: Add new VFE driver for SM8550 Depeng Shao
@ 2024-03-20 15:57 ` Bryan O'Donoghue
2024-03-25 12:47 ` Depeng Shao
2024-04-09 13:39 ` Bryan O'Donoghue
1 sibling, 1 reply; 31+ messages in thread
From: Bryan O'Donoghue @ 2024-03-20 15:57 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, andersson, konrad.dybcio, mchehab,
quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 14:11, Depeng Shao wrote:
> From: Yongsheng Li <quic_yon@quicinc.com>
>
> Add IFE driver for SM8550, the main difference with
> old HW is register offset is different, register
> update, reset and buf done is moved to CSID. And
> the image address support 36 bits, so need to right
> shift the image address when configuring the write
> master.
>
> Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
> Co-developed-by: Depeng Shao <quic_depengs@quicinc.com>
> Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
Same comment with your co-developed and SOB
> ---
> drivers/media/platform/qcom/camss/Makefile | 1 +
> .../media/platform/qcom/camss/camss-vfe-780.c | 455 ++++++++++++++++++
> drivers/media/platform/qcom/camss/camss-vfe.h | 1 +
> 3 files changed, 457 insertions(+)
> create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-780.c
>
> diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
> index c5fcd6eec0f2..ac40bbab18a3 100644
> --- a/drivers/media/platform/qcom/camss/Makefile
> +++ b/drivers/media/platform/qcom/camss/Makefile
> @@ -18,6 +18,7 @@ qcom-camss-objs += \
> camss-vfe-4-8.o \
> camss-vfe-17x.o \
> camss-vfe-480.o \
> + camss-vfe-780.o \
> camss-vfe-gen1.o \
> camss-vfe.o \
> camss-video.o \
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-780.c b/drivers/media/platform/qcom/camss/camss-vfe-780.c
> new file mode 100644
> index 000000000000..a78647f23c8c
> --- /dev/null
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-780.c
> @@ -0,0 +1,455 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * camss-vfe-780.c
> + *
> + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v780 (SM8550)
> + *
> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +
> +#include "camss.h"
> +#include "camss-vfe.h"
> +
> +#define VFE_HW_VERSION (vfe_is_lite(vfe) ? 0x1000 : 0x0)
> +
> +#define VFE_IRQ_CMD (vfe_is_lite(vfe) ? 0x1038 : 0x30)
> +#define IRQ_CMD_GLOBAL_CLEAR BIT(0)
> +
> +#define VFE_IRQ_MASK(n) ((vfe_is_lite(vfe) ? 0x1024 : 0x34) + (n) * 4)
> +#define IRQ_MASK_0_BUS_TOP_IRQ (vfe_is_lite(vfe) ? BIT(0) | BIT(1) | BIT(2) : \
> + BIT(0) | BIT(4) | BIT(18))
> +#define IRQ_MASK_1_BUS_TOP_IRQ(n) (vfe_is_lite(vfe) ? BIT(2 * n + 2) | BIT(2 * n + 3) : \
> + BIT(2 * n + 8) | BIT(2 * n + 9))
> +#define VFE_IRQ_CLEAR(n) ((vfe_is_lite(vfe) ? 0x102C : 0x3C) + (n) * 4)
> +#define VFE_IRQ_STATUS(n) ((vfe_is_lite(vfe) ? 0x101C : 0x44) + (n) * 4)
> +
> +#define BUS_REG_BASE (vfe_is_lite(vfe) ? 0x1200 : 0xC00)
> +
> +#define VFE_BUS_WM_CGC_OVERRIDE (BUS_REG_BASE + 0x08)
> +#define WM_CGC_OVERRIDE_ALL (0x7FFFFFF)
> +
> +#define VFE_BUS_WM_TEST_BUS_CTRL (BUS_REG_BASE + 0xdc)
> +
> +#define VFE_BUS_WM_CFG(n) (BUS_REG_BASE + 0x200 + (n) * 0x100)
> +#define WM_CFG_EN (0)
> +#define WM_VIR_FRM_EN (1)
> +#define WM_CFG_MODE (16)
> +#define MODE_QCOM_PLAIN (0)
> +#define MODE_MIPI_RAW (1)
> +#define VFE_BUS_WM_IMAGE_ADDR(n) (BUS_REG_BASE + 0x204 + (n) * 0x100)
> +#define VFE_BUS_WM_FRAME_INCR(n) (BUS_REG_BASE + 0x208 + (n) * 0x100)
> +#define VFE_BUS_WM_IMAGE_CFG_0(n) (BUS_REG_BASE + 0x20c + (n) * 0x100)
> +#define WM_IMAGE_CFG_0_DEFAULT_WIDTH (0xFFFF)
> +#define VFE_BUS_WM_IMAGE_CFG_1(n) (BUS_REG_BASE + 0x210 + (n) * 0x100)
> +#define VFE_BUS_WM_IMAGE_CFG_2(n) (BUS_REG_BASE + 0x214 + (n) * 0x100)
> +#define WM_IMAGE_CFG_2_DEFAULT_STRIDE (0xFFFF)
> +#define VFE_BUS_WM_PACKER_CFG(n) (BUS_REG_BASE + 0x218 + (n) * 0x100)
> +#define VFE_BUS_WM_HEADER_ADDR(n) (BUS_REG_BASE + 0x220 + (n) * 0x100)
> +#define VFE_BUS_WM_HEADER_INCR(n) (BUS_REG_BASE + 0x224 + (n) * 0x100)
> +#define VFE_BUS_WM_HEADER_CFG(n) (BUS_REG_BASE + 0x228 + (n) * 0x100)
> +
> +#define VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(n) (BUS_REG_BASE + 0x230 + (n) * 0x100)
> +#define VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(n) (BUS_REG_BASE + 0x234 + (n) * 0x100)
> +#define VFE_BUS_WM_FRAMEDROP_PERIOD(n) (BUS_REG_BASE + 0x238 + (n) * 0x100)
> +#define VFE_BUS_WM_FRAMEDROP_PATTERN(n) (BUS_REG_BASE + 0x23c + (n) * 0x100)
> +
> +#define VFE_BUS_WM_MMU_PREFETCH_CFG(n) (BUS_REG_BASE + 0x260 + (n) * 0x100)
> +#define VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(n) (BUS_REG_BASE + 0x264 + (n) * 0x100)
> +#define VFE_BUS_WM_SYSTEM_CACHE_CFG(n) (BUS_REG_BASE + 0x268 + (n) * 0x100)
> +
> +
> +/* for titan 780, each bus client is hardcoded to a specific path */
> +#define RDI_WM(n) ((vfe_is_lite(vfe) ? 0 : 23) + (n))
No admixture of hex and decimal please.
> +
> +#define MAX_VFE_OUTPUT_LINES 4
> +#define MAX_VFE_ACT_BUF 1
> +
> +static u32 vfe_hw_version(struct vfe_device *vfe)
> +{
> + u32 hw_version = readl_relaxed(vfe->base + VFE_HW_VERSION);
> +
> + u32 gen = (hw_version >> 28) & 0xF;
> + u32 rev = (hw_version >> 16) & 0xFFF;
> + u32 step = hw_version & 0xFFFF;
> +
> + dev_info(vfe->camss->dev, "VFE HW Version = %u.%u.%u\n", gen, rev, step);
> +
> + return hw_version;
> +}
Same comment as with CSID, its time to rationalise all of this
replicated code down to one place, instead of proliferating it further.
> +static void vfe_global_reset(struct vfe_device *vfe)
> +{
> +}
> +
> +static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line)
> +{
> + struct v4l2_pix_format_mplane *pix =
> + &line->video_out.active_fmt.fmt.pix_mp;
> +
> + wm = RDI_WM(wm); /* map to actual WM used (from wm=RDI index) */
> +
> + /* no clock gating at bus input */
> + writel_relaxed(0, vfe->base + VFE_BUS_WM_CGC_OVERRIDE);
> +
> + writel_relaxed(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL);
> +
> + writel_relaxed(ALIGN(pix->plane_fmt[0].bytesperline, 16) * pix->height >> 8,
> + vfe->base + VFE_BUS_WM_FRAME_INCR(wm));
> + writel_relaxed((WM_IMAGE_CFG_0_DEFAULT_WIDTH & 0xFFFF),
> + vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm));
> + writel_relaxed(WM_IMAGE_CFG_2_DEFAULT_STRIDE,
> + vfe->base + VFE_BUS_WM_IMAGE_CFG_2(wm));
> + writel_relaxed(0, vfe->base + VFE_BUS_WM_PACKER_CFG(wm));
> +
> + /* no dropped frames, one irq per frame */
> + writel_relaxed(0, vfe->base + VFE_BUS_WM_FRAMEDROP_PERIOD(wm));
> + writel_relaxed(1, vfe->base + VFE_BUS_WM_FRAMEDROP_PATTERN(wm));
> + writel_relaxed(0, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(wm));
> + writel_relaxed(1, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(wm));
> +
> + writel_relaxed(1, vfe->base + VFE_BUS_WM_MMU_PREFETCH_CFG(wm));
> + writel_relaxed(0xFFFFFFFF, vfe->base + VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(wm));
> +
> + writel_relaxed(1 << WM_CFG_EN | MODE_MIPI_RAW << WM_CFG_MODE,
> + vfe->base + VFE_BUS_WM_CFG(wm));
> +}
> +
> +static void vfe_wm_stop(struct vfe_device *vfe, u8 wm)
> +{
> + wm = RDI_WM(wm); /* map to actual WM used (from wm=RDI index) */
> + writel_relaxed(0, vfe->base + VFE_BUS_WM_CFG(wm));
> +}
vfe_wm_stop() as an example can/should live in a shared file.
As proof of concept code its fine to copy/paste between files but, to
merge we need to get rid of any replicated code - introducing
indirection/offsets as necessary.
> +static void vfe_wm_update(struct vfe_device *vfe, u8 wm, u64 addr,
> + struct vfe_line *line)
> +{
> + wm = RDI_WM(wm); /* map to actual WM used (from wm=RDI index) */
> + writel_relaxed((addr >> 8) & 0xFFFFFFFF, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
> +
> + dev_dbg(vfe->camss->dev, "wm:%d, image buf addr:0x%llx\n",
> + wm, addr);
> +}
> +
> +static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + v4l2_subdev_notify(&vfe->line[line_id].subdev, NOTIFY_RUP, (void *)&port_id);
> +}
> +
> +static inline void vfe_reg_update_clear(struct vfe_device *vfe,
> + enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + v4l2_subdev_notify(&vfe->line[line_id].subdev, NOTIFY_RUP_CLEAR, (void *)&port_id);
> +}
I'm not sure I quite understand why we need to use this API to clear
registers inside of the address space of the same driver.
Is there not a much more direct way to write our _internal_ registers ?
> +static void vfe_enable_irq_common(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + /* enable top BUS status IRQ */
> + writel_relaxed(IRQ_MASK_0_BUS_TOP_IRQ,
> + vfe->base + VFE_IRQ_MASK(0));
> +
> + writel_relaxed(IRQ_MASK_1_BUS_TOP_IRQ(port_id),
> + vfe->base + VFE_IRQ_MASK(1));
> +}
> +
> +/*
> + * vfe_isr - VFE module interrupt handler
> + * @irq: Interrupt line
> + * @dev: VFE device
> + *
> + * Return IRQ_HANDLED on success
> + */
> +static irqreturn_t vfe_isr(int irq, void *dev)
> +{
> + struct vfe_device *vfe = dev;
> + u32 status;
> +
> + status = readl_relaxed(vfe->base + VFE_IRQ_STATUS(0));
> + writel_relaxed(status, vfe->base + VFE_IRQ_CLEAR(0));
> + writel_relaxed(IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD);
> +
> + if (status)
> + dev_dbg(vfe->camss->dev, "Top Status_0:0x%x\n", status);
> +
> + status = readl_relaxed(vfe->base + VFE_IRQ_STATUS(1));
> + writel_relaxed(status, vfe->base + VFE_IRQ_CLEAR(1));
> + writel_relaxed(IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD);
> +
> + if (status)
> + dev_dbg(vfe->camss->dev, "Top Status_1:0x%x\n", status);
> +
> + return IRQ_HANDLED;
> +}
Why is this ISR required ? What does it do ?
Does it actually run on your reference hardware ?
If the purpose of the ISR is just to clear the status registers, why
even enable it ?
> +
> +/*
> + * vfe_halt - Trigger halt on VFE module and wait to complete
> + * @vfe: VFE device
> + *
> + * Return 0 on success or a negative error code otherwise
> + */
> +static int vfe_halt(struct vfe_device *vfe)
> +{
> + /* rely on vfe_disable_output() to stop the VFE */
> + return 0;
> +}
> +
> +static int vfe_get_output(struct vfe_line *line)
> +{
> + struct vfe_device *vfe = to_vfe(line);
> + struct vfe_output *output;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&vfe->output_lock, flags);
> +
> + output = &line->output;
> + if (output->state > VFE_OUTPUT_RESERVED) {
> + dev_err(vfe->camss->dev, "Output is running\n");
> + goto error;
> + }
> +
> + output->wm_num = 1;
> +
> + /* Correspondence between VFE line number and WM number.
> + * line 0 -> RDI 0, line 1 -> RDI1, line 2 -> RDI2, line 3 -> PIX/RDI3
> + * Note this 1:1 mapping will not work for PIX streams.
> + */
> + output->wm_idx[0] = line->id;
> + vfe->wm_output_map[line->id] = line->id;
> +
> + output->drop_update_idx = 0;
> +
> + spin_unlock_irqrestore(&vfe->output_lock, flags);
> +
> + return 0;
> +
> +error:
> + spin_unlock_irqrestore(&vfe->output_lock, flags);
> + output->state = VFE_OUTPUT_OFF;
> +
> + return -EINVAL;
> +}
> +
> +static int vfe_enable_output(struct vfe_line *line)
> +{
> + struct vfe_device *vfe = to_vfe(line);
> + struct vfe_output *output = &line->output;
> + unsigned long flags;
> + unsigned int i;
> +
> + spin_lock_irqsave(&vfe->output_lock, flags);
> +
> + vfe_reg_update_clear(vfe, line->id);
> +
> + if (output->state > VFE_OUTPUT_RESERVED) {
> + dev_err(vfe->camss->dev, "Output is not in reserved state %d\n",
> + output->state);
> + spin_unlock_irqrestore(&vfe->output_lock, flags);
> + return -EINVAL;
> + }
> +
> + WARN_ON(output->gen2.active_num);
> +
> + output->state = VFE_OUTPUT_ON;
> +
> + output->sequence = 0;
> +
> + vfe_wm_start(vfe, output->wm_idx[0], line);
> +
> + for (i = 0; i < MAX_VFE_ACT_BUF; i++) {
> + output->buf[i] = vfe_buf_get_pending(output);
> + if (!output->buf[i])
> + break;
> + output->gen2.active_num++;
> + vfe_wm_update(vfe, output->wm_idx[0], output->buf[i]->addr[0], line);
> +
> + vfe_reg_update(vfe, line->id);
> + }
> +
> + spin_unlock_irqrestore(&vfe->output_lock, flags);
> +
> + return 0;
> +}
So you'll see with the WIP code for x1e80100 which is I think the same
VFE - no one generation less 680 - that this code is copy/pasted.
But there's again no good reason for that. Common code needs to be
squashed down into one place.
---
bod
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 1/8] media: qcom: camss: Add CAMSS_8550 enum
2024-03-20 15:53 ` Bryan O'Donoghue
@ 2024-03-20 15:59 ` Krzysztof Kozlowski
0 siblings, 0 replies; 31+ messages in thread
From: Krzysztof Kozlowski @ 2024-03-20 15:59 UTC (permalink / raw)
To: Bryan O'Donoghue, Depeng Shao, rfoss, todor.too, andersson,
konrad.dybcio, mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 16:53, Bryan O'Donoghue wrote:
> On 20/03/2024 15:51, Krzysztof Kozlowski wrote:
>> On 20/03/2024 15:11, Depeng Shao wrote:
>>> From: Yongsheng Li <quic_yon@quicinc.com>
>>>
>>> Adds a CAMSS SoC identifier for the sm8550.
>>
>> Why?
>>
>>>
>>> Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
>>> ---
>>> drivers/media/platform/qcom/camss/camss.h | 1 +
>>> 1 file changed, 1 insertion(+)
>>>
>>> diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
>>> index ac15fe23a702..2f63206a8463 100644
>>> --- a/drivers/media/platform/qcom/camss/camss.h
>>> +++ b/drivers/media/platform/qcom/camss/camss.h
>>> @@ -78,6 +78,7 @@ enum camss_version {
>>> CAMSS_845,
>>> CAMSS_8250,
>>> CAMSS_8280XP,
>>> + CAMSS_8550,
>>> };
>>
>> What is the point of this patch alone? What does it change? Why adding
>> enum? In the next patch, are you going to add one line to some
>> kerneldoc? Another patch, one function?
>>
>> Best regards,
>> Krzysztof
>>
>
> Yeah true enough, you could also add this enum where you use it..
Just to clarify my comment: this does not mean that entire patchset
should be squashed into one patch, because that would be unmanageable.
But your work should be organized in logical chunks, where some added
code is being used. There is at least one more such change without
immediate users in this patchset...
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 8/8] media: qcom: camss: Add sm8550 support
2024-03-20 14:11 ` [PATCH v2 8/8] media: qcom: camss: Add sm8550 support Depeng Shao
@ 2024-03-20 16:01 ` Bryan O'Donoghue
2024-03-25 13:16 ` Depeng Shao
0 siblings, 1 reply; 31+ messages in thread
From: Bryan O'Donoghue @ 2024-03-20 16:01 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, andersson, konrad.dybcio, mchehab,
quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 14:11, Depeng Shao wrote:
> Add in functional logic throughout the code to support the SM8550.
>
> Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
> ---
> .../media/platform/qcom/camss/camss-csid.c | 19 +++++++++++++++++++
> .../media/platform/qcom/camss/camss-csiphy.c | 1 +
> drivers/media/platform/qcom/camss/camss-vfe.c | 7 +++++++
> .../media/platform/qcom/camss/camss-video.c | 1 +
> 4 files changed, 28 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
> index eb27d69e89a1..e9203dc15798 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.c
> +++ b/drivers/media/platform/qcom/camss/camss-csid.c
> @@ -590,6 +590,25 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
> csid->base = camss->vfe[id].base + VFE_480_LITE_CSID_OFFSET;
> else
> csid->base = camss->vfe[id].base + VFE_480_CSID_OFFSET;
> + } else if (camss->res->version == CAMSS_8550) {
> + /* for titan 780, CSID lite registers are inside the VFE lite region,
> + * between the VFE "top" and "bus" registers. this requires
> + * VFE to be initialized before CSID
> + */
> + if (id >= 2)
> + csid->base = camss->vfe[id].base;
Hard-coded magic numbers are definitely out.
If you need to differentiate - please include something in the struct
resources so that the flag is always available and we don't have to
start doing funky magic index/magic number gymnastics.
> + else {
> + csid->base =
> + devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
> + if (id != 0)
> + csid->top_base = camss->csid[0].top_base;
> + else
> + csid->top_base =
> + devm_platform_ioremap_resource_byname(pdev, res->reg[1]);
> + }
What is the point of hooking the TOP base just to clear our the status
registers ?
We take no meaningful action in the ISR that I can see.
> +
> + if (IS_ERR(csid->base))
> + return PTR_ERR(csid->base);
> } else {
> csid->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
> if (IS_ERR(csid->base))
> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
> index 45b3a8e5dea4..f35af0dd2147 100644
> --- a/drivers/media/platform/qcom/camss/camss-csiphy.c
> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
> @@ -579,6 +579,7 @@ int msm_csiphy_subdev_init(struct camss *camss,
> case CAMSS_845:
> case CAMSS_8250:
> case CAMSS_8280XP:
> + case CAMSS_8550:
> csiphy->formats = csiphy_formats_sdm845;
> csiphy->nformats = ARRAY_SIZE(csiphy_formats_sdm845);
> break;
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
> index d875237cf244..ff115c5521c6 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
> @@ -226,6 +226,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
> case CAMSS_845:
> case CAMSS_8250:
> case CAMSS_8280XP:
> + case CAMSS_8550:
> switch (sink_code) {
> case MEDIA_BUS_FMT_YUYV8_1X16:
> {
> @@ -296,6 +297,10 @@ int vfe_reset(struct vfe_device *vfe)
>
> reinit_completion(&vfe->reset_complete);
>
> + // The reset has been moved to csid in 8550
Please run checkpatch.pl on your code before submission C++ are not allowed.
---
bod
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 2/8] media: qcom: camss: Add subdev notify support
2024-03-20 14:11 ` [PATCH v2 2/8] media: qcom: camss: Add subdev notify support Depeng Shao
@ 2024-03-20 16:08 ` Bryan O'Donoghue
2024-03-20 16:41 ` Gjorgji Rosikopulos (Consultant)
0 siblings, 1 reply; 31+ messages in thread
From: Bryan O'Donoghue @ 2024-03-20 16:08 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, bryan.odonoghue, andersson,
konrad.dybcio, mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 14:11, Depeng Shao wrote:
> From: Yongsheng Li <quic_yon@quicinc.com>
>
> The buf done irq and register update register are moved
> to CSID in SM8550, so but the write master configuration
> in VFE, in case adapt existing code logic. So add buf
> done and register related subdev event, and use the notify
> interface in the v4l2_device structure to communicate
> between CSID and VFE driver.
Shouldn't it be possible to just have a function to write internally ?
You know the indexes of the CSID -> VFE connection.
The subdev notify is I think not the right fit for this purpose within
our driver.
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
> index fddccb69da13..4a9e5a2d1f92 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.h
> +++ b/drivers/media/platform/qcom/camss/camss-csid.h
> @@ -147,6 +147,13 @@ struct csid_hw_ops {
> * @csid: CSID device
> */
> void (*subdev_init)(struct csid_device *csid);
> +
> + /*
> + * event - receive event from parent v4l2 device
> + * @csid: CSID device
> + */
> + void (*event)(struct csid_device *csid,
> + unsigned int evt_type, void *arg);
> };
>
> struct csid_device {
> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
> index c9b7fe82b1f0..ffe1b95eea98 100644
> --- a/drivers/media/platform/qcom/camss/camss-csiphy.h
> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
> @@ -61,6 +61,8 @@ struct csiphy_hw_ops {
> void (*lanes_disable)(struct csiphy_device *csiphy,
> struct csiphy_config *cfg);
> irqreturn_t (*isr)(int irq, void *dev);
> + void (*event)(struct csiphy_device *csiphy,
> + unsigned int evt_type, void *arg);
> };
>
> struct csiphy_device {
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
> index 0572c9b08e11..9919fe0ff101 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.h
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.h
> @@ -115,6 +115,8 @@ struct vfe_hw_ops {
> int (*vfe_halt)(struct vfe_device *vfe);
> void (*violation_read)(struct vfe_device *vfe);
> void (*vfe_wm_stop)(struct vfe_device *vfe, u8 wm);
> + void (*event)(struct vfe_device *vfe,
> + unsigned int evt_type, void *arg);
> };
>
> struct vfe_isr_ops {
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index 1923615f0eea..b57cd25bf6c7 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -1904,6 +1904,55 @@ static void camss_genpd_cleanup(struct camss *camss)
> dev_pm_domain_detach(camss->genpd, true);
> }
>
> +static void camss_v4l2_subdev_notify(struct v4l2_subdev *sd,
> + unsigned int cmd, void *arg)
> +{
> + struct v4l2_device *v4l2_dev = sd->v4l2_dev;
> + struct camss *camss = to_camss(v4l2_dev);
> + struct vfe_device *vfe;
> + struct vfe_line *vfe_line;
> + struct csid_device *csid;
> + int evt_data = *(int *)arg;
> +
> + if (camss->res->version != CAMSS_8550)
> + return;
> +
> + switch (cmd) {
> + case NOTIFY_BUF_DONE:
> + csid = v4l2_get_subdevdata(sd);
> + vfe = &(camss->vfe[csid->id]);
> + if (vfe->ops->event)
> + vfe->ops->event(vfe,
> + NOTIFY_BUF_DONE, (void *)&evt_data);
> + break;
> +
> + case NOTIFY_RUP:
> + vfe_line = v4l2_get_subdevdata(sd);
> + vfe = to_vfe(vfe_line);
> + csid = &(camss->csid[vfe->id]);
> +
> + if (csid->ops->event)
> + csid->ops->event(csid,
> + NOTIFY_RUP, (void *)&evt_data);
> + break;
> +
> + case NOTIFY_RUP_CLEAR:
> + vfe_line = v4l2_get_subdevdata(sd);
> + vfe = to_vfe(vfe_line);
> + csid = &(camss->csid[vfe->id]);
> +
> + if (csid->ops->event)
> + csid->ops->event(csid,
> + NOTIFY_RUP_CLEAR, (void *)&evt_data);
> +
> + break;
> +
> + default:
> + dev_err(camss->dev, "Not supported evt type\n");
> + break;
> + }
> +}
I'm really not sure I see a good reason for this.
Why can't we just define calls between vfe and csid similar to
drivers/media/platform/qcom/camss/camss-csid.c: ret = vfe_get(vfe);
---
bod
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 5/8] media: qcom: camss: Add CSID gen3 driver
2024-03-20 15:40 ` Bryan O'Donoghue
@ 2024-03-20 16:12 ` Bryan O'Donoghue
2024-03-25 13:38 ` Depeng Shao
1 sibling, 0 replies; 31+ messages in thread
From: Bryan O'Donoghue @ 2024-03-20 16:12 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, andersson, konrad.dybcio, mchehab,
quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm, Gjorgji Rosikopulos
On 20/03/2024 15:40, Bryan O'Donoghue wrote:
> +static const struct csid_format csid_formats[] = {
> + {
> + MEDIA_BUS_FMT_UYVY8_1X16,
> + DATA_TYPE_YUV422_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 2,
> + },
> + {
> + MEDIA_BUS_FMT_VYUY8_1X16,
> + DATA_TYPE_YUV422_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 2,
> + },
> + {
> + MEDIA_BUS_FMT_YUYV8_1X16,
> + DATA_TYPE_YUV422_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 2,
> + },
> + {
> + MEDIA_BUS_FMT_YVYU8_1X16,
> + DATA_TYPE_YUV422_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 2,
> + },
> + {
> + MEDIA_BUS_FMT_SBGGR8_1X8,
> + DATA_TYPE_RAW_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGBRG8_1X8,
> + DATA_TYPE_RAW_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGRBG8_1X8,
> + DATA_TYPE_RAW_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SRGGB8_1X8,
> + DATA_TYPE_RAW_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SBGGR10_1X10,
> + DATA_TYPE_RAW_10BIT,
> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> + 10,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGBRG10_1X10,
> + DATA_TYPE_RAW_10BIT,
> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> + 10,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGRBG10_1X10,
> + DATA_TYPE_RAW_10BIT,
> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> + 10,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SRGGB10_1X10,
> + DATA_TYPE_RAW_10BIT,
> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> + 10,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_Y8_1X8,
> + DATA_TYPE_RAW_8BIT,
> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> + 8,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_Y10_1X10,
> + DATA_TYPE_RAW_10BIT,
> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> + 10,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SBGGR12_1X12,
> + DATA_TYPE_RAW_12BIT,
> + DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> + 12,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGBRG12_1X12,
> + DATA_TYPE_RAW_12BIT,
> + DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> + 12,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGRBG12_1X12,
> + DATA_TYPE_RAW_12BIT,
> + DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> + 12,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SRGGB12_1X12,
> + DATA_TYPE_RAW_12BIT,
> + DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> + 12,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SBGGR14_1X14,
> + DATA_TYPE_RAW_14BIT,
> + DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> + 14,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGBRG14_1X14,
> + DATA_TYPE_RAW_14BIT,
> + DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> + 14,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SGRBG14_1X14,
> + DATA_TYPE_RAW_14BIT,
> + DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> + 14,
> + 1,
> + },
> + {
> + MEDIA_BUS_FMT_SRGGB14_1X14,
> + DATA_TYPE_RAW_14BIT,
> + DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> + 14,
> + 1,
> + },
> +};
Also please consider including/reviewing Gjorgji's patchset which
reworks the declaration of resources.
https://lore.kernel.org/lkml/20240319173935.481-4-quic_grosikop@quicinc.com/T/
---
bod
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 2/8] media: qcom: camss: Add subdev notify support
2024-03-20 16:08 ` Bryan O'Donoghue
@ 2024-03-20 16:41 ` Gjorgji Rosikopulos (Consultant)
0 siblings, 0 replies; 31+ messages in thread
From: Gjorgji Rosikopulos (Consultant) @ 2024-03-20 16:41 UTC (permalink / raw)
To: Bryan O'Donoghue, Depeng Shao, rfoss, todor.too, andersson,
konrad.dybcio, mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
Hi Bryan,
On 3/20/2024 6:08 PM, Bryan O'Donoghue wrote:
> On 20/03/2024 14:11, Depeng Shao wrote:
>> From: Yongsheng Li <quic_yon@quicinc.com>
>>
>> The buf done irq and register update register are moved
>> to CSID in SM8550, so but the write master configuration
>> in VFE, in case adapt existing code logic. So add buf
>> done and register related subdev event, and use the notify
>> interface in the v4l2_device structure to communicate
>> between CSID and VFE driver.
>
>
> Shouldn't it be possible to just have a function to write internally ?
>
> You know the indexes of the CSID -> VFE connection.
>
> The subdev notify is I think not the right fit for this purpose within
> our driver.
>
<snip>
>
> I'm really not sure I see a good reason for this.
>
> Why can't we just define calls between vfe and csid similar to
>
> drivers/media/platform/qcom/camss/camss-csid.c: ret = vfe_get(vfe);
Maybe we need to rethink and redesign this part of the driver.
In the initial version when this driver was introduced the CSID was
independent device from hw perspective,
and represented as separate sub-device.
With the newer architectures CSID was part of IFE hw (handled by the VFE
sub-device in this driver)
and vfe_get was introduced, but i believe it was not an issue because
the CISD still was kind of independent.
In the patch series:
"https://lore.kernel.org/lkml/20240319173935.481-4-quic_grosikop@quicinc.com/T/"
We try to decouple CSID from VFE and remove direct dependency
introducing parent_dev_ops,
where depending of the topology and parent device (VFE in this case or
other parent in future chipsets which contain CSID)
can reuse the code.
I am not sure if introducing parent_dev_ops is right way to go but we
can discuss further and see how to extend the driver
in proper way.
Just to add i am not saying that adding direct calls to VFE is not
proper but just close the door for other sub-device contain CSID to use
the code. :-)
Regards,
~Gjorgji
>
> ---
> bod
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 3/8] media: qcom: camss: Add new csiphy driver 2-1-2
2024-03-20 15:21 ` Bryan O'Donoghue
@ 2024-03-25 12:15 ` Depeng Shao
0 siblings, 0 replies; 31+ messages in thread
From: Depeng Shao @ 2024-03-25 12:15 UTC (permalink / raw)
To: Bryan O'Donoghue, rfoss, todor.too, andersson, konrad.dybcio,
mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
Hi Bryan,
On 3/20/2024 11:21 PM, Bryan O'Donoghue wrote:
> On 20/03/2024 14:11, Depeng Shao wrote:
>> From: Yongsheng Li <quic_yon@quicinc.com>
>>
>> The CSIPHY register offset of SM8550 is different with
>> SM8250, so add a new driver for the SM8550 platform.
>>
>> Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
>> Co-developed-by: Depeng Shao <depengs@qti.qualcomm.com>
>
> You're listing yourself ? Twice with a different CD and SOB.
> Shouldn't this be
> Co-developed-by: Depeng Shao <quic_depengs@quicinc.com>
>
> ?
Sorry for mistake, will update it in new patch.
>
>> Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
>> ---
>> drivers/media/platform/qcom/camss/Makefile | 1 +
>> .../platform/qcom/camss/camss-csiphy-2-1-2.c | 343 ++++++++++++++++++
>> .../media/platform/qcom/camss/camss-csiphy.h | 1 +
>> 3 files changed, 345 insertions(+)
>> create mode 100644
>> drivers/media/platform/qcom/camss/camss-csiphy-2-1-2.c
>>
>> diff --git a/drivers/media/platform/qcom/camss/Makefile
>> b/drivers/media/platform/qcom/camss/Makefile
>> index 0d4389ab312d..28eba4bf3e38 100644
>> --- a/drivers/media/platform/qcom/camss/Makefile
>> +++ b/drivers/media/platform/qcom/camss/Makefile
>> @@ -9,6 +9,7 @@ qcom-camss-objs += \
>> camss-csid-gen2.o \
>> camss-csiphy-2ph-1-0.o \
>> camss-csiphy-3ph-1-0.o \
>> + camss-csiphy-2-1-2.o \
>
> File name here is incorrect camss-csiphy-3ph-1-2.o this is a 3 phase
> capable PHY right ? So both the filename and the commit title need to
> reflect that.
>
> I thought we had discussed offline using an offset instead of a new
> file ?
>
> https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/6dc8f49ef7c6ca69783aa02bdca81c77e66ecc0d
>
>
> Then just set the offset
>
> https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/022a837257d9e1fa8070f0dfa2f683e903111aa0
>
>
Yes, this is a good idea, but looks like the code in your x1e80100
branch hasn't ready yet, could we have a separate patch for this
optimization, then I can rebase my change based on it.
>
>> camss-csiphy.o \
>> camss-ispif.o \
>> camss-vfe-4-1.o \
>> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-2-1-2.c
>> b/drivers/media/platform/qcom/camss/camss-csiphy-2-1-2.c
>> new file mode 100644
>> index 000000000000..df7860d7a4f4
>> --- /dev/null
>> +++ b/drivers/media/platform/qcom/camss/camss-csiphy-2-1-2.c
>> @@ -0,0 +1,343 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * camss-csiphy-2-1-2.c
>> + *
>> + * Qualcomm MSM Camera Subsystem - CSIPHY Module 3phase v2.0
>> + *
>> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights
>> reserved.
>> + */
>> +
>> +#include "camss.h"
>> +#include "camss-csiphy.h"
>> +
>> +#include <linux/delay.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +
>> +
>> +#define CSIPHY_CMN_CSI_COMMON_CTRLn(n) (0x1000 + 0x4 * (n))
>> +#define CSIPHY_CMN_CSI_COMMON_CTRL5_CLK_ENABLE BIT(7)
>> +#define CSIPHY_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B BIT(0)
>> +#define CSIPHY_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID BIT(1)
>> +#define CSIPHY_CMN_CSI_COMMON_CTRL7_CONTROL 0x7A
>> +#define CSIPHY_CMN_CSI_COMMON_CTRL0_PHY_SW_RESET BIT(0)
>> +#define CSIPHY_CMN_CSI_COMMON_CTRL0_SWI_ENABLE_LANESYNC BIT(1)
>> +#define CSIPHY_CMN_CSI_COMMON_STATUSn(n) (0x10B0 + 0x4 * (n))
>> +
>> +#define CSIPHY_DEFAULT_PARAMS 0
>> +#define CSIPHY_LANE_ENABLE 1
>> +#define CSIPHY_SETTLE_CNT_LOWER_BYTE 2
>> +#define CSIPHY_SETTLE_CNT_HIGHER_BYTE 3
>> +#define CSIPHY_DNP_PARAMS 4
>> +#define CSIPHY_2PH_REGS 5
>> +#define CSIPHY_3PH_REGS 6
>> +
>> +struct csiphy_reg_t {
>> + s32 reg_addr;
>> + s32 reg_data;
>> + s32 delay;
>> + u32 csiphy_param_type;
>> +};
>> +
>> +/* 2.1.2 2PH */
>> +static const struct
>> +csiphy_reg_t lane_regs_sm8550[5][20] = {
>
> So per the tree I shared with you..
>
> https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/fa666c241eb530a08aa6b391e15b018296e93f66
>
>
> We don't need to break this up into a multi-dimensional array
>
> its just a straight write of values
Yeah, agree, I also don't want to do like this, I just follow the old
driver's format
>> + {
>> + {0x0E90, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0E98, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0E94, 0x07, 0x01, CSIPHY_DEFAULT_PARAMS},
>> + {0x00A0, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0090, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0098, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0094, 0x07, 0x01, 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, 0x01, 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, 0x01, 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, 0x01, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
>> + {0x0E10, 0x52, 0x00, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
>> + {0x0010, 0x52, 0x00, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
>> + {0x0410, 0x52, 0x00, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
>> + {0x0810, 0x52, 0x00, 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, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
>> + {0x0C10, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0094, 0xD7, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x005C, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0060, 0xBD, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0064, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0494, 0xD7, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x045C, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0460, 0xBD, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0464, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0894, 0xD7, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x085C, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0860, 0xBD, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0864, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0C94, 0xD7, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0C5C, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0C60, 0xBD, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + {0x0C64, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
>> + }
>> +};
>> +
>> +static void csiphy_hw_version_read(struct csiphy_device *csiphy,
>> + struct device *dev)
>> +{
>> + u32 hw_version;
>> +
>> + writel(CSIPHY_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID,
>> + csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(6));
>> +
>> + hw_version = readl_relaxed(csiphy->base +
>> + CSIPHY_CMN_CSI_COMMON_STATUSn(12));
>> + hw_version |= readl_relaxed(csiphy->base +
>> + CSIPHY_CMN_CSI_COMMON_STATUSn(13)) << 8;
>> + hw_version |= readl_relaxed(csiphy->base +
>> + CSIPHY_CMN_CSI_COMMON_STATUSn(14)) << 16;
>> + hw_version |= readl_relaxed(csiphy->base +
>> + CSIPHY_CMN_CSI_COMMON_STATUSn(15)) << 24;
>> +
>> + dev_info(dev, "CSIPHY 3PH HW Version = 0x%08x\n", hw_version);
>> +}
>> +
>> +/*
>> + * csiphy_reset - Perform software reset on CSIPHY module
>> + * @csiphy: CSIPHY device
>> + */
>> +static void csiphy_reset(struct csiphy_device *csiphy)
>> +{
>> + writel_relaxed(0x1, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(0));
>> + usleep_range(5000, 8000);
>> + writel_relaxed(0x0, csiphy->base + CSIPHY_CMN_CSI_COMMON_CTRLn(0));
>> +}
>> +
>> +static irqreturn_t csiphy_isr(int irq, void *dev)
>> +{
>> + struct csiphy_device *csiphy = dev;
>> + int i;
>> +
>> + for (i = 0; i < 11; i++) {
>> + int c = i + 22;
>> + u8 val = readl_relaxed(csiphy->base +
>> + CSIPHY_CMN_CSI_COMMON_STATUSn(i));
>> +
>> + writel_relaxed(val, csiphy->base +
>> + CSIPHY_CMN_CSI_COMMON_CTRLn(c));
>> + }
>> +
>> + writel_relaxed(0x1, csiphy->base +
>> CSIPHY_CMN_CSI_COMMON_CTRLn(10));
>> + writel_relaxed(0x0, csiphy->base +
>> CSIPHY_CMN_CSI_COMMON_CTRLn(10));
>> +
>> + for (i = 22; i < 33; i++)
>> + writel_relaxed(0x0, csiphy->base +
>> + CSIPHY_CMN_CSI_COMMON_CTRLn(i));
>> +
>> + return IRQ_HANDLED;
>> +}
>> +
>> +/*
>> + * csiphy_settle_cnt_calc - Calculate settle count value
>> + *
>> + * Helper function to calculate settle count value. This is
>> + * based on the CSI2 T_hs_settle parameter which in turn
>> + * is calculated based on the CSI2 transmitter link frequency.
>> + *
>> + * Return settle count value or 0 if the CSI2 link frequency
>> + * is not available
>> + */
>> +static u8 csiphy_settle_cnt_calc(s64 link_freq, u32 timer_clk_rate)
>> +{
>> + u32 ui; /* ps */
>> + u32 timer_period; /* ps */
>> + u32 t_hs_prepare_max; /* ps */
>> + u32 t_hs_settle; /* ps */
>> + u8 settle_cnt;
>> +
>> + if (link_freq <= 0)
>> + return 0;
>> +
>> + ui = div_u64(1000000000000LL, link_freq);
>> + ui /= 2;
>> + t_hs_prepare_max = 85000 + 6 * ui;
>> + t_hs_settle = t_hs_prepare_max;
>> +
>> + timer_period = div_u64(1000000000000LL, timer_clk_rate);
>> + settle_cnt = t_hs_settle / timer_period - 6;
>> +
>> + return settle_cnt;
>> +}
>
> Yep this is all literal copy/paste of existing code.
>
> Please try taking
>
> https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/aa27ac8e1ffedd48c5ef6ac0f75f1f15716fe296
>
>
> https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/fa666c241eb530a08aa6b391e15b018296e93f66
>
>
> https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/e9e99dee4e723755274e6430bb43adfbf77d2a1a
>
>
> https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/5dc53c39b96eb22bdfe47554f047e6b63ddb25c0
>
>
> https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/36655b353fa71269812cff0e695341ff12042546
>
>
> https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/6dc8f49ef7c6ca69783aa02bdca81c77e66ecc0d
>
>
> and
>
> https://git.codelinaro.org/bryan.odonoghue/kernel/-/commit/042ec64867d43e014c2b369db3b92b4f5432497f
>
>
> into your tree
>
> it works for me on sm8250 and is WIP for x1e80100
>
> Point being we need to make an effort to unify/reuse/fix init
> sequences upstream not to copy/paste from one file to another.
>
I asked can we have a separate change for the csiphy optimization in
above, looks like this the separate series.
Sorry, I just want to make sure the merge order since there are many
ongoing changes, they will conflict with each other.
>> +
>> +static void csiphy_config_lanes(struct csiphy_device *csiphy,
>> + u8 settle_cnt)
>> +{
>> + const struct csiphy_reg_t *r;
>> + int i, l, array_size;
>> + u32 val;
>> +
>> + switch (csiphy->camss->res->version) {
>> + case CAMSS_8550:
>> + r = &lane_regs_sm8550[0][0];
>> + array_size = ARRAY_SIZE(lane_regs_sm8550[0]);
>> + break;
>> + default:
>> + WARN(1, "unknown csi version\n");
>> + return;
>> + }
>> +
>> + for (l = 0; l < 5; l++) {
>
> These hard-coded values in control loops must be done away with upstream.
>
Won't have these code if I rebase the change based on yours.
> ---
> bod
Thanks,
Depeng
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 4/8] media: qcom: camss: Add new params for csid_device
2024-03-20 15:53 ` Krzysztof Kozlowski
@ 2024-03-25 12:30 ` Depeng Shao
0 siblings, 0 replies; 31+ messages in thread
From: Depeng Shao @ 2024-03-25 12:30 UTC (permalink / raw)
To: Krzysztof Kozlowski, rfoss, todor.too, bryan.odonoghue,
andersson, konrad.dybcio, mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
Hi Krzysztof,
On 3/20/2024 11:53 PM, Krzysztof Kozlowski wrote:
> On 20/03/2024 15:11, Depeng Shao wrote:
>> CSID gen3 has a new register block which is named as
>> CSID top, it controls the output of CSID, since the
>> CSID can connect to SFE or original VFE in CSID gen3.
>> The register update is moved to CSID from VFE in CSID
>> gen3.
>> So, adding top_base and reg_update variables in csid
>> device structure for CSID gen3.
>
> Please wrap commit message according to Linux coding style / submission
> process (neither too early nor over the limit):
> https://elixir.bootlin.com/linux/v6.4-rc1/source/Documentation/process/submitting-patches.rst#L597
>
Thanks, will update it.
>>
>> Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
>> ---
>> drivers/media/platform/qcom/camss/camss-csid.h | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
>> index 4a9e5a2d1f92..ca654b007441 100644
>> --- a/drivers/media/platform/qcom/camss/camss-csid.h
>> +++ b/drivers/media/platform/qcom/camss/camss-csid.h
>> @@ -162,7 +162,9 @@ struct csid_device {
>> struct v4l2_subdev subdev;
>> struct media_pad pads[MSM_CSID_PADS_NUM];
>> void __iomem *base;
>> + void __iomem *top_base;
>> u32 irq;
>> + u32 reg_update;
>> char irq_name[30];
>
> This is pointless. The are no users of this!
>
> Sorry, don't add random code here or there without concept.
>
For the old code, they are new concept, since it is new block in the
hardware, I just want to highlight them.
But thanks for the comment, will update the code based on your comment.
> Best regards,
> Krzysztof
>
Thanks,
Depeng
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 6/8] media: qcom: camss: Add new VFE driver for SM8550
2024-03-20 15:57 ` Bryan O'Donoghue
@ 2024-03-25 12:47 ` Depeng Shao
0 siblings, 0 replies; 31+ messages in thread
From: Depeng Shao @ 2024-03-25 12:47 UTC (permalink / raw)
To: Bryan O'Donoghue, rfoss, todor.too, andersson, konrad.dybcio,
mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
Hi Bryan,
On 3/20/2024 11:57 PM, Bryan O'Donoghue wrote:
> On 20/03/2024 14:11, Depeng Shao wrote:
>> From: Yongsheng Li <quic_yon@quicinc.com>
>>
>> Add IFE driver for SM8550, the main difference with
>> old HW is register offset is different, register
>> update, reset and buf done is moved to CSID. And
>> the image address support 36 bits, so need to right
>> shift the image address when configuring the write
>> master.
>>
>> Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
>> Co-developed-by: Depeng Shao <quic_depengs@quicinc.com>
>> Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
>
> Same comment with your co-developed and SOB
>
>> ---
>> drivers/media/platform/qcom/camss/Makefile | 1 +
>> .../media/platform/qcom/camss/camss-vfe-780.c | 455 ++++++++++++++++++
>> drivers/media/platform/qcom/camss/camss-vfe.h | 1 +
>> 3 files changed, 457 insertions(+)
>> create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-780.c
>>
>> diff --git a/drivers/media/platform/qcom/camss/Makefile
>> b/drivers/media/platform/qcom/camss/Makefile
>> index c5fcd6eec0f2..ac40bbab18a3 100644
>> --- a/drivers/media/platform/qcom/camss/Makefile
>> +++ b/drivers/media/platform/qcom/camss/Makefile
>> @@ -18,6 +18,7 @@ qcom-camss-objs += \
>> camss-vfe-4-8.o \
>> camss-vfe-17x.o \
>> camss-vfe-480.o \
>> + camss-vfe-780.o \
>> camss-vfe-gen1.o \
>> camss-vfe.o \
>> camss-video.o \
>> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-780.c
>> b/drivers/media/platform/qcom/camss/camss-vfe-780.c
>> new file mode 100644
>> index 000000000000..a78647f23c8c
>> --- /dev/null
>> +++ b/drivers/media/platform/qcom/camss/camss-vfe-780.c
>> @@ -0,0 +1,455 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * camss-vfe-780.c
>> + *
>> + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v780
>> (SM8550)
>> + *
>> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights
>> reserved.
>> + */
>> +
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +#include <linux/iopoll.h>
>> +
>> +#include "camss.h"
>> +#include "camss-vfe.h"
>> +
>> +#define VFE_HW_VERSION (vfe_is_lite(vfe) ? 0x1000 : 0x0)
>> +
>> +#define VFE_IRQ_CMD (vfe_is_lite(vfe) ? 0x1038 : 0x30)
>> +#define IRQ_CMD_GLOBAL_CLEAR BIT(0)
>> +
>> +#define VFE_IRQ_MASK(n) ((vfe_is_lite(vfe) ? 0x1024 :
>> 0x34) + (n) * 4)
>> +#define IRQ_MASK_0_BUS_TOP_IRQ (vfe_is_lite(vfe) ? BIT(0) |
>> BIT(1) | BIT(2) : \
>> + BIT(0) | BIT(4) | BIT(18))
>> +#define IRQ_MASK_1_BUS_TOP_IRQ(n) (vfe_is_lite(vfe) ? BIT(2
>> * n + 2) | BIT(2 * n + 3) : \
>> + BIT(2 * n + 8) | BIT(2 * n + 9))
>> +#define VFE_IRQ_CLEAR(n) ((vfe_is_lite(vfe) ? 0x102C : 0x3C) +
>> (n) * 4)
>> +#define VFE_IRQ_STATUS(n) ((vfe_is_lite(vfe) ? 0x101C : 0x44)
>> + (n) * 4)
>> +
>> +#define BUS_REG_BASE (vfe_is_lite(vfe) ? 0x1200 : 0xC00)
>> +
>> +#define VFE_BUS_WM_CGC_OVERRIDE (BUS_REG_BASE + 0x08)
>> +#define WM_CGC_OVERRIDE_ALL (0x7FFFFFF)
>> +
>> +#define VFE_BUS_WM_TEST_BUS_CTRL (BUS_REG_BASE + 0xdc)
>> +
>> +#define VFE_BUS_WM_CFG(n) (BUS_REG_BASE + 0x200 + (n) * 0x100)
>> +#define WM_CFG_EN (0)
>> +#define WM_VIR_FRM_EN (1)
>> +#define WM_CFG_MODE (16)
>> +#define MODE_QCOM_PLAIN (0)
>> +#define MODE_MIPI_RAW (1)
>> +#define VFE_BUS_WM_IMAGE_ADDR(n) (BUS_REG_BASE + 0x204 + (n) * 0x100)
>> +#define VFE_BUS_WM_FRAME_INCR(n) (BUS_REG_BASE + 0x208 + (n) * 0x100)
>> +#define VFE_BUS_WM_IMAGE_CFG_0(n) (BUS_REG_BASE + 0x20c + (n) *
>> 0x100)
>> +#define WM_IMAGE_CFG_0_DEFAULT_WIDTH (0xFFFF)
>> +#define VFE_BUS_WM_IMAGE_CFG_1(n) (BUS_REG_BASE + 0x210 + (n) *
>> 0x100)
>> +#define VFE_BUS_WM_IMAGE_CFG_2(n) (BUS_REG_BASE + 0x214 + (n) *
>> 0x100)
>> +#define WM_IMAGE_CFG_2_DEFAULT_STRIDE (0xFFFF)
>> +#define VFE_BUS_WM_PACKER_CFG(n) (BUS_REG_BASE + 0x218 + (n) * 0x100)
>> +#define VFE_BUS_WM_HEADER_ADDR(n) (BUS_REG_BASE + 0x220 + (n) *
>> 0x100)
>> +#define VFE_BUS_WM_HEADER_INCR(n) (BUS_REG_BASE + 0x224 + (n) *
>> 0x100)
>> +#define VFE_BUS_WM_HEADER_CFG(n) (BUS_REG_BASE + 0x228 + (n) * 0x100)
>> +
>> +#define VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(n) (BUS_REG_BASE + 0x230 +
>> (n) * 0x100)
>> +#define VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(n) (BUS_REG_BASE + 0x234
>> + (n) * 0x100)
>> +#define VFE_BUS_WM_FRAMEDROP_PERIOD(n) (BUS_REG_BASE + 0x238 +
>> (n) * 0x100)
>> +#define VFE_BUS_WM_FRAMEDROP_PATTERN(n) (BUS_REG_BASE + 0x23c
>> + (n) * 0x100)
>> +
>> +#define VFE_BUS_WM_MMU_PREFETCH_CFG(n) (BUS_REG_BASE + 0x260 + (n)
>> * 0x100)
>> +#define VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(n) (BUS_REG_BASE +
>> 0x264 + (n) * 0x100)
>> +#define VFE_BUS_WM_SYSTEM_CACHE_CFG(n) (BUS_REG_BASE + 0x268 + (n)
>> * 0x100)
>> +
>> +
>> +/* for titan 780, each bus client is hardcoded to a specific path */
>> +#define RDI_WM(n) ((vfe_is_lite(vfe) ? 0 : 23) + (n))
>
> No admixture of hex and decimal please.
>
>> +
>> +#define MAX_VFE_OUTPUT_LINES 4
>> +#define MAX_VFE_ACT_BUF 1
>> +
>> +static u32 vfe_hw_version(struct vfe_device *vfe)
>> +{
>> + u32 hw_version = readl_relaxed(vfe->base + VFE_HW_VERSION);
>> +
>> + u32 gen = (hw_version >> 28) & 0xF;
>> + u32 rev = (hw_version >> 16) & 0xFFF;
>> + u32 step = hw_version & 0xFFFF;
>> +
>> + dev_info(vfe->camss->dev, "VFE HW Version = %u.%u.%u\n", gen,
>> rev, step);
>> +
>> + return hw_version;
>> +}
>
> Same comment as with CSID, its time to rationalise all of this
> replicated code down to one place, instead of proliferating it further.
>
I understand, but the original driver and current driver are using macro
definition to define the register offset, then we aren't able to add the
common code to one place.
We need to refactor the code to not use macro definition for the
register offset first, then we can reuse the common code.
>> +static void vfe_global_reset(struct vfe_device *vfe)
>> +{
>> +}
>> +
>> +static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct
>> vfe_line *line)
>> +{
>> + struct v4l2_pix_format_mplane *pix =
>> + &line->video_out.active_fmt.fmt.pix_mp;
>> +
>> + wm = RDI_WM(wm); /* map to actual WM used (from wm=RDI index) */
>> +
>> + /* no clock gating at bus input */
>> + writel_relaxed(0, vfe->base + VFE_BUS_WM_CGC_OVERRIDE);
>> +
>> + writel_relaxed(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL);
>> +
>> + writel_relaxed(ALIGN(pix->plane_fmt[0].bytesperline, 16) *
>> pix->height >> 8,
>> + vfe->base + VFE_BUS_WM_FRAME_INCR(wm));
>> + writel_relaxed((WM_IMAGE_CFG_0_DEFAULT_WIDTH & 0xFFFF),
>> + vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm));
>> + writel_relaxed(WM_IMAGE_CFG_2_DEFAULT_STRIDE,
>> + vfe->base + VFE_BUS_WM_IMAGE_CFG_2(wm));
>> + writel_relaxed(0, vfe->base + VFE_BUS_WM_PACKER_CFG(wm));
>> +
>> + /* no dropped frames, one irq per frame */
>> + writel_relaxed(0, vfe->base + VFE_BUS_WM_FRAMEDROP_PERIOD(wm));
>> + writel_relaxed(1, vfe->base + VFE_BUS_WM_FRAMEDROP_PATTERN(wm));
>> + writel_relaxed(0, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(wm));
>> + writel_relaxed(1, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(wm));
>> +
>> + writel_relaxed(1, vfe->base + VFE_BUS_WM_MMU_PREFETCH_CFG(wm));
>> + writel_relaxed(0xFFFFFFFF, vfe->base +
>> VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(wm));
>> +
>> + writel_relaxed(1 << WM_CFG_EN | MODE_MIPI_RAW << WM_CFG_MODE,
>> + vfe->base + VFE_BUS_WM_CFG(wm));
>> +}
>> +
>> +static void vfe_wm_stop(struct vfe_device *vfe, u8 wm)
>> +{
>> + wm = RDI_WM(wm); /* map to actual WM used (from wm=RDI index) */
>> + writel_relaxed(0, vfe->base + VFE_BUS_WM_CFG(wm));
>> +}
>
> vfe_wm_stop() as an example can/should live in a shared file.
>
> As proof of concept code its fine to copy/paste between files but, to
> merge we need to get rid of any replicated code - introducing
> indirection/offsets as necessary.
>
Same with above, we'd better to refactor the code to not use macro
definition for the register offset first.
>> +static void vfe_wm_update(struct vfe_device *vfe, u8 wm, u64 addr,
>> + struct vfe_line *line)
>> +{
>> + wm = RDI_WM(wm); /* map to actual WM used (from wm=RDI index) */
>> + writel_relaxed((addr >> 8) & 0xFFFFFFFF, vfe->base +
>> VFE_BUS_WM_IMAGE_ADDR(wm));
>> +
>> + dev_dbg(vfe->camss->dev, "wm:%d, image buf addr:0x%llx\n",
>> + wm, addr);
>> +}
>> +
>> +static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id
>> line_id)
>> +{
>> + int port_id = line_id;
>> +
>> + v4l2_subdev_notify(&vfe->line[line_id].subdev, NOTIFY_RUP, (void
>> *)&port_id);
>> +}
>> +
>> +static inline void vfe_reg_update_clear(struct vfe_device *vfe,
>> + enum vfe_line_id line_id)
>> +{
>> + int port_id = line_id;
>> +
>> + v4l2_subdev_notify(&vfe->line[line_id].subdev, NOTIFY_RUP_CLEAR,
>> (void *)&port_id);
>> +}
>
> I'm not sure I quite understand why we need to use this API to clear
> registers inside of the address space of the same driver.
>
> Is there not a much more direct way to write our _internal_ registers ?
>
Since the register update(RUP) is moved to CSID, so it isn't _internal_
registers in this hardware.
>
>> +static void vfe_enable_irq_common(struct vfe_device *vfe, enum
>> vfe_line_id line_id)
>> +{
>> + int port_id = line_id;
>> +
>> + /* enable top BUS status IRQ */
>> + writel_relaxed(IRQ_MASK_0_BUS_TOP_IRQ,
>> + vfe->base + VFE_IRQ_MASK(0));
>> +
>> + writel_relaxed(IRQ_MASK_1_BUS_TOP_IRQ(port_id),
>> + vfe->base + VFE_IRQ_MASK(1));
>> +}
>> +
>> +/*
>> + * vfe_isr - VFE module interrupt handler
>> + * @irq: Interrupt line
>> + * @dev: VFE device
>> + *
>> + * Return IRQ_HANDLED on success
>> + */
>> +static irqreturn_t vfe_isr(int irq, void *dev)
>> +{
>> + struct vfe_device *vfe = dev;
>> + u32 status;
>> +
>> + status = readl_relaxed(vfe->base + VFE_IRQ_STATUS(0));
>> + writel_relaxed(status, vfe->base + VFE_IRQ_CLEAR(0));
>> + writel_relaxed(IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD);
>> +
>> + if (status)
>> + dev_dbg(vfe->camss->dev, "Top Status_0:0x%x\n", status);
>> +
>> + status = readl_relaxed(vfe->base + VFE_IRQ_STATUS(1));
>> + writel_relaxed(status, vfe->base + VFE_IRQ_CLEAR(1));
>> + writel_relaxed(IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD);
>> +
>> + if (status)
>> + dev_dbg(vfe->camss->dev, "Top Status_1:0x%x\n", status);
>> +
>> + return IRQ_HANDLED;
>> +}
>
> Why is this ISR required ? What does it do ?
>
> Does it actually run on your reference hardware ?
>
> If the purpose of the ISR is just to clear the status registers, why
> even enable it ?
>
Yeah, we can remove it, it was added for some debug info and verify the
hardware, but it doesn't affect the control in this hardware, so we can
remove it.
>> +
>> +/*
>> + * vfe_halt - Trigger halt on VFE module and wait to complete
>> + * @vfe: VFE device
>> + *
>> + * Return 0 on success or a negative error code otherwise
>> + */
>> +static int vfe_halt(struct vfe_device *vfe)
>> +{
>> + /* rely on vfe_disable_output() to stop the VFE */
>> + return 0;
>> +}
>> +
>> +static int vfe_get_output(struct vfe_line *line)
>> +{
>> + struct vfe_device *vfe = to_vfe(line);
>> + struct vfe_output *output;
>> + unsigned long flags;
>> +
>> + spin_lock_irqsave(&vfe->output_lock, flags);
>> +
>> + output = &line->output;
>> + if (output->state > VFE_OUTPUT_RESERVED) {
>> + dev_err(vfe->camss->dev, "Output is running\n");
>> + goto error;
>> + }
>> +
>> + output->wm_num = 1;
>> +
>> + /* Correspondence between VFE line number and WM number.
>> + * line 0 -> RDI 0, line 1 -> RDI1, line 2 -> RDI2, line 3 ->
>> PIX/RDI3
>> + * Note this 1:1 mapping will not work for PIX streams.
>> + */
>> + output->wm_idx[0] = line->id;
>> + vfe->wm_output_map[line->id] = line->id;
>> +
>> + output->drop_update_idx = 0;
>> +
>> + spin_unlock_irqrestore(&vfe->output_lock, flags);
>> +
>> + return 0;
>> +
>> +error:
>> + spin_unlock_irqrestore(&vfe->output_lock, flags);
>> + output->state = VFE_OUTPUT_OFF;
>> +
>> + return -EINVAL;
>> +}
>> +
>> +static int vfe_enable_output(struct vfe_line *line)
>> +{
>> + struct vfe_device *vfe = to_vfe(line);
>> + struct vfe_output *output = &line->output;
>> + unsigned long flags;
>> + unsigned int i;
>> +
>> + spin_lock_irqsave(&vfe->output_lock, flags);
>> +
>> + vfe_reg_update_clear(vfe, line->id);
>> +
>> + if (output->state > VFE_OUTPUT_RESERVED) {
>> + dev_err(vfe->camss->dev, "Output is not in reserved state %d\n",
>> + output->state);
>> + spin_unlock_irqrestore(&vfe->output_lock, flags);
>> + return -EINVAL;
>> + }
>> +
>> + WARN_ON(output->gen2.active_num);
>> +
>> + output->state = VFE_OUTPUT_ON;
>> +
>> + output->sequence = 0;
>> +
>> + vfe_wm_start(vfe, output->wm_idx[0], line);
>> +
>> + for (i = 0; i < MAX_VFE_ACT_BUF; i++) {
>> + output->buf[i] = vfe_buf_get_pending(output);
>> + if (!output->buf[i])
>> + break;
>> + output->gen2.active_num++;
>> + vfe_wm_update(vfe, output->wm_idx[0],
>> output->buf[i]->addr[0], line);
>> +
>> + vfe_reg_update(vfe, line->id);
>> + }
>> +
>> + spin_unlock_irqrestore(&vfe->output_lock, flags);
>> +
>> + return 0;
>> +}
>
> So you'll see with the WIP code for x1e80100 which is I think the same
> VFE - no one generation less 680 - that this code is copy/pasted.
>
> But there's again no good reason for that. Common code needs to be
> squashed down into one place.
>
Agree, this part can be moved to camss-vfe.c, since they don't have
register configuration, just some common code.
> ---
> bod
Thanks,
Depeng
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 8/8] media: qcom: camss: Add sm8550 support
2024-03-20 16:01 ` Bryan O'Donoghue
@ 2024-03-25 13:16 ` Depeng Shao
0 siblings, 0 replies; 31+ messages in thread
From: Depeng Shao @ 2024-03-25 13:16 UTC (permalink / raw)
To: Bryan O'Donoghue, rfoss, todor.too, andersson, konrad.dybcio,
mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
Hi Bryan,
On 3/21/2024 12:01 AM, Bryan O'Donoghue wrote:
> On 20/03/2024 14:11, Depeng Shao wrote:
>> Add in functional logic throughout the code to support the SM8550.
>>
>> Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
>> ---
>> .../media/platform/qcom/camss/camss-csid.c | 19 +++++++++++++++++++
>> .../media/platform/qcom/camss/camss-csiphy.c | 1 +
>> drivers/media/platform/qcom/camss/camss-vfe.c | 7 +++++++
>> .../media/platform/qcom/camss/camss-video.c | 1 +
>> 4 files changed, 28 insertions(+)
>>
>> diff --git a/drivers/media/platform/qcom/camss/camss-csid.c
>> b/drivers/media/platform/qcom/camss/camss-csid.c
>> index eb27d69e89a1..e9203dc15798 100644
>> --- a/drivers/media/platform/qcom/camss/camss-csid.c
>> +++ b/drivers/media/platform/qcom/camss/camss-csid.c
>> @@ -590,6 +590,25 @@ int msm_csid_subdev_init(struct camss *camss,
>> struct csid_device *csid,
>> csid->base = camss->vfe[id].base +
>> VFE_480_LITE_CSID_OFFSET;
>> else
>> csid->base = camss->vfe[id].base + VFE_480_CSID_OFFSET;
>> + } else if (camss->res->version == CAMSS_8550) {
>> + /* for titan 780, CSID lite registers are inside the VFE lite
>> region,
>> + * between the VFE "top" and "bus" registers. this requires
>> + * VFE to be initialized before CSID
>> + */
>> + if (id >= 2)
>> + csid->base = camss->vfe[id].base;
>
> Hard-coded magic numbers are definitely out.
>
> If you need to differentiate - please include something in the struct
> resources so that the flag is always available and we don't have to
> start doing funky magic index/magic number gymnastics.
>
Sure, will update this part.
>> + else {
>> + csid->base =
>> + devm_platform_ioremap_resource_byname(pdev,
>> res->reg[0]);
>> + if (id != 0)
>> + csid->top_base = camss->csid[0].top_base;
>> + else
>> + csid->top_base =
>> + devm_platform_ioremap_resource_byname(pdev,
>> res->reg[1]);
>> + }
>
> What is the point of hooking the TOP base just to clear our the status
> registers ?
>
> We take no meaningful action in the ISR that I can see.
>
The csid top is a new small hardware block, it controls the output of
CSID, since the CSID can connect to Sensor Front End(SFE) or original
VFE in CSID gen3.
>
>> +
>> + if (IS_ERR(csid->base))
>> + return PTR_ERR(csid->base);
>> } else {
>> csid->base = devm_platform_ioremap_resource_byname(pdev,
>> res->reg[0]);
>> if (IS_ERR(csid->base))
>> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c
>> b/drivers/media/platform/qcom/camss/camss-csiphy.c
>> index 45b3a8e5dea4..f35af0dd2147 100644
>> --- a/drivers/media/platform/qcom/camss/camss-csiphy.c
>> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
>> @@ -579,6 +579,7 @@ int msm_csiphy_subdev_init(struct camss *camss,
>> case CAMSS_845:
>> case CAMSS_8250:
>> case CAMSS_8280XP:
>> + case CAMSS_8550:
>> csiphy->formats = csiphy_formats_sdm845;
>> csiphy->nformats = ARRAY_SIZE(csiphy_formats_sdm845);
>> break;
>> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c
>> b/drivers/media/platform/qcom/camss/camss-vfe.c
>> index d875237cf244..ff115c5521c6 100644
>> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
>> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
>> @@ -226,6 +226,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line,
>> u32 sink_code,
>> case CAMSS_845:
>> case CAMSS_8250:
>> case CAMSS_8280XP:
>> + case CAMSS_8550:
>> switch (sink_code) {
>> case MEDIA_BUS_FMT_YUYV8_1X16:
>> {
>> @@ -296,6 +297,10 @@ int vfe_reset(struct vfe_device *vfe)
>> reinit_completion(&vfe->reset_complete);
>> + // The reset has been moved to csid in 8550
>
> Please run checkpatch.pl on your code before submission C++ are not
> allowed.
>
> ---
> bod
Thanks,
Depeng
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 5/8] media: qcom: camss: Add CSID gen3 driver
2024-03-20 15:40 ` Bryan O'Donoghue
2024-03-20 16:12 ` Bryan O'Donoghue
@ 2024-03-25 13:38 ` Depeng Shao
1 sibling, 0 replies; 31+ messages in thread
From: Depeng Shao @ 2024-03-25 13:38 UTC (permalink / raw)
To: Bryan O'Donoghue, rfoss, todor.too, andersson, konrad.dybcio,
mchehab, quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
Hi Bryan,
On 3/20/2024 11:40 PM, Bryan O'Donoghue wrote:
> On 20/03/2024 14:11, Depeng Shao wrote:
>> The CSID in SM8550 is gen3, it has new register
>> offset and new functionality, the buf done irq,
>> register update and reset is moved to CSID gen3.
>>
>> Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
>> Co-developed-by: Yongsheng Li <quic_yon@quicinc.com>
>> Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
>> ---
>> drivers/media/platform/qcom/camss/Makefile | 1 +
>> .../platform/qcom/camss/camss-csid-gen3.c | 639 ++++++++++++++++++
>> .../platform/qcom/camss/camss-csid-gen3.h | 26 +
>> .../media/platform/qcom/camss/camss-csid.h | 1 +
>> 4 files changed, 667 insertions(+)
>> create mode 100644 drivers/media/platform/qcom/camss/camss-csid-gen3.c
>> create mode 100644 drivers/media/platform/qcom/camss/camss-csid-gen3.h
>>
>> diff --git a/drivers/media/platform/qcom/camss/Makefile
>> b/drivers/media/platform/qcom/camss/Makefile
>> index 28eba4bf3e38..c5fcd6eec0f2 100644
>> --- a/drivers/media/platform/qcom/camss/Makefile
>> +++ b/drivers/media/platform/qcom/camss/Makefile
>> @@ -7,6 +7,7 @@ qcom-camss-objs += \
>> camss-csid-4-1.o \
>> camss-csid-4-7.o \
>> camss-csid-gen2.o \
>> + camss-csid-gen3.o \
>> camss-csiphy-2ph-1-0.o \
>> camss-csiphy-3ph-1-0.o \
>> camss-csiphy-2-1-2.o \
>> diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen3.c
>> b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
>> new file mode 100644
>> index 000000000000..b97005f7065d
>> --- /dev/null
>> +++ b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
>> @@ -0,0 +1,639 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * camss-csid-gen3.c
>> + *
>> + * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
>> + *
>> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights
>> reserved.
>> + */
>> +#include <linux/completion.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +#include <linux/kernel.h>
>> +#include <linux/of.h>
>> +#include <linux/delay.h>
>
> Please alphanumerically sort your include list.
>
>> +
>> +
>> +#include "camss-csid.h"
>> +#include "camss-csid-gen3.h"
>> +#include "camss.h"
>
> and here.
>
>> +
>> +#define CSID_TOP_IO_PATH_CFG0(csid) (0x4 * (csid))
>> +#define OUTPUT_IFE_EN 0x100
>> +#define INTERNAL_CSID 1
>> +
>> +#define CSID_HW_VERSION 0x0
>> +#define HW_VERSION_STEPPING 0
>> +#define HW_VERSION_REVISION 16
>> +#define HW_VERSION_GENERATION 28
>> +
>> +#define CSID_RST_CFG 0xC
>> +#define RST_MODE 0
>> +#define RST_LOCATION 4
>> +
>> +#define CSID_RST_CMD 0x10
>> +#define SELECT_HW_RST 0
>> +#define SELECT_SW_RST 1
>> +#define SELECT_IRQ_RST 2
>> +
>> +#define CSID_CSI2_RX_IRQ_STATUS 0x9C
>> +#define CSID_CSI2_RX_IRQ_MASK 0xA0
>> +#define CSID_CSI2_RX_IRQ_CLEAR 0xA4
>> +#define CSID_CSI2_RX_IRQ_SET 0xA8
>> +
>> +#define CSID_CSI2_RDIN_IRQ_STATUS(rdi) (0xEC + 0x10 * (rdi))
>> +#define CSID_CSI2_RDIN_IRQ_MASK(rdi) (0xF0 + 0x10 * (rdi))
>> +#define CSID_CSI2_RDIN_INFO_FIFO_FULL 2
>> +#define CSID_CSI2_RDIN_INFO_CAMIF_EOF 3
>> +#define CSID_CSI2_RDIN_INFO_CAMIF_SOF 4
>> +#define CSID_CSI2_RDIN_INFO_INPUT_EOF 9
>> +#define CSID_CSI2_RDIN_INFO_INPUT_SOF 12
>> +#define CSID_CSI2_RDIN_ERROR_REC_FRAME_DROP 18
>> +#define CSID_CSI2_RDIN_ERROR_REC_OVERFLOW_IRQ 19
>> +#define CSID_CSI2_RDIN_ERROR_REC_CCIF_VIOLATION 20
>> +#define CSID_CSI2_RDIN_EPOCH0 21
>> +#define CSID_CSI2_RDIN_EPOCH1 22
>> +#define CSID_CSI2_RDIN_RUP_DONE 23
>> +#define CSID_CSI2_RDIN_CCIF_VIOLATION 29
>> +
>> +#define CSID_CSI2_RDIN_IRQ_CLEAR(rdi) (0xF4 + 0x10 * (rdi))
>> +#define CSID_CSI2_RDIN_IRQ_SET(rdi) (0xF8 + 0x10 * (rdi))
>> +
>> +#define CSID_TOP_IRQ_STATUS 0x7C
>> +#define TOP_IRQ_STATUS_RESET_DONE 0
>> +#define CSID_TOP_IRQ_MASK 0x80
>> +#define CSID_TOP_IRQ_CLEAR 0x84
>> +#define CSID_TOP_IRQ_SET 0x88
>> +#define CSID_IRQ_CMD 0x14
>> +#define IRQ_CMD_CLEAR 0
>> +#define IRQ_CMD_SET 4
>> +
>> +#define CSID_BUF_DONE_IRQ_STATUS 0x8C
>> +#define BUF_DONE_IRQ_STATUS_RDI_OFFSET (csid_is_lite(csid) ? 1
>> : 14)
>
> Stick with hex please 0x01 : 0x0e
>
>> +#define CSID_BUF_DONE_IRQ_MASK 0x90
>> +#define CSID_BUF_DONE_IRQ_CLEAR 0x94
>> +#define CSID_BUF_DONE_IRQ_SET 0x98
>> +
>> +#define CSID_CSI2_RX_CFG0 0x200
>> +#define CSI2_RX_CFG0_NUM_ACTIVE_LANES 0
>> +#define CSI2_RX_CFG0_DL0_INPUT_SEL 4
>> +#define CSI2_RX_CFG0_DL1_INPUT_SEL 8
>> +#define CSI2_RX_CFG0_DL2_INPUT_SEL 12
>> +#define CSI2_RX_CFG0_DL3_INPUT_SEL 16
>> +#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 27
>> +#define CSI2_RX_CFG0_TPG_NUM_SEL 28
>> +
>> +#define CSID_CSI2_RX_CFG1 0x204
>> +#define CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN 0
>> +#define CSI2_RX_CFG1_DE_SCRAMBLE_EN 1
>> +#define CSI2_RX_CFG1_VC_MODE 2
>> +#define CSI2_RX_CFG1_COMPLETE_STREAM_EN 4
>> +#define CSI2_RX_CFG1_COMPLETE_STREAM_FRAME_TIMING 5
>> +#define CSI2_RX_CFG1_MISR_EN 6
>> +#define CSI2_RX_CFG1_PHY_BIST_EN 7
>> +#define CSI2_RX_CFG1_EPD_MODE 8
>> +#define CSI2_RX_CFG1_EOTP_EN 9
>> +#define CSI2_RX_CFG1_DYN_SWITCH_EN 10
>> +#define CSI2_RX_CFG1_RUP_AUP_LATCH_DIS 11
>> +
>> +#define CSID_CSI2_RX_CAPTURE_CTRL 0x208
>> +#define CSI2_RX_CAPTURE_CTRL_LONG_PKT_CAPTURE_EN 0
>> +#define CSI2_RX_CAPTURE_CTRL_SHORT_PKT_CAPTURE_EN 1
>> +#define CSI2_RX_CAPTURE_CTRL_CPHY_PKT_CAPTURE_EN 3
>> +#define CSI2_RX_CAPTURE_CTRL_LONG_PKT_CAPTURE_DT 4
>> +#define CSI2_RX_CAPTURE_CTRL_LONG_PKT_CAPTURE_VC 10
>> +#define CSI2_RX_CAPTURE_CTRL_SHORT_PKT_CAPTURE_VC 15
>> +#define CSI2_RX_CAPTURE_CTRL_CPHY_PKT_CAPTURE_DT 20
>> +#define CSI2_RX_CAPTURE_CTRL_CPHY_PKT_CAPTURE_VC 26
>> +
>> +#define CSID_RDI_CFG0(rdi) (0x500 + 0x100 * (rdi))
>> +#define RDI_CFG0_VFR_EN 0
>> +#define RDI_CFG0_FRAME_ID_DEC_EN 1
>> +#define RDI_CFG0_RETIME_DIS 5
>> +#define RDI_CFG0_TIMESTAMP_EN 6
>> +#define RDI_CFG0_TIMESTAMP_STB_SEL 8
>> +#define RDI_CFG0_DECODE_FORMAT 12
>> +#define RDI_CFG0_DT 16
>> +#define RDI_CFG0_VC 22
>> +#define RDI_CFG0_DT_ID 27
>> +#define RDI_CFG0_EN 31
>> +
>> +#define CSID_RDI_CFG1(rdi) (0x510 + 0x100 * (rdi))
>> +#define RDI_CFG1_BYTE_CNTR_EN 2
>> +#define RDI_CFG1_DROP_H_EN 5
>> +#define RDI_CFG1_DROP_V_EN 6
>> +#define RDI_CFG1_CROP_H_EN 7
>> +#define RDI_CFG1_CROP_V_EN 8
>> +#define RDI_CFG1_MISR_EN 9
>> +#define RDI_CFG1_PIX_STORE 10
>> +#define RDI_CFG1_PLAIN_ALIGNMENT 11
>> +#define RDI_CFG1_PLAIN_FORMAT 12
>> +#define RDI_CFG1_EARLY_EOF_EN 14
>> +#define RDI_CFG1_PACKING_FORMAT 15
>> +
>> +#define CSID_RDI_CTRL(rdi) (0x504 + 0x100 * (rdi))
>> +#define RDI_CTRL_START_CMD 0
>> +#define RDI_CTRL_START_MODE 2
>> +
>> +#define CSID_RDI_EPOCH_IRQ_CFG(rdi) (0x52C + 0x100 * (rdi))
>> +
>> +#define CSID_RDI_FRM_DROP_PATTERN(rdi) (0x540 + 0x100 *
>> (rdi))
>> +#define CSID_RDI_FRM_DROP_PERIOD(rdi) (0x544 + 0x100 * (rdi))
>> +#define CSID_RDI_IRQ_SUBSAMPLE_PATTERN(rdi) (0x548 + 0x100 *
>> (rdi))
>> +#define CSID_RDI_IRQ_SUBSAMPLE_PERIOD(rdi) (0x54C + 0x100 *
>> (rdi))
>> +#define CSID_RDI_RPP_PIX_DROP_PATTERN(rdi) (0x558 + 0x100 *
>> (rdi))
>> +#define CSID_RDI_RPP_PIX_DROP_PERIOD(rdi) (0x55C + 0x100 * (rdi))
>> +#define CSID_RDI_RPP_LINE_DROP_PATTERN(rdi) (0x560 + 0x100 *
>> (rdi))
>> +#define CSID_RDI_RPP_LINE_DROP_PERIOD(rdi) (0x564 + 0x100 *
>> (rdi))
>> +
>> +#define CSID_RDI_RPP_HCROP(rdi) (0x550 + 0x100 * (rdi))
>> +#define CSID_RDI_RPP_VCROP(rdi) (0x554 + 0x100 * (rdi))
>> +
>> +#define CSID_RDI_ERROR_RECOVERY_CFG0(rdi) (0x514 + 0x100 * (rdi))
>> +
>> +#define CSID_DISCARD_FRAMES 4
>> +
>> +#define CSID_REG_UPDATE_CMD 0x18
>> +static inline int reg_update_rdi(struct csid_device *csid, int n)
>> +{
>> + return BIT(n + 4) + BIT(20 + n);
>> +}
>> +
>> +#define REG_UPDATE_RDI reg_update_rdi
>> +
>> +static const struct csid_format csid_formats[] = {
>> + {
>> + MEDIA_BUS_FMT_UYVY8_1X16,
>> + DATA_TYPE_YUV422_8BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
>> + 8,
>> + 2,
>> + },
>> + {
>> + MEDIA_BUS_FMT_VYUY8_1X16,
>> + DATA_TYPE_YUV422_8BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
>> + 8,
>> + 2,
>> + },
>> + {
>> + MEDIA_BUS_FMT_YUYV8_1X16,
>> + DATA_TYPE_YUV422_8BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
>> + 8,
>> + 2,
>> + },
>> + {
>> + MEDIA_BUS_FMT_YVYU8_1X16,
>> + DATA_TYPE_YUV422_8BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
>> + 8,
>> + 2,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SBGGR8_1X8,
>> + DATA_TYPE_RAW_8BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
>> + 8,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SGBRG8_1X8,
>> + DATA_TYPE_RAW_8BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
>> + 8,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SGRBG8_1X8,
>> + DATA_TYPE_RAW_8BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
>> + 8,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SRGGB8_1X8,
>> + DATA_TYPE_RAW_8BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
>> + 8,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SBGGR10_1X10,
>> + DATA_TYPE_RAW_10BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
>> + 10,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SGBRG10_1X10,
>> + DATA_TYPE_RAW_10BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
>> + 10,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SGRBG10_1X10,
>> + DATA_TYPE_RAW_10BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
>> + 10,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SRGGB10_1X10,
>> + DATA_TYPE_RAW_10BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
>> + 10,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_Y8_1X8,
>> + DATA_TYPE_RAW_8BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_8_BIT,
>> + 8,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_Y10_1X10,
>> + DATA_TYPE_RAW_10BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_10_BIT,
>> + 10,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SBGGR12_1X12,
>> + DATA_TYPE_RAW_12BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_12_BIT,
>> + 12,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SGBRG12_1X12,
>> + DATA_TYPE_RAW_12BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_12_BIT,
>> + 12,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SGRBG12_1X12,
>> + DATA_TYPE_RAW_12BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_12_BIT,
>> + 12,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SRGGB12_1X12,
>> + DATA_TYPE_RAW_12BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_12_BIT,
>> + 12,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SBGGR14_1X14,
>> + DATA_TYPE_RAW_14BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_14_BIT,
>> + 14,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SGBRG14_1X14,
>> + DATA_TYPE_RAW_14BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_14_BIT,
>> + 14,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SGRBG14_1X14,
>> + DATA_TYPE_RAW_14BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_14_BIT,
>> + 14,
>> + 1,
>> + },
>> + {
>> + MEDIA_BUS_FMT_SRGGB14_1X14,
>> + DATA_TYPE_RAW_14BIT,
>> + DECODE_FORMAT_UNCOMPRESSED_14_BIT,
>> + 14,
>> + 1,
>> + },
>> +};
>> +
>> +static void __csid_configure_rx(struct csid_device *csid,
>> + struct csid_phy_config *phy, int vc)
>> +{
>> + int val;
>> +
>> + 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;
>> +
>> + writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG0);
>> +
>> + val = 1 << CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN;
>> + if (vc > 3)
>> + val |= 1 << CSI2_RX_CFG1_VC_MODE;
>> + writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1);
>> +}
>> +
>> +static void __csid_ctrl_rdi(struct csid_device *csid, int enable, u8
>> rdi)
>> +{
>> + int val;
>> +
>> + if (enable)
>> + val = 1 << RDI_CTRL_START_CMD;
>> + else
>> + val = 0 << RDI_CTRL_START_CMD;
>> + writel_relaxed(val, csid->base + CSID_RDI_CTRL(rdi));
>> +}
>> +
>> +static void __csid_configure_top(struct csid_device *csid)
>> +{
>> + u32 val;
>> +
>> + if (csid->top_base) {
>> + val = OUTPUT_IFE_EN | INTERNAL_CSID;
>> + writel_relaxed(val, csid->top_base +
>> CSID_TOP_IO_PATH_CFG0(csid->id));
>> + }
>> +}
>> +
>> +static void __csid_configure_rdi_stream(struct csid_device *csid, u8
>> enable, u8 vc)
>> +{
>> + u32 val;
>> + u8 lane_cnt = csid->phy.lane_cnt;
>> + /* Source pads matching RDI channels on hardware. Pad 1 -> RDI0,
>> Pad 2 -> RDI1, etc. */
>> + struct v4l2_mbus_framefmt *input_format =
>> &csid->fmt[MSM_CSID_PAD_FIRST_SRC + vc];
>> + const struct csid_format *format =
>> csid_get_fmt_entry(csid->formats, csid->nformats,
>> + input_format->code);
>> +
>> + if (!lane_cnt)
>> + lane_cnt = 4;
>> +
>> + val = 0;
>> + writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PERIOD(vc));
>> +
>> + /*
>> + * DT_ID is a two bit bitfield that is concatenated with
>> + * the four least significant bits of the five bit VC
>> + * bitfield to generate an internal CID value.
>> + *
>> + * CSID_RDI_CFG0(vc)
>> + * DT_ID : 28:27
>> + * VC : 26:22
>> + * DT : 21:16
>> + *
>> + * CID : VC 3:0 << 2 | DT_ID 1:0
>> + */
>> + u8 dt_id = vc & 0x03;
>> +
>> + val = 1 << RDI_CFG0_TIMESTAMP_EN;
>> + val |= 2 << RDI_CFG0_TIMESTAMP_STB_SEL;
>> + /* note: for non-RDI path, this should be format->decode_format */
>> + val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT;
>> + val |= vc << RDI_CFG0_VC;
>> + val |= format->data_type << RDI_CFG0_DT;
>> + val |= dt_id << RDI_CFG0_DT_ID;
>> +
>> + writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc));
>> +
>> + val = 1 << RDI_CFG1_PACKING_FORMAT;
>> + val |= 1 << RDI_CFG1_PIX_STORE;
>> + val |= 1 << RDI_CFG1_DROP_H_EN;
>> + val |= 1 << RDI_CFG1_DROP_V_EN;
>> + val |= 1 << RDI_CFG1_CROP_H_EN;
>> + val |= 1 << RDI_CFG1_CROP_V_EN;
>> + val |= RDI_CFG1_EARLY_EOF_EN;
>> +
>> + writel_relaxed(val, csid->base + CSID_RDI_CFG1(vc));
>> +
>> + val = 0;
>> + writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PERIOD(vc));
>> +
>> + val = 1;
>> + writel_relaxed(val, csid->base +
>> CSID_RDI_IRQ_SUBSAMPLE_PATTERN(vc));
>> +
>> + val = 0;
>> + writel_relaxed(val, csid->base + CSID_RDI_CTRL(vc));
>> +
>> + val = readl_relaxed(csid->base + CSID_RDI_CFG0(vc));
>> + val |= enable << RDI_CFG0_EN;
>> + writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc));
>> +}
>
> Hmm.
>
> So I think 90% of the code here can be moved into a shared file -
> ideally instantiated in gen2.c and then reused here rather than
> copy/paste from one file to the other.
>
> Lets sync up and try to get a unified tree for x1e80100 and sm8550 for
> that purpose.
>
> I think the code you have here is slightly further along that the
> CSID/VFE stuff I've been working with.
>
> But still - reductio ad absurdum - we need to functionally decompose and
> not replicate code.
>
Yes, agree, most of the code are same, but the difficult part is most of
the code is configuring the register which are defined as macro
definition, and they are different between different platform.
>> +
>> +static void csid_configure_stream(struct csid_device *csid, u8 enable)
>> +{
>> + u8 i;
>> +
>> + /* Loop through all enabled VCs and configure stream for each */
>> + for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
>> + if (csid->phy.en_vc & BIT(i)) {
>> + __csid_configure_top(csid);
>> + __csid_configure_rdi_stream(csid, enable, i);
>> + __csid_configure_rx(csid, &csid->phy, i);
>> + __csid_ctrl_rdi(csid, enable, i);
>> + }
>> +}
>
> Another example, straight copy/paste - we need to zap all of that.
>
> ---
> bod
Thanks,
Depeng
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 6/8] media: qcom: camss: Add new VFE driver for SM8550
2024-03-20 14:11 ` [PATCH v2 6/8] media: qcom: camss: Add new VFE driver for SM8550 Depeng Shao
2024-03-20 15:57 ` Bryan O'Donoghue
@ 2024-04-09 13:39 ` Bryan O'Donoghue
2024-04-09 15:35 ` Bryan O'Donoghue
1 sibling, 1 reply; 31+ messages in thread
From: Bryan O'Donoghue @ 2024-04-09 13:39 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, andersson, konrad.dybcio, mchehab,
quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 20/03/2024 14:11, Depeng Shao wrote:
> +#define VFE_IRQ_STATUS(n) ((vfe_is_lite(vfe) ? 0x101C : 0x44) + (n) * 4)
These defines do the right thing for the RDI however
1. Please use 'rdi' not 'n' as the parameter here and
2. Pass 'vfe' explicitly not implicitly
Right now you need a variable named 'vfe' in the scope of the macro but
that ought to be an explicit parameter passed to the macro.
---
bod
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 6/8] media: qcom: camss: Add new VFE driver for SM8550
2024-04-09 13:39 ` Bryan O'Donoghue
@ 2024-04-09 15:35 ` Bryan O'Donoghue
0 siblings, 0 replies; 31+ messages in thread
From: Bryan O'Donoghue @ 2024-04-09 15:35 UTC (permalink / raw)
To: Depeng Shao, rfoss, todor.too, andersson, konrad.dybcio, mchehab,
quic_yon
Cc: linux-kernel, linux-media, linux-arm-msm
On 09/04/2024 14:39, Bryan O'Donoghue wrote:
> 1. Please use 'rdi' not 'n' as the parameter here and
Ignore this comment 'n' is the right value here - you've already used
'rdi' in CSID which is the appropriate place 'n' is correct here.
---
bod
^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2024-04-09 15:35 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-20 14:11 [PATCH v2 0/8] media: qcom: camss: Add sm8550 support Depeng Shao
2024-03-20 14:11 ` [PATCH v2 1/8] media: qcom: camss: Add CAMSS_8550 enum Depeng Shao
2024-03-20 14:50 ` Bryan O'Donoghue
2024-03-20 15:51 ` Krzysztof Kozlowski
2024-03-20 15:53 ` Bryan O'Donoghue
2024-03-20 15:59 ` Krzysztof Kozlowski
2024-03-20 14:11 ` [PATCH v2 2/8] media: qcom: camss: Add subdev notify support Depeng Shao
2024-03-20 16:08 ` Bryan O'Donoghue
2024-03-20 16:41 ` Gjorgji Rosikopulos (Consultant)
2024-03-20 14:11 ` [PATCH v2 3/8] media: qcom: camss: Add new csiphy driver 2-1-2 Depeng Shao
2024-03-20 15:21 ` Bryan O'Donoghue
2024-03-25 12:15 ` Depeng Shao
2024-03-20 14:11 ` [PATCH v2 4/8] media: qcom: camss: Add new params for csid_device Depeng Shao
2024-03-20 15:26 ` Bryan O'Donoghue
2024-03-20 15:53 ` Krzysztof Kozlowski
2024-03-25 12:30 ` Depeng Shao
2024-03-20 14:11 ` [PATCH v2 5/8] media: qcom: camss: Add CSID gen3 driver Depeng Shao
2024-03-20 15:40 ` Bryan O'Donoghue
2024-03-20 16:12 ` Bryan O'Donoghue
2024-03-25 13:38 ` Depeng Shao
2024-03-20 14:11 ` [PATCH v2 6/8] media: qcom: camss: Add new VFE driver for SM8550 Depeng Shao
2024-03-20 15:57 ` Bryan O'Donoghue
2024-03-25 12:47 ` Depeng Shao
2024-04-09 13:39 ` Bryan O'Donoghue
2024-04-09 15:35 ` Bryan O'Donoghue
2024-03-20 14:11 ` [PATCH v2 7/8] media: qcom: camss: Add sm8550 resources Depeng Shao
2024-03-20 15:50 ` Krzysztof Kozlowski
2024-03-20 14:11 ` [PATCH v2 8/8] media: qcom: camss: Add sm8550 support Depeng Shao
2024-03-20 16:01 ` Bryan O'Donoghue
2024-03-25 13:16 ` Depeng Shao
2024-03-20 15:08 ` [PATCH v2 0/8] " Bryan O'Donoghue
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).