linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/17] CAMSS: SM8250 support (and some fixes)
@ 2021-06-08 22:34 Jonathan Marek
  2021-06-08 22:34 ` [PATCH 01/17] media: camss: csiphy-3ph: don't print HW version as an error Jonathan Marek
                   ` (17 more replies)
  0 siblings, 18 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:34 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Andy Gross, Bjorn Andersson,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Hans Verkuil, open list,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER,
	Mauro Carvalho Chehab, Rob Herring, Todor Tomov

This adds initial support for SM8250 and its 4 VFEs and 6 CSIPHYs.
The only big change is the added camss-vfe-480.c to support the
Titan 480 VFE.

v2:
 - Fixed some typos in commit messages (patches 02 and 08)
 - patch 03 ("media: camss: csiphy-3ph: add support for SM8250 CSI DPHY"):
   - moved definition of CAMSS_8250 to this patch,
   - removed unused lane_enable variable
   - added a default unreachable case to avoid a warning
   - added a is_gen2 variable (minor rework)
 - Undo DECODE_FORMAT_PAYLOAD_ONLY change, add comment instead (patch 04)
 - "ops" reworks in addition to removing dead code (patch 12)
 - renamed csid-170 to csid-gen2, added defines for offsets, add missing
   camnoc_axi clock to sm8250 vfe resources (patch 16/17)

Jonathan Marek (17):
  media: camss: csiphy-3ph: don't print HW version as an error
  media: camss: csiphy-3ph: disable interrupts
  media: camss: csiphy-3ph: add support for SM8250 CSI DPHY
  media: camss: csid-170: fix non-10bit formats
  media: camss: csid-170: don't enable unused irqs
  media: camss: csid-170: remove stray comment
  media: camss: csid-170: support more than one lite vfe
  media: camss: csid-170: set the right HALT_CMD when disabled
  media: camss: csid: allow csid to work without a regulator
  media: camss: remove vdda-csiN from sdm845 resources
  media: camss: fix VFE irq name
  media: camss: remove some vfe ops and clean up dead vfe-170 code
  media: camss: vfe-170: fix "VFE halt timeout" error
  media: camss: Add initial support for VFE hardware version Titan 480
  media: camss: add support for V4L2_PIX_FMT_GREY for sdm845 HW
  media: camss: add support for SM8250 camss
  media: dt-bindings: media: camss: Add qcom,sm8250-camss binding

 .../bindings/media/qcom,sm8250-camss.yaml     | 399 +++++++++++++
 drivers/media/platform/qcom/camss/Makefile    |   3 +-
 .../{camss-csid-170.c => camss-csid-gen2.c}   |  32 +-
 .../media/platform/qcom/camss/camss-csid.c    |  45 +-
 .../media/platform/qcom/camss/camss-csid.h    |   2 +-
 .../qcom/camss/camss-csiphy-3ph-1-0.c         | 184 ++++--
 .../media/platform/qcom/camss/camss-csiphy.c  |   9 +-
 .../media/platform/qcom/camss/camss-vfe-170.c | 101 +---
 .../media/platform/qcom/camss/camss-vfe-4-1.c |  25 +-
 .../media/platform/qcom/camss/camss-vfe-4-7.c |  63 +-
 .../media/platform/qcom/camss/camss-vfe-4-8.c |  65 +--
 .../media/platform/qcom/camss/camss-vfe-480.c | 545 ++++++++++++++++++
 .../platform/qcom/camss/camss-vfe-gen1.c      |  94 +--
 .../platform/qcom/camss/camss-vfe-gen1.h      |  39 +-
 drivers/media/platform/qcom/camss/camss-vfe.c |  29 +-
 drivers/media/platform/qcom/camss/camss-vfe.h |  17 +-
 .../media/platform/qcom/camss/camss-video.c   |   5 +-
 drivers/media/platform/qcom/camss/camss.c     | 205 ++++++-
 drivers/media/platform/qcom/camss/camss.h     |   1 +
 19 files changed, 1523 insertions(+), 340 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
 rename drivers/media/platform/qcom/camss/{camss-csid-170.c => camss-csid-gen2.c} (95%)
 create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-480.c

-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 01/17] media: camss: csiphy-3ph: don't print HW version as an error
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
@ 2021-06-08 22:34 ` Jonathan Marek
  2021-06-08 22:34 ` [PATCH 02/17] media: camss: csiphy-3ph: disable interrupts Jonathan Marek
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:34 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

Avoid unnecessary noise in normal usage (it prints every time CSIPHY is
powered on).

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
index e318c822ab04c..5948abdcd2206 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
@@ -163,7 +163,7 @@ static void csiphy_hw_version_read(struct csiphy_device *csiphy,
 	hw_version |= readl_relaxed(csiphy->base +
 				   CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(15)) << 24;
 
-	dev_err(dev, "CSIPHY 3PH HW Version = 0x%08x\n", hw_version);
+	dev_dbg(dev, "CSIPHY 3PH HW Version = 0x%08x\n", hw_version);
 }
 
 /*
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 02/17] media: camss: csiphy-3ph: disable interrupts
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
  2021-06-08 22:34 ` [PATCH 01/17] media: camss: csiphy-3ph: don't print HW version as an error Jonathan Marek
@ 2021-06-08 22:34 ` Jonathan Marek
  2021-06-08 22:34 ` [PATCH 03/17] media: camss: csiphy-3ph: add support for SM8250 CSI DPHY Jonathan Marek
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:34 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

The driver does nothing with the interrupts, so set the irq mask registers
to zero to avoid wasting CPU time for nothing.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 .../qcom/camss/camss-csiphy-3ph-1-0.c         | 35 ++-----------------
 1 file changed, 3 insertions(+), 32 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
index 5948abdcd2206..783b65295d20b 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
@@ -352,38 +352,9 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy,
 	else if (csiphy->camss->version == CAMSS_845)
 		csiphy_gen2_config_lanes(csiphy, settle_cnt);
 
-	val = 0xff;
-	writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(11));
-
-	val = 0xff;
-	writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(12));
-
-	val = 0xfb;
-	writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(13));
-
-	val = 0xff;
-	writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(14));
-
-	val = 0x7f;
-	writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(15));
-
-	val = 0xff;
-	writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(16));
-
-	val = 0xff;
-	writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(17));
-
-	val = 0xef;
-	writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(18));
-
-	val = 0xff;
-	writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(19));
-
-	val = 0xff;
-	writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(20));
-
-	val = 0xff;
-	writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(21));
+	/* IRQ_MASK registers - disable all interrupts */
+	for (i = 11; i < 22; i++)
+		writel_relaxed(0, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(i));
 }
 
 static void csiphy_lanes_disable(struct csiphy_device *csiphy,
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 03/17] media: camss: csiphy-3ph: add support for SM8250 CSI DPHY
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
  2021-06-08 22:34 ` [PATCH 01/17] media: camss: csiphy-3ph: don't print HW version as an error Jonathan Marek
  2021-06-08 22:34 ` [PATCH 02/17] media: camss: csiphy-3ph: disable interrupts Jonathan Marek
@ 2021-06-08 22:34 ` Jonathan Marek
  2021-06-08 22:34 ` [PATCH 04/17] media: camss: csid-170: fix non-10bit formats Jonathan Marek
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:34 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

Add support for CSIPHY (2PH/DPHY mode) found on SM8250 hardware.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 .../qcom/camss/camss-csiphy-3ph-1-0.c         | 147 ++++++++++++++++--
 drivers/media/platform/qcom/camss/camss.h     |   1 +
 2 files changed, 139 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
index 783b65295d20b..c5b0a91b36f88 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
@@ -62,6 +62,7 @@ struct csiphy_reg_t {
 	u32 csiphy_param_type;
 };
 
+/* GEN2 1.0 2PH */
 static const struct
 csiphy_reg_t lane_regs_sdm845[5][14] = {
 	{
@@ -146,6 +147,121 @@ csiphy_reg_t lane_regs_sdm845[5][14] = {
 	},
 };
 
+/* GEN2 1.2.1 2PH */
+static const struct
+csiphy_reg_t lane_regs_sm8250[5][20] = {
+	{
+		{0x0030, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0900, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0908, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0904, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0904, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0034, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0010, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x001C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x0000, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0024, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+	},
+	{
+		{0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0C80, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0C88, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0C84, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0C84, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0704, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0734, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0710, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x071C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x073C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0708, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x070c, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0714, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0724, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+	},
+	{
+		{0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0A00, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0A08, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0A04, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0A04, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0234, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0210, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x021C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0208, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x0200, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0224, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+	},
+	{
+		{0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0B00, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0B08, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0B04, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0B04, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0434, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0410, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x041C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x043C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0408, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x0400, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0428, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0424, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+	},
+	{
+		{0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0C00, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0C08, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0C04, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0C04, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0634, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0610, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x061C, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0608, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x0600, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x060c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0628, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0624, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+	},
+};
+
 static void csiphy_hw_version_read(struct csiphy_device *csiphy,
 				   struct device *dev)
 {
@@ -298,13 +414,25 @@ static void csiphy_gen1_config_lanes(struct csiphy_device *csiphy,
 static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy,
 				     u8 settle_cnt)
 {
-	int i, l;
+	const struct csiphy_reg_t *r;
+	int i, l, array_size;
 	u32 val;
 
-	for (l = 0; l < 5; l++) {
-		for (i = 0; i < 14; i++) {
-			const struct csiphy_reg_t *r = &lane_regs_sdm845[l][i];
+	switch (csiphy->camss->version) {
+	case CAMSS_845:
+		r = &lane_regs_sdm845[0][0];
+		array_size = ARRAY_SIZE(lane_regs_sdm845[0]);
+		break;
+	case CAMSS_8250:
+		r = &lane_regs_sm8250[0][0];
+		array_size = ARRAY_SIZE(lane_regs_sm8250[0]);
+		break;
+	default:
+		unreachable();
+	}
 
+	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;
@@ -325,13 +453,15 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy,
 				s64 link_freq, u8 lane_mask)
 {
 	struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg;
+	bool is_gen2 = (csiphy->camss->version == CAMSS_845 ||
+			csiphy->camss->version == CAMSS_8250);
 	u8 settle_cnt;
 	u8 val;
 	int i;
 
 	settle_cnt = csiphy_settle_cnt_calc(link_freq, csiphy->timer_clk_rate);
 
-	val = BIT(c->clk.pos);
+	val = is_gen2 ? BIT(7) : BIT(c->clk.pos);
 	for (i = 0; i < c->num_data; i++)
 		val |= BIT(c->data[i].pos * 2);
 
@@ -346,11 +476,10 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy,
 	val = 0x00;
 	writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(0));
 
-	if (csiphy->camss->version == CAMSS_8x16 ||
-	    csiphy->camss->version == CAMSS_8x96)
-		csiphy_gen1_config_lanes(csiphy, cfg, settle_cnt);
-	else if (csiphy->camss->version == CAMSS_845)
+	if (is_gen2)
 		csiphy_gen2_config_lanes(csiphy, settle_cnt);
+	else
+		csiphy_gen1_config_lanes(csiphy, cfg, settle_cnt);
 
 	/* IRQ_MASK registers - disable all interrupts */
 	for (i = 11; i < 22; i++)
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index dc8b4154f92b3..377e2474a485f 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -69,6 +69,7 @@ enum camss_version {
 	CAMSS_8x96,
 	CAMSS_660,
 	CAMSS_845,
+	CAMSS_8250,
 };
 
 struct camss {
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 04/17] media: camss: csid-170: fix non-10bit formats
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (2 preceding siblings ...)
  2021-06-08 22:34 ` [PATCH 03/17] media: camss: csiphy-3ph: add support for SM8250 CSI DPHY Jonathan Marek
@ 2021-06-08 22:34 ` Jonathan Marek
  2021-06-08 22:34 ` [PATCH 05/17] media: camss: csid-170: don't enable unused irqs Jonathan Marek
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:34 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab, Hans Verkuil,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

Use the decode_format/data_type from the "format" struct instead of a
hardcoded 10-bit format.

Fixes: eebe6d00e9bf ("media: camss: Add support for CSID hardware version Titan 170")
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 drivers/media/platform/qcom/camss/camss-csid-170.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csid-170.c b/drivers/media/platform/qcom/camss/camss-csid-170.c
index ac22ff29d2a9f..aa65043c33037 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-170.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-170.c
@@ -366,7 +366,7 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
 			val |= input_format->width & 0x1fff << TPG_DT_n_CFG_0_FRAME_WIDTH;
 			writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_0(0));
 
-			val = DATA_TYPE_RAW_10BIT << TPG_DT_n_CFG_1_DATA_TYPE;
+			val = format->data_type << TPG_DT_n_CFG_1_DATA_TYPE;
 			writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_1(0));
 
 			val = tg->mode << TPG_DT_n_CFG_2_PAYLOAD_MODE;
@@ -382,8 +382,9 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
 		val = 1 << RDI_CFG0_BYTE_CNTR_EN;
 		val |= 1 << RDI_CFG0_FORMAT_MEASURE_EN;
 		val |= 1 << RDI_CFG0_TIMESTAMP_EN;
+		/* note: for non-RDI path, this should be format->decode_format */
 		val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT;
-		val |= DATA_TYPE_RAW_10BIT << RDI_CFG0_DATA_TYPE;
+		val |= format->data_type << RDI_CFG0_DATA_TYPE;
 		val |= vc << RDI_CFG0_VIRTUAL_CHANNEL;
 		val |= dt_id << RDI_CFG0_DT_ID;
 		writel_relaxed(val, csid->base + CSID_RDI_CFG0(0));
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 05/17] media: camss: csid-170: don't enable unused irqs
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (3 preceding siblings ...)
  2021-06-08 22:34 ` [PATCH 04/17] media: camss: csid-170: fix non-10bit formats Jonathan Marek
@ 2021-06-08 22:34 ` Jonathan Marek
  2021-06-08 22:34 ` [PATCH 06/17] media: camss: csid-170: remove stray comment Jonathan Marek
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:34 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab, Hans Verkuil,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

csid_isr() only checks for the reset irq, so enabling any other irqs
doesn't make sense. The "RDI irq" comment is also wrong, the register
should be CSID_CSI2_RDIN_IRQ_MASK. Without this fix there may be an
excessive amount of irqs.

Fixes: eebe6d00e9bf ("media: camss: Add support for CSID hardware version Titan 170")
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 drivers/media/platform/qcom/camss/camss-csid-170.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csid-170.c b/drivers/media/platform/qcom/camss/camss-csid-170.c
index aa65043c33037..a006c8dbceb13 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-170.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-170.c
@@ -444,12 +444,6 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
 	val |= 1 << CSI2_RX_CFG1_MISR_EN;
 	writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1); // csi2_vc_mode_shift_val ?
 
-	/* error irqs start at BIT(11) */
-	writel_relaxed(~0u, csid->base + CSID_CSI2_RX_IRQ_MASK);
-
-	/* RDI irq */
-	writel_relaxed(~0u, csid->base + CSID_TOP_IRQ_MASK);
-
 	val = 1 << RDI_CTRL_HALT_CMD;
 	writel_relaxed(val, csid->base + CSID_RDI_CTRL(0));
 }
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 06/17] media: camss: csid-170: remove stray comment
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (4 preceding siblings ...)
  2021-06-08 22:34 ` [PATCH 05/17] media: camss: csid-170: don't enable unused irqs Jonathan Marek
@ 2021-06-08 22:34 ` Jonathan Marek
  2021-06-08 22:34 ` [PATCH 07/17] media: camss: csid-170: support more than one lite vfe Jonathan Marek
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:34 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab, Hans Verkuil,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

This is a leftover from my original patches, it doesn't serve any purpose.
(it was a reminder to figure out how downstream sets a particular field in
the register).

Fixes: eebe6d00e9bf ("media: camss: Add support for CSID hardware version Titan 170")
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 drivers/media/platform/qcom/camss/camss-csid-170.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csid-170.c b/drivers/media/platform/qcom/camss/camss-csid-170.c
index a006c8dbceb13..f0c6a72592f99 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-170.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-170.c
@@ -442,7 +442,7 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
 
 	val = 1 << CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN;
 	val |= 1 << CSI2_RX_CFG1_MISR_EN;
-	writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1); // csi2_vc_mode_shift_val ?
+	writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1);
 
 	val = 1 << RDI_CTRL_HALT_CMD;
 	writel_relaxed(val, csid->base + CSID_RDI_CTRL(0));
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 07/17] media: camss: csid-170: support more than one lite vfe
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (5 preceding siblings ...)
  2021-06-08 22:34 ` [PATCH 06/17] media: camss: csid-170: remove stray comment Jonathan Marek
@ 2021-06-08 22:34 ` Jonathan Marek
  2021-06-08 22:34 ` [PATCH 08/17] media: camss: csid-170: set the right HALT_CMD when disabled Jonathan Marek
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:34 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

Change the IS_LITE condition so that it returns true for the second lite
vfe found on titan 480 hardware (8250), which will have id == 3.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 drivers/media/platform/qcom/camss/camss-csid-170.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csid-170.c b/drivers/media/platform/qcom/camss/camss-csid-170.c
index f0c6a72592f99..2c84d40fe3e04 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-170.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-170.c
@@ -21,7 +21,7 @@
  * interface support. As a result of that it has an
  * alternate register layout.
  */
-#define IS_LITE		(csid->id == 2 ? 1 : 0)
+#define IS_LITE		(csid->id >= 2 ? 1 : 0)
 
 #define CSID_HW_VERSION		0x0
 #define		HW_VERSION_STEPPING	0
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 08/17] media: camss: csid-170: set the right HALT_CMD when disabled
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (6 preceding siblings ...)
  2021-06-08 22:34 ` [PATCH 07/17] media: camss: csid-170: support more than one lite vfe Jonathan Marek
@ 2021-06-08 22:34 ` Jonathan Marek
  2021-06-08 22:34 ` [PATCH 09/17] media: camss: csid: allow csid to work without a regulator Jonathan Marek
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:34 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab, Hans Verkuil,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

Use the "HALT_CMD_RESUME_AT_FRAME_BOUNDARY" define instead of a "1" which
is otherwise confusing, and add a "HALT_CMD_HALT_AT_FRAME_BOUNDARY" which
is set when disabling.

Fixes: eebe6d00e9bf ("media: camss: Add support for CSID hardware version Titan 170")
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 drivers/media/platform/qcom/camss/camss-csid-170.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csid-170.c b/drivers/media/platform/qcom/camss/camss-csid-170.c
index 2c84d40fe3e04..22a7d7ad63403 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-170.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-170.c
@@ -105,7 +105,8 @@
 #define CSID_RDI_CTRL(rdi)			((IS_LITE ? 0x208 : 0x308)\
 						+ 0x100 * (rdi))
 #define		RDI_CTRL_HALT_CMD		0
-#define			ALT_CMD_RESUME_AT_FRAME_BOUNDARY	1
+#define			HALT_CMD_HALT_AT_FRAME_BOUNDARY		0
+#define			HALT_CMD_RESUME_AT_FRAME_BOUNDARY	1
 #define		RDI_CTRL_HALT_MODE		2
 
 #define CSID_RDI_FRM_DROP_PATTERN(rdi)			((IS_LITE ? 0x20C : 0x30C)\
@@ -444,7 +445,10 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable)
 	val |= 1 << CSI2_RX_CFG1_MISR_EN;
 	writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1);
 
-	val = 1 << RDI_CTRL_HALT_CMD;
+	if (enable)
+		val = HALT_CMD_RESUME_AT_FRAME_BOUNDARY << RDI_CTRL_HALT_CMD;
+	else
+		val = HALT_CMD_HALT_AT_FRAME_BOUNDARY << RDI_CTRL_HALT_CMD;
 	writel_relaxed(val, csid->base + CSID_RDI_CTRL(0));
 }
 
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 09/17] media: camss: csid: allow csid to work without a regulator
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (7 preceding siblings ...)
  2021-06-08 22:34 ` [PATCH 08/17] media: camss: csid-170: set the right HALT_CMD when disabled Jonathan Marek
@ 2021-06-08 22:34 ` Jonathan Marek
  2021-06-10  8:01   ` Robert Foss
  2021-06-08 22:34 ` [PATCH 10/17] media: camss: remove vdda-csiN from sdm845 resources Jonathan Marek
                   ` (8 subsequent siblings)
  17 siblings, 1 reply; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:34 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

At least for titan HW, CSID don't have an associated regulator. This change
is necessary to be able to model this in the CSID resources.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 drivers/media/platform/qcom/camss/camss-csid.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index cc11fbfdae132..528674dea06ca 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -162,7 +162,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
 			return ret;
 		}
 
-		ret = regulator_enable(csid->vdda);
+		ret = csid->vdda ? regulator_enable(csid->vdda) : 0;
 		if (ret < 0) {
 			pm_runtime_put_sync(dev);
 			return ret;
@@ -170,14 +170,16 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
 
 		ret = csid_set_clock_rates(csid);
 		if (ret < 0) {
-			regulator_disable(csid->vdda);
+			if (csid->vdda)
+				regulator_disable(csid->vdda);
 			pm_runtime_put_sync(dev);
 			return ret;
 		}
 
 		ret = camss_enable_clocks(csid->nclocks, csid->clock, dev);
 		if (ret < 0) {
-			regulator_disable(csid->vdda);
+			if (csid->vdda)
+				regulator_disable(csid->vdda);
 			pm_runtime_put_sync(dev);
 			return ret;
 		}
@@ -188,7 +190,8 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
 		if (ret < 0) {
 			disable_irq(csid->irq);
 			camss_disable_clocks(csid->nclocks, csid->clock);
-			regulator_disable(csid->vdda);
+			if (csid->vdda)
+				regulator_disable(csid->vdda);
 			pm_runtime_put_sync(dev);
 			return ret;
 		}
@@ -197,7 +200,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
 	} else {
 		disable_irq(csid->irq);
 		camss_disable_clocks(csid->nclocks, csid->clock);
-		ret = regulator_disable(csid->vdda);
+		ret = csid->vdda ? regulator_disable(csid->vdda) : 0;
 		pm_runtime_put_sync(dev);
 	}
 
@@ -634,7 +637,9 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
 
 	/* Regulator */
 
-	csid->vdda = devm_regulator_get(dev, res->regulator[0]);
+	csid->vdda = NULL;
+	if (res->regulator[0])
+		csid->vdda = devm_regulator_get(dev, res->regulator[0]);
 	if (IS_ERR(csid->vdda)) {
 		dev_err(dev, "could not get regulator\n");
 		return PTR_ERR(csid->vdda);
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 10/17] media: camss: remove vdda-csiN from sdm845 resources
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (8 preceding siblings ...)
  2021-06-08 22:34 ` [PATCH 09/17] media: camss: csid: allow csid to work without a regulator Jonathan Marek
@ 2021-06-08 22:34 ` Jonathan Marek
  2021-06-08 22:35 ` [PATCH 11/17] media: camss: fix VFE irq name Jonathan Marek
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:34 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

This isn't used and only works because devm_regulator_get() returns a dummy
regulator.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 drivers/media/platform/qcom/camss/camss.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index ef100d5f77636..c08d6d6f6f90d 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -542,7 +542,7 @@ static const struct resources csiphy_res_845[] = {
 static const struct resources csid_res_845[] = {
 	/* CSID0 */
 	{
-		.regulator = { "vdda-csi0" },
+		.regulator = { NULL },
 		.clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
 				"soc_ahb", "vfe0", "vfe0_src",
 				"vfe0_cphy_rx", "csi0",
@@ -562,7 +562,7 @@ static const struct resources csid_res_845[] = {
 
 	/* CSID1 */
 	{
-		.regulator = { "vdda-csi1" },
+		.regulator = { NULL },
 		.clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
 				"soc_ahb", "vfe1", "vfe1_src",
 				"vfe1_cphy_rx", "csi1",
@@ -582,7 +582,7 @@ static const struct resources csid_res_845[] = {
 
 	/* CSID2 */
 	{
-		.regulator = { "vdda-csi2" },
+		.regulator = { NULL },
 		.clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src",
 				"soc_ahb", "vfe_lite", "vfe_lite_src",
 				"vfe_lite_cphy_rx", "csi2",
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 11/17] media: camss: fix VFE irq name
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (9 preceding siblings ...)
  2021-06-08 22:34 ` [PATCH 10/17] media: camss: remove vdda-csiN from sdm845 resources Jonathan Marek
@ 2021-06-08 22:35 ` Jonathan Marek
  2021-06-08 22:35 ` [PATCH 12/17] media: camss: remove some vfe ops and clean up dead vfe-170 code Jonathan Marek
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:35 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

vfe->id isn't set yet, so use "id" instead here.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 drivers/media/platform/qcom/camss/camss-vfe.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 15695fd466c4d..dec89079c6ae4 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -1290,7 +1290,6 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
 	case CAMSS_660:
 		vfe->ops = &vfe_ops_4_8;
 		break;
-
 	case CAMSS_845:
 		vfe->ops = &vfe_ops_170;
 		break;
@@ -1319,7 +1318,7 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
 
 	vfe->irq = r->start;
 	snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d",
-		 dev_name(dev), MSM_VFE_NAME, vfe->id);
+		 dev_name(dev), MSM_VFE_NAME, id);
 	ret = devm_request_irq(dev, vfe->irq, vfe->ops->isr,
 			       IRQF_TRIGGER_RISING, vfe->irq_name, vfe);
 	if (ret < 0) {
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 12/17] media: camss: remove some vfe ops and clean up dead vfe-170 code
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (10 preceding siblings ...)
  2021-06-08 22:35 ` [PATCH 11/17] media: camss: fix VFE irq name Jonathan Marek
@ 2021-06-08 22:35 ` Jonathan Marek
  2021-06-09  3:23   ` kernel test robot
                     ` (2 more replies)
  2021-06-08 22:35 ` [PATCH 13/17] media: camss: vfe-170: fix "VFE halt timeout" error Jonathan Marek
                   ` (5 subsequent siblings)
  17 siblings, 3 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:35 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

Delete vfe_isr_ops. In all cases the right function can just be called
directly.

From vfe_hw_ops:
 - enable_irq_common is completely dead
 - isr_read/violation_read dont need ops (call right function directly)
 - reg_update/reg_update_clear moved to gen1 ops, vfe-170 can call the
   right function directly

This reveals dead function in vfe-170 which are deleted. comp_done IRQ
handling is also removed for vfe-170 - only RDI is supported.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
---
 .../media/platform/qcom/camss/camss-vfe-170.c | 89 ++----------------
 .../media/platform/qcom/camss/camss-vfe-4-1.c | 25 +++--
 .../media/platform/qcom/camss/camss-vfe-4-7.c | 63 ++++++-------
 .../media/platform/qcom/camss/camss-vfe-4-8.c | 65 ++++++-------
 .../platform/qcom/camss/camss-vfe-gen1.c      | 94 ++++++++++---------
 .../platform/qcom/camss/camss-vfe-gen1.h      | 39 +++++++-
 drivers/media/platform/qcom/camss/camss-vfe.c | 16 ----
 drivers/media/platform/qcom/camss/camss-vfe.h | 16 ----
 8 files changed, 169 insertions(+), 238 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c
index 8594d275b41d1..1de793b218194 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-170.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c
@@ -188,20 +188,6 @@ static void vfe_hw_version_read(struct vfe_device *vfe, struct device *dev)
 	dev_err(dev, "VFE HW Version = %u.%u.%u\n", gen, rev, step);
 }
 
-static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits)
-{
-	u32 bits = readl_relaxed(vfe->base + reg);
-
-	writel_relaxed(bits & ~clr_bits, vfe->base + reg);
-}
-
-static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits)
-{
-	u32 bits = readl_relaxed(vfe->base + reg);
-
-	writel_relaxed(bits | set_bits, vfe->base + reg);
-}
-
 static void vfe_global_reset(struct vfe_device *vfe)
 {
 	u32 reset_bits = GLOBAL_RESET_CMD_CORE		|
@@ -305,38 +291,16 @@ static inline void vfe_reg_update_clear(struct vfe_device *vfe,
 
 static void vfe_enable_irq_common(struct vfe_device *vfe)
 {
-	vfe_reg_set(vfe, VFE_IRQ_MASK_0, ~0u);
-	vfe_reg_set(vfe, VFE_IRQ_MASK_1, ~0u);
+	writel_relaxed(~0u, vfe->base + VFE_IRQ_MASK_0);
+	writel_relaxed(~0u, vfe->base + VFE_IRQ_MASK_1);
 
 	writel_relaxed(~0u, vfe->base + VFE_BUS_IRQ_MASK(0));
 	writel_relaxed(~0u, vfe->base + VFE_BUS_IRQ_MASK(1));
 	writel_relaxed(~0u, vfe->base + VFE_BUS_IRQ_MASK(2));
 }
 
-static void vfe_isr_halt_ack(struct vfe_device *vfe)
-{
-	complete(&vfe->halt_complete);
-}
-
-static void vfe_isr_read(struct vfe_device *vfe, u32 *status0, u32 *status1)
-{
-	*status0 = readl_relaxed(vfe->base + VFE_IRQ_STATUS_0);
-	*status1 = readl_relaxed(vfe->base + VFE_IRQ_STATUS_1);
-
-	writel_relaxed(*status0, vfe->base + VFE_IRQ_CLEAR_0);
-	writel_relaxed(*status1, vfe->base + VFE_IRQ_CLEAR_1);
-
-	/* Enforce ordering between IRQ Clear and Global IRQ Clear */
-	wmb();
-	writel_relaxed(CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD);
-}
-
-static void vfe_violation_read(struct vfe_device *vfe)
-{
-	u32 violation = readl_relaxed(vfe->base + VFE_VIOLATION_STATUS);
-
-	pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
-}
+static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id);
+static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm);
 
 /*
  * vfe_isr - VFE module interrupt handler
@@ -369,24 +333,16 @@ static irqreturn_t vfe_isr(int irq, void *dev)
 	writel_relaxed(1, vfe->base + VFE_BUS_IRQ_CLEAR_GLOBAL);
 
 	if (status0 & STATUS_0_RESET_ACK)
-		vfe->isr_ops.reset_ack(vfe);
+		vfe_isr_reset_ack(vfe);
 
 	for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
 		if (status0 & STATUS_0_RDI_REG_UPDATE(i))
-			vfe->isr_ops.reg_update(vfe, i);
-
-	for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
-		if (status0 & STATUS_1_RDI_SOF(i))
-			vfe->isr_ops.sof(vfe, i);
-
-	for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
-		if (vfe_bus_status[0] & STATUS0_COMP_BUF_DONE(i))
-			vfe->isr_ops.comp_done(vfe, i);
+			vfe_isr_reg_update(vfe, i);
 
 	for (wm = 0; wm < MSM_VFE_IMAGE_MASTERS_NUM; wm++)
 		if (status0 & BIT(9))
 			if (vfe_bus_status[1] & STATUS1_WM_CLIENT_BUF_DONE(wm))
-				vfe->isr_ops.wm_done(vfe, wm);
+				vfe_isr_wm_done(vfe, wm);
 
 	return IRQ_HANDLED;
 }
@@ -456,7 +412,6 @@ static int vfe_enable_output(struct vfe_line *line)
 {
 	struct vfe_device *vfe = to_vfe(line);
 	struct vfe_output *output = &line->output;
-	const struct vfe_hw_ops *ops = vfe->ops;
 	struct media_entity *sensor;
 	unsigned long flags;
 	unsigned int frame_skip = 0;
@@ -474,7 +429,7 @@ static int vfe_enable_output(struct vfe_line *line)
 
 	spin_lock_irqsave(&vfe->output_lock, flags);
 
-	ops->reg_update_clear(vfe, line->id);
+	vfe_reg_update_clear(vfe, line->id);
 
 	if (output->state != VFE_OUTPUT_OFF) {
 		dev_err(vfe->camss->dev, "Output is not in reserved state %d\n",
@@ -501,7 +456,7 @@ static int vfe_enable_output(struct vfe_line *line)
 		vfe_wm_update(vfe, output->wm_idx[0], output->buf[i]->addr[0], line);
 	}
 
-	ops->reg_update(vfe, line->id);
+	vfe_reg_update(vfe, line->id);
 
 	spin_unlock_irqrestore(&vfe->output_lock, flags);
 
@@ -607,16 +562,6 @@ static int vfe_disable(struct vfe_line *line)
 	return 0;
 }
 
-/*
- * vfe_isr_sof - Process start of frame interrupt
- * @vfe: VFE Device
- * @line_id: VFE line
- */
-static void vfe_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id)
-{
-	/* nop */
-}
-
 /*
  * vfe_isr_reg_update - Process reg update interrupt
  * @vfe: VFE Device
@@ -628,7 +573,7 @@ static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
 	unsigned long flags;
 
 	spin_lock_irqsave(&vfe->output_lock, flags);
-	vfe->ops->reg_update_clear(vfe, line_id);
+	vfe_reg_update_clear(vfe, line_id);
 
 	output = &vfe->line[line_id].output;
 
@@ -747,15 +692,6 @@ static int vfe_queue_buffer(struct camss_video *vid,
 	return 0;
 }
 
-static const struct vfe_isr_ops vfe_isr_ops_170 = {
-	.reset_ack = vfe_isr_reset_ack,
-	.halt_ack = vfe_isr_halt_ack,
-	.reg_update = vfe_isr_reg_update,
-	.sof = vfe_isr_sof,
-	.comp_done = vfe_isr_comp_done,
-	.wm_done = vfe_isr_wm_done,
-};
-
 static const struct camss_video_ops vfe_video_ops_170 = {
 	.queue_buffer = vfe_queue_buffer,
 	.flush_buffers = vfe_flush_buffers,
@@ -763,7 +699,6 @@ static const struct camss_video_ops vfe_video_ops_170 = {
 
 static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
 {
-	vfe->isr_ops = vfe_isr_ops_170;
 	vfe->video_ops = vfe_video_ops_170;
 
 	vfe->line_num = VFE_LINE_NUM_GEN2;
@@ -772,15 +707,11 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
 const struct vfe_hw_ops vfe_ops_170 = {
 	.global_reset = vfe_global_reset,
 	.hw_version_read = vfe_hw_version_read,
-	.isr_read = vfe_isr_read,
 	.isr = vfe_isr,
 	.pm_domain_off = vfe_pm_domain_off,
 	.pm_domain_on = vfe_pm_domain_on,
-	.reg_update_clear = vfe_reg_update_clear,
-	.reg_update = vfe_reg_update,
 	.subdev_init = vfe_subdev_init,
 	.vfe_disable = vfe_disable,
 	.vfe_enable = vfe_enable,
 	.vfe_halt = vfe_halt,
-	.violation_read = vfe_violation_read,
 };
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
index 53c56a8d45458..873f348cf2fae 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
@@ -898,34 +898,34 @@ static irqreturn_t vfe_isr(int irq, void *dev)
 	u32 value0, value1;
 	int i, j;
 
-	vfe->ops->isr_read(vfe, &value0, &value1);
+	vfe_isr_read(vfe, &value0, &value1);
 
 	dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
 		value0, value1);
 
 	if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)
-		vfe->isr_ops.reset_ack(vfe);
+		vfe_isr_reset_ack(vfe);
 
 	if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
-		vfe->ops->violation_read(vfe);
+		vfe_violation_read(vfe);
 
 	if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
-		vfe->isr_ops.halt_ack(vfe);
+		vfe_gen1_isr_halt_ack(vfe);
 
 	for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++)
 		if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
-			vfe->isr_ops.reg_update(vfe, i);
+			vfe_gen1_reg_update(vfe, i);
 
 	if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)
-		vfe->isr_ops.sof(vfe, VFE_LINE_PIX);
+		vfe_gen1_isr_sof(vfe, VFE_LINE_PIX);
 
 	for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
 		if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))
-			vfe->isr_ops.sof(vfe, i);
+			vfe_gen1_isr_sof(vfe, i);
 
 	for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
 		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {
-			vfe->isr_ops.comp_done(vfe, i);
+			vfe_gen1_isr_comp_done(vfe, i);
 			for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)
 				if (vfe->wm_output_map[j] == VFE_LINE_PIX)
 					value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);
@@ -933,7 +933,7 @@ static irqreturn_t vfe_isr(int irq, void *dev)
 
 	for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)
 		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))
-			vfe->isr_ops.wm_done(vfe, i);
+			vfe_gen1_isr_wm_done(vfe, i);
 
 	return IRQ_HANDLED;
 }
@@ -991,11 +991,12 @@ static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_1 = {
 	.wm_set_pong_addr = vfe_wm_set_pong_addr,
 	.wm_set_subsample = vfe_wm_set_subsample,
 	.wm_set_ub_cfg = vfe_wm_set_ub_cfg,
+	.reg_update_clear = vfe_reg_update_clear,
+	.reg_update = vfe_reg_update,
 };
 
 static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
 {
-	vfe->isr_ops = vfe_isr_ops_gen1;
 	vfe->ops_gen1 = &vfe_ops_gen1_4_1;
 	vfe->video_ops = vfe_video_ops_gen1;
 
@@ -1005,15 +1006,11 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
 const struct vfe_hw_ops vfe_ops_4_1 = {
 	.global_reset = vfe_global_reset,
 	.hw_version_read = vfe_hw_version_read,
-	.isr_read = vfe_isr_read,
 	.isr = vfe_isr,
 	.pm_domain_off = vfe_pm_domain_off,
 	.pm_domain_on = vfe_pm_domain_on,
-	.reg_update_clear = vfe_reg_update_clear,
-	.reg_update = vfe_reg_update,
 	.subdev_init = vfe_subdev_init,
 	.vfe_disable = vfe_gen1_disable,
 	.vfe_enable = vfe_gen1_enable,
 	.vfe_halt = vfe_gen1_halt,
-	.violation_read = vfe_violation_read,
 };
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
index a596352177583..35178f66360eb 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
@@ -1037,7 +1037,25 @@ static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev)
 	return ret;
 }
 
+static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
+{
+	*value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
+	*value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
 
+	writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
+	writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
+
+	/* Enforce barrier between local & global IRQ clear */
+	wmb();
+	writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
+}
+
+static void vfe_violation_read(struct vfe_device *vfe)
+{
+	u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
+
+	pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
+}
 
 /*
  * vfe_isr - VFE module interrupt handler
@@ -1052,34 +1070,34 @@ static irqreturn_t vfe_isr(int irq, void *dev)
 	u32 value0, value1;
 	int i, j;
 
-	vfe->ops->isr_read(vfe, &value0, &value1);
+	vfe_isr_read(vfe, &value0, &value1);
 
 	dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
 		value0, value1);
 
 	if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)
-		vfe->isr_ops.reset_ack(vfe);
+		vfe_isr_reset_ack(vfe);
 
 	if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
-		vfe->ops->violation_read(vfe);
+		vfe_violation_read(vfe);
 
 	if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
-		vfe->isr_ops.halt_ack(vfe);
+		vfe_gen1_isr_halt_ack(vfe);
 
 	for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
 		if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
-			vfe->isr_ops.reg_update(vfe, i);
+			vfe_gen1_reg_update(vfe, i);
 
 	if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)
-		vfe->isr_ops.sof(vfe, VFE_LINE_PIX);
+		vfe_gen1_isr_sof(vfe, VFE_LINE_PIX);
 
 	for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
 		if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))
-			vfe->isr_ops.sof(vfe, i);
+			vfe_gen1_isr_sof(vfe, i);
 
 	for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
 		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {
-			vfe->isr_ops.comp_done(vfe, i);
+			vfe_gen1_isr_comp_done(vfe, i);
 			for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)
 				if (vfe->wm_output_map[j] == VFE_LINE_PIX)
 					value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);
@@ -1087,24 +1105,11 @@ static irqreturn_t vfe_isr(int irq, void *dev)
 
 	for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)
 		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))
-			vfe->isr_ops.wm_done(vfe, i);
+			vfe_gen1_isr_wm_done(vfe, i);
 
 	return IRQ_HANDLED;
 }
 
-static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
-{
-	*value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
-	*value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
-
-	writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
-	writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
-
-	/* Enforce barrier between local & global IRQ clear */
-	wmb();
-	writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
-}
-
 /*
  * vfe_pm_domain_off - Disable power domains specific to this VFE.
  * @vfe: VFE Device
@@ -1141,13 +1146,6 @@ static int vfe_pm_domain_on(struct vfe_device *vfe)
 	return 0;
 }
 
-static void vfe_violation_read(struct vfe_device *vfe)
-{
-	u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
-
-	pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
-}
-
 static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_7 = {
 	.bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi,
 	.bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi,
@@ -1183,11 +1181,12 @@ static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_7 = {
 	.wm_set_pong_addr = vfe_wm_set_pong_addr,
 	.wm_set_subsample = vfe_wm_set_subsample,
 	.wm_set_ub_cfg = vfe_wm_set_ub_cfg,
+	.reg_update_clear = vfe_reg_update_clear,
+	.reg_update = vfe_reg_update,
 };
 
 static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
 {
-	vfe->isr_ops = vfe_isr_ops_gen1;
 	vfe->ops_gen1 = &vfe_ops_gen1_4_7;
 	vfe->video_ops = vfe_video_ops_gen1;
 
@@ -1197,15 +1196,11 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
 const struct vfe_hw_ops vfe_ops_4_7 = {
 	.global_reset = vfe_global_reset,
 	.hw_version_read = vfe_hw_version_read,
-	.isr_read = vfe_isr_read,
 	.isr = vfe_isr,
 	.pm_domain_off = vfe_pm_domain_off,
 	.pm_domain_on = vfe_pm_domain_on,
-	.reg_update_clear = vfe_reg_update_clear,
-	.reg_update = vfe_reg_update,
 	.subdev_init = vfe_subdev_init,
 	.vfe_disable = vfe_gen1_disable,
 	.vfe_enable = vfe_gen1_enable,
 	.vfe_halt = vfe_gen1_halt,
-	.violation_read = vfe_violation_read,
 };
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-8.c b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
index 998429dbb65cd..d4ddbbf44f514 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
@@ -968,6 +968,26 @@ static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev)
 	return ret;
 }
 
+static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
+{
+	*value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
+	*value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
+
+	writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
+	writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
+
+	/* Enforce barrier between local & global IRQ clear */
+	wmb();
+	writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
+}
+
+static void vfe_violation_read(struct vfe_device *vfe)
+{
+	u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
+
+	pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
+}
+
 /*
  * vfe_isr - VFE module interrupt handler
  * @irq: Interrupt line
@@ -981,34 +1001,34 @@ static irqreturn_t vfe_isr(int irq, void *dev)
 	u32 value0, value1;
 	int i, j;
 
-	vfe->ops->isr_read(vfe, &value0, &value1);
+	vfe_isr_read(vfe, &value0, &value1);
 
 	dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
 		value0, value1);
 
 	if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)
-		vfe->isr_ops.reset_ack(vfe);
+		vfe_isr_reset_ack(vfe);
 
 	if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
-		vfe->ops->violation_read(vfe);
+		vfe_violation_read(vfe);
 
 	if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
-		vfe->isr_ops.halt_ack(vfe);
+		vfe_gen1_isr_halt_ack(vfe);
 
 	for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
 		if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
-			vfe->isr_ops.reg_update(vfe, i);
+			vfe_gen1_reg_update(vfe, i);
 
 	if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)
-		vfe->isr_ops.sof(vfe, VFE_LINE_PIX);
+		vfe_gen1_isr_sof(vfe, VFE_LINE_PIX);
 
 	for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
 		if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))
-			vfe->isr_ops.sof(vfe, i);
+			vfe_gen1_isr_sof(vfe, i);
 
 	for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
 		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {
-			vfe->isr_ops.comp_done(vfe, i);
+			vfe_gen1_isr_comp_done(vfe, i);
 			for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)
 				if (vfe->wm_output_map[j] == VFE_LINE_PIX)
 					value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);
@@ -1016,7 +1036,7 @@ static irqreturn_t vfe_isr(int irq, void *dev)
 
 	for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)
 		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))
-			vfe->isr_ops.wm_done(vfe, i);
+			vfe_gen1_isr_wm_done(vfe, i);
 
 	return IRQ_HANDLED;
 }
@@ -1081,19 +1101,6 @@ static void vfe_set_ds(struct vfe_device *vfe)
 	writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16);
 }
 
-static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
-{
-	*value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
-	*value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
-
-	writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
-	writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
-
-	/* Enforce barrier between local & global IRQ clear */
-	wmb();
-	writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
-}
-
 /*
  * vfe_pm_domain_off - Disable power domains specific to this VFE.
  * @vfe: VFE Device
@@ -1125,13 +1132,6 @@ static int vfe_pm_domain_on(struct vfe_device *vfe)
 	return 0;
 }
 
-static void vfe_violation_read(struct vfe_device *vfe)
-{
-	u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
-
-	pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
-}
-
 static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_8 = {
 	.bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi,
 	.bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi,
@@ -1167,11 +1167,12 @@ static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_8 = {
 	.wm_set_pong_addr = vfe_wm_set_pong_addr,
 	.wm_set_subsample = vfe_wm_set_subsample,
 	.wm_set_ub_cfg = vfe_wm_set_ub_cfg,
+	.reg_update_clear = vfe_reg_update_clear,
+	.reg_update = vfe_reg_update,
 };
 
 static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
 {
-	vfe->isr_ops = vfe_isr_ops_gen1;
 	vfe->ops_gen1 = &vfe_ops_gen1_4_8;
 	vfe->video_ops = vfe_video_ops_gen1;
 
@@ -1181,15 +1182,11 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
 const struct vfe_hw_ops vfe_ops_4_8 = {
 	.global_reset = vfe_global_reset,
 	.hw_version_read = vfe_hw_version_read,
-	.isr_read = vfe_isr_read,
 	.isr = vfe_isr,
 	.pm_domain_off = vfe_pm_domain_off,
 	.pm_domain_on = vfe_pm_domain_on,
-	.reg_update_clear = vfe_reg_update_clear,
-	.reg_update = vfe_reg_update,
 	.subdev_init = vfe_subdev_init,
 	.vfe_disable = vfe_gen1_disable,
 	.vfe_enable = vfe_gen1_enable,
 	.vfe_halt = vfe_gen1_halt,
-	.violation_read = vfe_violation_read,
 };
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-gen1.c b/drivers/media/platform/qcom/camss/camss-vfe-gen1.c
index 4fd265d018834..2c0cd14bbdf8e 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-gen1.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-gen1.c
@@ -37,7 +37,6 @@ static int vfe_disable_output(struct vfe_line *line)
 {
 	struct vfe_device *vfe = to_vfe(line);
 	struct vfe_output *output = &line->output;
-	const struct vfe_hw_ops *ops = vfe->ops;
 	unsigned long flags;
 	unsigned long time;
 	unsigned int i;
@@ -55,7 +54,7 @@ static int vfe_disable_output(struct vfe_line *line)
 	for (i = 0; i < output->wm_num; i++)
 		vfe->ops_gen1->wm_enable(vfe, output->wm_idx[i], 0);
 
-	ops->reg_update(vfe, line->id);
+	vfe->ops_gen1->reg_update(vfe, line->id);
 	output->wait_reg_update = 1;
 	spin_unlock_irqrestore(&vfe->output_lock, flags);
 
@@ -162,21 +161,21 @@ static void vfe_output_frame_drop(struct vfe_device *vfe,
 		vfe->ops_gen1->wm_set_framedrop_pattern(vfe, output->wm_idx[i], drop_pattern);
 	}
 
-	vfe->ops->reg_update(vfe, container_of(output, struct vfe_line, output)->id);
+	vfe->ops_gen1->reg_update(vfe, container_of(output, struct vfe_line, output)->id);
 }
 
 static int vfe_enable_output(struct vfe_line *line)
 {
 	struct vfe_device *vfe = to_vfe(line);
 	struct vfe_output *output = &line->output;
-	const struct vfe_hw_ops *ops = vfe->ops;
+	const struct vfe_hw_ops_gen1 *ops = vfe->ops_gen1;
 	struct media_entity *sensor;
 	unsigned long flags;
 	unsigned int frame_skip = 0;
 	unsigned int i;
 	u16 ub_size;
 
-	ub_size = vfe->ops_gen1->get_ub_size(vfe->id);
+	ub_size = ops->get_ub_size(vfe->id);
 	if (!ub_size)
 		return -EINVAL;
 
@@ -236,38 +235,38 @@ static int vfe_enable_output(struct vfe_line *line)
 	vfe_output_init_addrs(vfe, output, 0, line);
 
 	if (line->id != VFE_LINE_PIX) {
-		vfe->ops_gen1->set_cgc_override(vfe, output->wm_idx[0], 1);
-		vfe->ops_gen1->enable_irq_wm_line(vfe, output->wm_idx[0], line->id, 1);
-		vfe->ops_gen1->bus_connect_wm_to_rdi(vfe, output->wm_idx[0], line->id);
-		vfe->ops_gen1->wm_set_subsample(vfe, output->wm_idx[0]);
-		vfe->ops_gen1->set_rdi_cid(vfe, line->id, 0);
-		vfe->ops_gen1->wm_set_ub_cfg(vfe, output->wm_idx[0],
+		ops->set_cgc_override(vfe, output->wm_idx[0], 1);
+		ops->enable_irq_wm_line(vfe, output->wm_idx[0], line->id, 1);
+		ops->bus_connect_wm_to_rdi(vfe, output->wm_idx[0], line->id);
+		ops->wm_set_subsample(vfe, output->wm_idx[0]);
+		ops->set_rdi_cid(vfe, line->id, 0);
+		ops->wm_set_ub_cfg(vfe, output->wm_idx[0],
 					    (ub_size + 1) * output->wm_idx[0], ub_size);
-		vfe->ops_gen1->wm_frame_based(vfe, output->wm_idx[0], 1);
-		vfe->ops_gen1->wm_enable(vfe, output->wm_idx[0], 1);
-		vfe->ops_gen1->bus_reload_wm(vfe, output->wm_idx[0]);
+		ops->wm_frame_based(vfe, output->wm_idx[0], 1);
+		ops->wm_enable(vfe, output->wm_idx[0], 1);
+		ops->bus_reload_wm(vfe, output->wm_idx[0]);
 	} else {
 		ub_size /= output->wm_num;
 		for (i = 0; i < output->wm_num; i++) {
-			vfe->ops_gen1->set_cgc_override(vfe, output->wm_idx[i], 1);
-			vfe->ops_gen1->wm_set_subsample(vfe, output->wm_idx[i]);
-			vfe->ops_gen1->wm_set_ub_cfg(vfe, output->wm_idx[i],
+			ops->set_cgc_override(vfe, output->wm_idx[i], 1);
+			ops->wm_set_subsample(vfe, output->wm_idx[i]);
+			ops->wm_set_ub_cfg(vfe, output->wm_idx[i],
 						     (ub_size + 1) * output->wm_idx[i], ub_size);
-			vfe->ops_gen1->wm_line_based(vfe, output->wm_idx[i],
+			ops->wm_line_based(vfe, output->wm_idx[i],
 						     &line->video_out.active_fmt.fmt.pix_mp, i, 1);
-			vfe->ops_gen1->wm_enable(vfe, output->wm_idx[i], 1);
-			vfe->ops_gen1->bus_reload_wm(vfe, output->wm_idx[i]);
+			ops->wm_enable(vfe, output->wm_idx[i], 1);
+			ops->bus_reload_wm(vfe, output->wm_idx[i]);
 		}
-		vfe->ops_gen1->enable_irq_pix_line(vfe, 0, line->id, 1);
-		vfe->ops_gen1->set_module_cfg(vfe, 1);
-		vfe->ops_gen1->set_camif_cfg(vfe, line);
-		vfe->ops_gen1->set_realign_cfg(vfe, line, 1);
-		vfe->ops_gen1->set_xbar_cfg(vfe, output, 1);
-		vfe->ops_gen1->set_demux_cfg(vfe, line);
-		vfe->ops_gen1->set_scale_cfg(vfe, line);
-		vfe->ops_gen1->set_crop_cfg(vfe, line);
-		vfe->ops_gen1->set_clamp_cfg(vfe);
-		vfe->ops_gen1->set_camif_cmd(vfe, 1);
+		ops->enable_irq_pix_line(vfe, 0, line->id, 1);
+		ops->set_module_cfg(vfe, 1);
+		ops->set_camif_cfg(vfe, line);
+		ops->set_realign_cfg(vfe, line, 1);
+		ops->set_xbar_cfg(vfe, output, 1);
+		ops->set_demux_cfg(vfe, line);
+		ops->set_scale_cfg(vfe, line);
+		ops->set_crop_cfg(vfe, line);
+		ops->set_clamp_cfg(vfe);
+		ops->set_camif_cmd(vfe, 1);
 	}
 
 	ops->reg_update(vfe, line->id);
@@ -508,7 +507,7 @@ static void vfe_buf_update_wm_on_new(struct vfe_device *vfe,
  * vfe_isr_halt_ack - Process halt ack
  * @vfe: VFE Device
  */
-static void vfe_isr_halt_ack(struct vfe_device *vfe)
+void vfe_gen1_isr_halt_ack(struct vfe_device *vfe)
 {
 	complete(&vfe->halt_complete);
 	vfe->ops_gen1->halt_clear(vfe);
@@ -519,7 +518,7 @@ static void vfe_isr_halt_ack(struct vfe_device *vfe)
  * @vfe: VFE Device
  * @line_id: VFE line
  */
-static void vfe_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id)
+void vfe_gen1_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id)
 {
 	struct vfe_output *output;
 	unsigned long flags;
@@ -538,14 +537,14 @@ static void vfe_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id)
  * @vfe: VFE Device
  * @line_id: VFE line
  */
-static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
+void vfe_gen1_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
 {
 	struct vfe_output *output;
 	struct vfe_line *line = &vfe->line[line_id];
 	unsigned long flags;
 
 	spin_lock_irqsave(&vfe->output_lock, flags);
-	vfe->ops->reg_update_clear(vfe, line_id);
+	vfe->ops_gen1->reg_update_clear(vfe, line_id);
 
 	output = &line->output;
 
@@ -605,7 +604,7 @@ static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
  * @vfe: VFE Device
  * @wm: Write master id
  */
-static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm)
+void vfe_gen1_isr_wm_done(struct vfe_device *vfe, u8 wm)
 {
 	struct camss_buffer *ready_buf;
 	struct vfe_output *output;
@@ -675,6 +674,22 @@ static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm)
 	spin_unlock_irqrestore(&vfe->output_lock, flags);
 }
 
+/**
+ * vfe_isr_comp_done() - Process composite image done interrupt
+ * @vfe: VFE Device
+ * @comp: Composite image id
+ */
+void vfe_gen1_isr_comp_done(struct vfe_device *vfe, u8 comp)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
+		if (vfe->wm_output_map[i] == VFE_LINE_PIX) {
+			vfe_gen1_isr_wm_done(vfe, i);
+			break;
+		}
+}
+
 /*
  * vfe_queue_buffer - Add empty buffer
  * @vid: Video device structure
@@ -727,15 +742,6 @@ int vfe_word_per_line(u32 format, u32 width)
 	return val;
 }
 
-const struct vfe_isr_ops vfe_isr_ops_gen1 = {
-	.reset_ack = vfe_isr_reset_ack,
-	.halt_ack = vfe_isr_halt_ack,
-	.reg_update = vfe_isr_reg_update,
-	.sof = vfe_isr_sof,
-	.comp_done = vfe_isr_comp_done,
-	.wm_done = vfe_isr_wm_done,
-};
-
 const struct camss_video_ops vfe_video_ops_gen1 = {
 	.queue_buffer = vfe_queue_buffer,
 	.flush_buffers = vfe_flush_buffers,
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-gen1.h b/drivers/media/platform/qcom/camss/camss-vfe-gen1.h
index 6d5f9656562c8..2619df66aa713 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-gen1.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe-gen1.h
@@ -55,6 +55,9 @@ struct vfe_hw_ops_gen1 {
 	void (*wm_set_pong_addr)(struct vfe_device *vfe, u8 wm, u32 addr);
 	int (*wm_get_ping_pong_status)(struct vfe_device *vfe, u8 wm);
 	void (*wm_enable)(struct vfe_device *vfe, u8 wm, u8 enable);
+	void (*reg_update)(struct vfe_device *vfe, enum vfe_line_id line_id);
+	void (*reg_update_clear)(struct vfe_device *vfe,
+				 enum vfe_line_id line_id);
 };
 
 /*
@@ -95,13 +98,47 @@ int vfe_gen1_disable(struct vfe_line *line);
 int vfe_gen1_enable(struct vfe_line *line);
 
 /*
- * vfe_gen1_enable - Halt VFE module
+ * vfe_gen1_halt - Halt VFE module
  * @vfe: VFE device
  *
  * Return 0 on success
  */
 int vfe_gen1_halt(struct vfe_device *vfe);
 
+/*
+ * vfe_gen1_isr_halt_ack - Process halt ack
+ * @vfe: VFE Device
+ */
+void vfe_gen1_isr_halt_ack(struct vfe_device *vfe);
+
+/*
+ * vfe_gen1_isr_sof - Process start of frame interrupt
+ * @vfe: VFE Device
+ * @line_id: VFE line
+ */
+void vfe_gen1_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id);
+
+/*
+ * vfe_gen1_reg_update - Process reg update interrupt
+ * @vfe: VFE Device
+ * @line_id: VFE line
+ */
+void vfe_gen1_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id);
+
+/*
+ * vfe_gen1_isr_wm_done - Process write master done interrupt
+ * @vfe: VFE Device
+ * @wm: Write master id
+ */
+void vfe_gen1_isr_wm_done(struct vfe_device *vfe, u8 wm);
+
+/**
+ * vfe_gen1_isr_comp_done() - Process composite image done interrupt
+ * @vfe: VFE Device
+ * @comp: Composite image id
+ */
+void vfe_gen1_isr_comp_done(struct vfe_device *vfe, u8 comp);
+
 /*
  * vfe_word_per_line - Calculate number of words per frame width
  * @format: V4L2 format
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index dec89079c6ae4..3e467034710b9 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -405,22 +405,6 @@ int vfe_put_output(struct vfe_line *line)
 	return 0;
 }
 
-/**
- * vfe_isr_comp_done() - Process composite image done interrupt
- * @vfe: VFE Device
- * @comp: Composite image id
- */
-void vfe_isr_comp_done(struct vfe_device *vfe, u8 comp)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
-		if (vfe->wm_output_map[i] == VFE_LINE_PIX) {
-			vfe->isr_ops.wm_done(vfe, i);
-			break;
-		}
-}
-
 void vfe_isr_reset_ack(struct vfe_device *vfe)
 {
 	complete(&vfe->reset_complete);
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index 844b9275031d9..97a1361996308 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -101,30 +101,15 @@ struct vfe_line {
 struct vfe_device;
 
 struct vfe_hw_ops {
-	void (*enable_irq_common)(struct vfe_device *vfe);
 	void (*global_reset)(struct vfe_device *vfe);
 	void (*hw_version_read)(struct vfe_device *vfe, struct device *dev);
 	irqreturn_t (*isr)(int irq, void *dev);
-	void (*isr_read)(struct vfe_device *vfe, u32 *value0, u32 *value1);
 	void (*pm_domain_off)(struct vfe_device *vfe);
 	int (*pm_domain_on)(struct vfe_device *vfe);
-	void (*reg_update)(struct vfe_device *vfe, enum vfe_line_id line_id);
-	void (*reg_update_clear)(struct vfe_device *vfe,
-				 enum vfe_line_id line_id);
 	void (*subdev_init)(struct device *dev, struct vfe_device *vfe);
 	int (*vfe_disable)(struct vfe_line *line);
 	int (*vfe_enable)(struct vfe_line *line);
 	int (*vfe_halt)(struct vfe_device *vfe);
-	void (*violation_read)(struct vfe_device *vfe);
-};
-
-struct vfe_isr_ops {
-	void (*reset_ack)(struct vfe_device *vfe);
-	void (*halt_ack)(struct vfe_device *vfe);
-	void (*reg_update)(struct vfe_device *vfe, enum vfe_line_id line_id);
-	void (*sof)(struct vfe_device *vfe, enum vfe_line_id line_id);
-	void (*comp_done)(struct vfe_device *vfe, u8 comp);
-	void (*wm_done)(struct vfe_device *vfe, u8 wm);
 };
 
 struct vfe_device {
@@ -149,7 +134,6 @@ struct vfe_device {
 	u8 was_streaming;
 	const struct vfe_hw_ops *ops;
 	const struct vfe_hw_ops_gen1 *ops_gen1;
-	struct vfe_isr_ops isr_ops;
 	struct camss_video_ops video_ops;
 };
 
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 13/17] media: camss: vfe-170: fix "VFE halt timeout" error
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (11 preceding siblings ...)
  2021-06-08 22:35 ` [PATCH 12/17] media: camss: remove some vfe ops and clean up dead vfe-170 code Jonathan Marek
@ 2021-06-08 22:35 ` Jonathan Marek
  2021-06-08 22:35 ` [PATCH 14/17] media: camss: Add initial support for VFE hardware version Titan 480 Jonathan Marek
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:35 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab, Hans Verkuil,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

This function waits for halt_complete but doesn't do anything to cause
it to complete, and always hits the "VFE halt timeout" error. Just delete
this code for now.

Fixes: 7319cdf189bb ("media: camss: Add support for VFE hardware version Titan 170")
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 drivers/media/platform/qcom/camss/camss-vfe-170.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c
index 1de793b218194..ba142c8cec6ee 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-170.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c
@@ -355,17 +355,7 @@ static irqreturn_t vfe_isr(int irq, void *dev)
  */
 static int vfe_halt(struct vfe_device *vfe)
 {
-	unsigned long time;
-
-	reinit_completion(&vfe->halt_complete);
-
-	time = wait_for_completion_timeout(&vfe->halt_complete,
-					   msecs_to_jiffies(VFE_HALT_TIMEOUT_MS));
-	if (!time) {
-		dev_err(vfe->camss->dev, "VFE halt timeout\n");
-		return -EIO;
-	}
-
+	/* rely on vfe_disable_output() to stop the VFE */
 	return 0;
 }
 
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 14/17] media: camss: Add initial support for VFE hardware version Titan 480
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (12 preceding siblings ...)
  2021-06-08 22:35 ` [PATCH 13/17] media: camss: vfe-170: fix "VFE halt timeout" error Jonathan Marek
@ 2021-06-08 22:35 ` Jonathan Marek
  2021-06-10 12:40   ` Robert Foss
  2021-06-08 22:35 ` [PATCH 15/17] media: camss: add support for V4L2_PIX_FMT_GREY for sdm845 HW Jonathan Marek
                   ` (3 subsequent siblings)
  17 siblings, 1 reply; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:35 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab, open list,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER

Add support for VFE found on SM8250 (Titan 480). This implementation is
based on the titan 170 implementation. It supports the normal and lite VFE,
and only supports the RDI0 capture path.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
---
 drivers/media/platform/qcom/camss/Makefile    |   1 +
 .../media/platform/qcom/camss/camss-vfe-480.c | 545 ++++++++++++++++++
 drivers/media/platform/qcom/camss/camss-vfe.h |   1 +
 3 files changed, 547 insertions(+)
 create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-480.c

diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
index 0752c46ea37b5..81dd56aff0f27 100644
--- a/drivers/media/platform/qcom/camss/Makefile
+++ b/drivers/media/platform/qcom/camss/Makefile
@@ -15,6 +15,7 @@ qcom-camss-objs += \
 		camss-vfe-4-7.o \
 		camss-vfe-4-8.o \
 		camss-vfe-170.o \
+		camss-vfe-480.o \
 		camss-vfe-gen1.o \
 		camss-vfe.o \
 		camss-video.o \
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-480.c b/drivers/media/platform/qcom/camss/camss-vfe-480.c
new file mode 100644
index 0000000000000..6e6a4caee0a96
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-vfe-480.c
@@ -0,0 +1,545 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-vfe-480.c
+ *
+ * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v480 (SM8250)
+ *
+ * Copyright (C) 2020-2021 Linaro Ltd.
+ * Copyright (C) 2021 Jonathan Marek
+ */
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+#include "camss.h"
+#include "camss-vfe.h"
+
+/* VFE 2/3 are lite and have a different register layout */
+#define IS_LITE		(vfe->id >= 2 ? 1 : 0)
+
+#define VFE_HW_VERSION			(0x00)
+
+#define VFE_GLOBAL_RESET_CMD		(IS_LITE ? 0x0c : 0x1c)
+#define	    GLOBAL_RESET_HW_AND_REG	(IS_LITE ? BIT(1) : BIT(0))
+
+#define VFE_REG_UPDATE_CMD		(IS_LITE ? 0x20 : 0x34)
+#define	    REG_UPDATE_RDI(n)		(IS_LITE ? BIT(n) : BIT(1 + (n)))
+#define VFE_IRQ_CMD			(IS_LITE ? 0x24 : 0x38)
+#define     IRQ_CMD_GLOBAL_CLEAR	BIT(0)
+
+#define VFE_IRQ_MASK(n)			((IS_LITE ? 0x28 : 0x3c) + (n) * 4)
+#define	    IRQ_MASK_0_RESET_ACK	(IS_LITE ? BIT(17) : BIT(0))
+#define	    IRQ_MASK_0_BUS_TOP_IRQ	(IS_LITE ? BIT(4) : BIT(7))
+#define VFE_IRQ_CLEAR(n)		((IS_LITE ? 0x34 : 0x48) + (n) * 4)
+#define VFE_IRQ_STATUS(n)		((IS_LITE ? 0x40 : 0x54) + (n) * 4)
+
+#define BUS_REG_BASE			(IS_LITE ? 0x1a00 : 0xaa00)
+
+#define VFE_BUS_WM_CGC_OVERRIDE		(BUS_REG_BASE + 0x08)
+#define		WM_CGC_OVERRIDE_ALL	(0x3FFFFFF)
+
+#define VFE_BUS_WM_TEST_BUS_CTRL	(BUS_REG_BASE + 0xdc)
+
+#define VFE_BUS_IRQ_MASK(n)		(BUS_REG_BASE + 0x18 + (n) * 4)
+#define     BUS_IRQ_MASK_0_RDI_RUP(n)	(IS_LITE ? BIT(n) : BIT(3 + (n)))
+#define     BUS_IRQ_MASK_0_COMP_DONE(n)	(IS_LITE ? BIT(4 + (n)) : BIT(6 + (n)))
+#define VFE_BUS_IRQ_CLEAR(n)		(BUS_REG_BASE + 0x20 + (n) * 4)
+#define VFE_BUS_IRQ_STATUS(n)		(BUS_REG_BASE + 0x28 + (n) * 4)
+#define VFE_BUS_IRQ_CLEAR_GLOBAL	(BUS_REG_BASE + 0x30)
+
+#define VFE_BUS_WM_CFG(n)		(BUS_REG_BASE + 0x200 + (n) * 0x100)
+#define		WM_CFG_EN			(0)
+#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 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_SYSTEM_CACHE_CFG(n)	(BUS_REG_BASE + 0x260 + (n) * 0x100)
+#define VFE_BUS_WM_BURST_LIMIT(n)	(BUS_REG_BASE + 0x264 + (n) * 0x100)
+
+/* for titan 480, each bus client is hardcoded to a specific path
+ * and each bus client is part of a hardcoded "comp group"
+ */
+#define RDI_WM(n)			((IS_LITE ? 0 : 23) + (n))
+#define RDI_COMP_GROUP(n)		((IS_LITE ? 0 : 11) + (n))
+
+static void vfe_hw_version_read(struct vfe_device *vfe, struct device *dev)
+{
+	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_dbg(dev, "VFE HW Version = %u.%u.%u\n", gen, rev, step);
+}
+
+static void vfe_global_reset(struct vfe_device *vfe)
+{
+	writel_relaxed(IRQ_MASK_0_RESET_ACK, vfe->base + VFE_IRQ_MASK(0));
+	writel_relaxed(GLOBAL_RESET_HW_AND_REG, vfe->base + VFE_GLOBAL_RESET_CMD);
+}
+
+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(WM_CGC_OVERRIDE_ALL, vfe->base + VFE_BUS_WM_CGC_OVERRIDE);
+
+	writel_relaxed(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL);
+
+	writel_relaxed(pix->plane_fmt[0].bytesperline * pix->height,
+		       vfe->base + VFE_BUS_WM_FRAME_INCR(wm));
+	writel_relaxed(0xf, vfe->base + VFE_BUS_WM_BURST_LIMIT(wm));
+	writel_relaxed(WM_IMAGE_CFG_0_DEFAULT_WIDTH,
+		       vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm));
+	writel_relaxed(pix->plane_fmt[0].bytesperline,
+		       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 << 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, u32 addr,
+			  struct vfe_line *line)
+{
+	wm = RDI_WM(wm); /* map to actual WM used (from wm=RDI index) */
+	writel_relaxed(addr, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
+}
+
+static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+	vfe->reg_update |= REG_UPDATE_RDI(line_id);
+	writel_relaxed(vfe->reg_update, vfe->base + VFE_REG_UPDATE_CMD);
+}
+
+static inline void vfe_reg_update_clear(struct vfe_device *vfe,
+					enum vfe_line_id line_id)
+{
+	vfe->reg_update &= ~REG_UPDATE_RDI(line_id);
+}
+
+static void vfe_enable_irq_common(struct vfe_device *vfe)
+{
+	/* enable only the IRQs used: rup and comp_done irqs for RDI0 */
+	writel_relaxed(IRQ_MASK_0_RESET_ACK | IRQ_MASK_0_BUS_TOP_IRQ,
+		       vfe->base + VFE_IRQ_MASK(0));
+	writel_relaxed(BUS_IRQ_MASK_0_RDI_RUP(0) | BUS_IRQ_MASK_0_COMP_DONE(RDI_COMP_GROUP(0)),
+		       vfe->base + VFE_BUS_IRQ_MASK(0));
+}
+
+static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id);
+static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm);
+
+/*
+ * 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 & IRQ_MASK_0_RESET_ACK)
+		vfe_isr_reset_ack(vfe);
+
+	if (status & IRQ_MASK_0_BUS_TOP_IRQ) {
+		u32 status = readl_relaxed(vfe->base + VFE_BUS_IRQ_STATUS(0));
+		writel_relaxed(status, vfe->base + VFE_BUS_IRQ_CLEAR(0));
+		writel_relaxed(1, vfe->base + VFE_BUS_IRQ_CLEAR_GLOBAL);
+
+		if (status & BUS_IRQ_MASK_0_RDI_RUP(0))
+			vfe_isr_reg_update(vfe, 0);
+
+		if (status & BUS_IRQ_MASK_0_COMP_DONE(RDI_COMP_GROUP(0)))
+			vfe_isr_wm_done(vfe, 0);
+	}
+
+	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;
+	int wm_idx;
+
+	spin_lock_irqsave(&vfe->output_lock, flags);
+
+	output = &line->output;
+	if (output->state != VFE_OUTPUT_OFF) {
+		dev_err(vfe->camss->dev, "Output is running\n");
+		goto error;
+	}
+
+	output->wm_num = 1;
+
+	wm_idx = vfe_reserve_wm(vfe, line->id);
+	if (wm_idx < 0) {
+		dev_err(vfe->camss->dev, "Can not reserve wm\n");
+		goto error_get_wm;
+	}
+	output->wm_idx[0] = wm_idx;
+
+	output->drop_update_idx = 0;
+
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+	return 0;
+
+error_get_wm:
+	vfe_release_wm(vfe, output->wm_idx[0]);
+	output->state = VFE_OUTPUT_OFF;
+error:
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+	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_OFF) {
+		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;
+	output->wait_reg_update = 0;
+	reinit_completion(&output->reg_update);
+
+	vfe_wm_start(vfe, output->wm_idx[0], line);
+
+	for (i = 0; i < 2; 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;
+}
+
+static int vfe_disable_output(struct vfe_line *line)
+{
+	struct vfe_device *vfe = to_vfe(line);
+	struct vfe_output *output = &line->output;
+	unsigned long flags;
+	unsigned int i;
+	bool done;
+	int timeout = 0;
+
+	do {
+		spin_lock_irqsave(&vfe->output_lock, flags);
+		done = !output->gen2.active_num;
+		spin_unlock_irqrestore(&vfe->output_lock, flags);
+		usleep_range(10000, 20000);
+
+		if (timeout++ == 100) {
+			dev_err(vfe->camss->dev, "VFE idle timeout - resetting\n");
+			vfe_reset(vfe);
+			output->gen2.active_num = 0;
+			return 0;
+		}
+	} while (!done);
+
+	spin_lock_irqsave(&vfe->output_lock, flags);
+	for (i = 0; i < output->wm_num; i++)
+		vfe_wm_stop(vfe, output->wm_idx[i]);
+	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);
+
+	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_disable - Disable streaming on VFE line
+ * @line: VFE line
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int vfe_disable(struct vfe_line *line)
+{
+	struct vfe_device *vfe = to_vfe(line);
+
+	vfe_disable_output(line);
+
+	vfe_put_output(line);
+
+	mutex_lock(&vfe->stream_lock);
+
+	vfe->stream_count--;
+
+	mutex_unlock(&vfe->stream_lock);
+
+	return 0;
+}
+
+/*
+ * vfe_isr_reg_update - Process reg update interrupt
+ * @vfe: VFE Device
+ * @line_id: VFE line
+ */
+static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+	struct vfe_output *output;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vfe->output_lock, flags);
+	vfe_reg_update_clear(vfe, line_id);
+
+	output = &vfe->line[line_id].output;
+
+	if (output->wait_reg_update) {
+		output->wait_reg_update = 0;
+		complete(&output->reg_update);
+	}
+
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+}
+
+/*
+ * vfe_isr_wm_done - Process write master done interrupt
+ * @vfe: VFE Device
+ * @wm: Write master id
+ */
+static void vfe_isr_wm_done(struct vfe_device *vfe, u8 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);
+	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_pm_domain_off - Disable power domains specific to this VFE.
+ * @vfe: VFE Device
+ */
+static void vfe_pm_domain_off(struct vfe_device *vfe)
+{
+	/* nop */
+}
+
+/*
+ * vfe_pm_domain_on - Enable power domains specific to this VFE.
+ * @vfe: VFE Device
+ */
+static int vfe_pm_domain_on(struct vfe_device *vfe)
+{
+	return 0;
+}
+
+/*
+ * 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 < 2) {
+		output->buf[output->gen2.active_num++] = buf;
+		vfe_wm_update(vfe, output->wm_idx[0], buf->addr[0], line);
+	} 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_480 = {
+	.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_480;
+	vfe->line_num = 1;
+}
+
+const struct vfe_hw_ops vfe_ops_480 = {
+	.global_reset = vfe_global_reset,
+	.hw_version_read = vfe_hw_version_read,
+	.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,
+};
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index 97a1361996308..e80b482885d4a 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -185,5 +185,6 @@ extern const struct vfe_hw_ops vfe_ops_4_1;
 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;
 
 #endif /* QC_MSM_CAMSS_VFE_H */
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 15/17] media: camss: add support for V4L2_PIX_FMT_GREY for sdm845 HW
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (13 preceding siblings ...)
  2021-06-08 22:35 ` [PATCH 14/17] media: camss: Add initial support for VFE hardware version Titan 480 Jonathan Marek
@ 2021-06-08 22:35 ` Jonathan Marek
  2021-06-08 22:35 ` [PATCH 16/17] media: camss: add support for SM8250 camss Jonathan Marek
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:35 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

Add this common format to the various format lists relevant to sdm845.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 drivers/media/platform/qcom/camss/camss-csid-170.c | 7 +++++++
 drivers/media/platform/qcom/camss/camss-csiphy.c   | 1 +
 drivers/media/platform/qcom/camss/camss-vfe.c      | 1 +
 drivers/media/platform/qcom/camss/camss-video.c    | 2 ++
 4 files changed, 11 insertions(+)

diff --git a/drivers/media/platform/qcom/camss/camss-csid-170.c b/drivers/media/platform/qcom/camss/camss-csid-170.c
index 22a7d7ad63403..9e54d251793fc 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-170.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-170.c
@@ -262,6 +262,13 @@ static const struct csid_format csid_formats[] = {
 		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,
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
index b3c3bf19e5223..f82f1e2aa6883 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -94,6 +94,7 @@ static const struct csiphy_format csiphy_formats_sdm845[] = {
 	{ MEDIA_BUS_FMT_SGBRG14_1X14, 14 },
 	{ MEDIA_BUS_FMT_SGRBG14_1X14, 14 },
 	{ MEDIA_BUS_FMT_SRGGB14_1X14, 14 },
+	{ MEDIA_BUS_FMT_Y8_1X8, 8 },
 	{ MEDIA_BUS_FMT_Y10_1X10, 10 },
 };
 
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 3e467034710b9..b08bded2344e6 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -118,6 +118,7 @@ static const struct vfe_format formats_rdi_845[] = {
 	{ MEDIA_BUS_FMT_SGBRG14_1X14, 14 },
 	{ MEDIA_BUS_FMT_SGRBG14_1X14, 14 },
 	{ MEDIA_BUS_FMT_SRGGB14_1X14, 14 },
+	{ MEDIA_BUS_FMT_Y8_1X8, 8 },
 	{ MEDIA_BUS_FMT_Y10_1X10, 10 },
 	{ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16 },
 };
diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
index f282275af626f..54e77d30d452c 100644
--- a/drivers/media/platform/qcom/camss/camss-video.c
+++ b/drivers/media/platform/qcom/camss/camss-video.c
@@ -176,6 +176,8 @@ static const struct camss_format_info formats_rdi_845[] = {
 	  { { 1, 1 } }, { { 1, 1 } }, { 14 } },
 	{ MEDIA_BUS_FMT_SRGGB14_1X14, V4L2_PIX_FMT_SRGGB14P, 1,
 	  { { 1, 1 } }, { { 1, 1 } }, { 14 } },
+	{ MEDIA_BUS_FMT_Y8_1X8, V4L2_PIX_FMT_GREY, 1,
+	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
 	{ MEDIA_BUS_FMT_Y10_1X10, V4L2_PIX_FMT_Y10P, 1,
 	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
 	{ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, V4L2_PIX_FMT_Y10, 1,
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 16/17] media: camss: add support for SM8250 camss
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (14 preceding siblings ...)
  2021-06-08 22:35 ` [PATCH 15/17] media: camss: add support for V4L2_PIX_FMT_GREY for sdm845 HW Jonathan Marek
@ 2021-06-08 22:35 ` Jonathan Marek
  2021-06-10  8:03   ` Robert Foss
  2021-06-08 22:35 ` [PATCH 17/17] media: dt-bindings: media: camss: Add qcom,sm8250-camss binding Jonathan Marek
  2021-06-16 18:16 ` [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Andrey Konovalov
  17 siblings, 1 reply; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:35 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Todor Tomov, Andy Gross,
	Bjorn Andersson, Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

The Titan 480 camss found on SM8250 has 6 CSIPHY and 4 VFE/CSID.

CSID is compatible with the Titan 170 CSID, but the Titan 480 CSID are
inside the VFE region (between the "top" and "bus" registers), so a
workaround is added to avoid ioremap failure.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Robert Foss <robert.foss@linaro.org>
---
 drivers/media/platform/qcom/camss/Makefile    |   2 +-
 .../{camss-csid-170.c => camss-csid-gen2.c}   |   2 +-
 .../media/platform/qcom/camss/camss-csid.c    |  28 ++-
 .../media/platform/qcom/camss/camss-csid.h    |   2 +-
 .../media/platform/qcom/camss/camss-csiphy.c  |   8 +-
 drivers/media/platform/qcom/camss/camss-vfe.c |   9 +-
 .../media/platform/qcom/camss/camss-video.c   |   3 +-
 drivers/media/platform/qcom/camss/camss.c     | 199 ++++++++++++++++--
 8 files changed, 227 insertions(+), 26 deletions(-)
 rename drivers/media/platform/qcom/camss/{camss-csid-170.c => camss-csid-gen2.c} (99%)

diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
index 81dd56aff0f27..4e22223589739 100644
--- a/drivers/media/platform/qcom/camss/Makefile
+++ b/drivers/media/platform/qcom/camss/Makefile
@@ -6,7 +6,7 @@ qcom-camss-objs += \
 		camss-csid.o \
 		camss-csid-4-1.o \
 		camss-csid-4-7.o \
-		camss-csid-170.o \
+		camss-csid-gen2.o \
 		camss-csiphy-2ph-1-0.o \
 		camss-csiphy-3ph-1-0.o \
 		camss-csiphy.o \
diff --git a/drivers/media/platform/qcom/camss/camss-csid-170.c b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
similarity index 99%
rename from drivers/media/platform/qcom/camss/camss-csid-170.c
rename to drivers/media/platform/qcom/camss/camss-csid-gen2.c
index 9e54d251793fc..abbfbf4488934 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-170.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
@@ -594,7 +594,7 @@ static void csid_subdev_init(struct csid_device *csid)
 	csid->testgen.nmodes = CSID_PAYLOAD_MODE_NUM_SUPPORTED_GEN2;
 }
 
-const struct csid_hw_ops csid_ops_170 = {
+const struct csid_hw_ops csid_ops_gen2 = {
 	.configure_stream = csid_configure_stream,
 	.configure_testgen_pattern = csid_configure_testgen_pattern,
 	.hw_version = csid_hw_version,
diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index 528674dea06ca..b4c068a152f73 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -25,6 +25,10 @@
 #include "camss-csid-gen1.h"
 #include "camss.h"
 
+/* offset of CSID registers in VFE region for VFE 480 */
+#define VFE_480_CSID_OFFSET 0x1200
+#define VFE_480_LITE_CSID_OFFSET 0x200
+
 #define MSM_CSID_NAME "msm_csid"
 
 const char * const csid_testgen_modes[] = {
@@ -560,8 +564,9 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
 	} else if (camss->version == CAMSS_8x96 ||
 		   camss->version == CAMSS_660) {
 		csid->ops = &csid_ops_4_7;
-	} else if (camss->version == CAMSS_845) {
-		csid->ops = &csid_ops_170;
+	} else if (camss->version == CAMSS_845 ||
+		   camss->version == CAMSS_8250) {
+		csid->ops = &csid_ops_gen2;
 	} else {
 		return -EINVAL;
 	}
@@ -569,10 +574,21 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
 
 	/* Memory */
 
-	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]);
-	csid->base = devm_ioremap_resource(dev, r);
-	if (IS_ERR(csid->base))
-		return PTR_ERR(csid->base);
+	if (camss->version == CAMSS_8250) {
+		/* for titan 480, CSID registers are inside the VFE region,
+		 * between the VFE "top" and "bus" registers. this requires
+		 * VFE to be initialized before CSID
+		 */
+		if (id >= 2) /* VFE/CSID lite */
+			csid->base = camss->vfe[id].base + VFE_480_LITE_CSID_OFFSET;
+		else
+			csid->base = camss->vfe[id].base + VFE_480_CSID_OFFSET;
+	} else {
+		r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]);
+		csid->base = devm_ioremap_resource(dev, r);
+		if (IS_ERR(csid->base))
+			return PTR_ERR(csid->base);
+	}
 
 	/* Interrupt */
 
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index 814ebc7c29d65..17a50fa426be1 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -205,7 +205,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_170;
+extern const struct csid_hw_ops csid_ops_gen2;
 
 
 #endif /* QC_MSM_CAMSS_CSID_H */
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
index f82f1e2aa6883..1d10c816acf5c 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -582,7 +582,8 @@ int msm_csiphy_subdev_init(struct camss *camss,
 		csiphy->ops = &csiphy_ops_3ph_1_0;
 		csiphy->formats = csiphy_formats_8x96;
 		csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x96);
-	} else if (camss->version == CAMSS_845) {
+	} else if (camss->version == CAMSS_845 ||
+		   camss->version == CAMSS_8250) {
 		csiphy->ops = &csiphy_ops_3ph_1_0;
 		csiphy->formats = csiphy_formats_sdm845;
 		csiphy->nformats = ARRAY_SIZE(csiphy_formats_sdm845);
@@ -679,7 +680,10 @@ int msm_csiphy_subdev_init(struct camss *camss,
 
 		if (!strcmp(clock->name, "csiphy0_timer") ||
 		    !strcmp(clock->name, "csiphy1_timer") ||
-		    !strcmp(clock->name, "csiphy2_timer"))
+		    !strcmp(clock->name, "csiphy2_timer") ||
+		    !strcmp(clock->name, "csiphy3_timer") ||
+		    !strcmp(clock->name, "csiphy4_timer") ||
+		    !strcmp(clock->name, "csiphy5_timer"))
 			csiphy->rate_set[i] = true;
 
 		if (camss->version == CAMSS_660 &&
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index b08bded2344e6..48d05ece0dcc1 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -220,7 +220,8 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
 		}
 	else if (vfe->camss->version == CAMSS_8x96 ||
 		 vfe->camss->version == CAMSS_660 ||
-		 vfe->camss->version == CAMSS_845)
+		 vfe->camss->version == CAMSS_845 ||
+		 vfe->camss->version == CAMSS_8250)
 		switch (sink_code) {
 		case MEDIA_BUS_FMT_YUYV8_2X8:
 		{
@@ -1278,6 +1279,9 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
 	case CAMSS_845:
 		vfe->ops = &vfe_ops_170;
 		break;
+	case CAMSS_8250:
+		vfe->ops = &vfe_ops_480;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -1389,7 +1393,8 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
 				l->formats = formats_rdi_8x96;
 				l->nformats = ARRAY_SIZE(formats_rdi_8x96);
 			}
-		} else if (camss->version == CAMSS_845) {
+		} else if (camss->version == CAMSS_845 ||
+			   camss->version == CAMSS_8250) {
 			l->formats = formats_rdi_845;
 			l->nformats = ARRAY_SIZE(formats_rdi_845);
 		} else {
diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
index 54e77d30d452c..5dc1ddbe6d658 100644
--- a/drivers/media/platform/qcom/camss/camss-video.c
+++ b/drivers/media/platform/qcom/camss/camss-video.c
@@ -1011,7 +1011,8 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
 			video->formats = formats_rdi_8x96;
 			video->nformats = ARRAY_SIZE(formats_rdi_8x96);
 		}
-	}  else if (video->camss->version == CAMSS_845) {
+	}  else if (video->camss->version == CAMSS_845 ||
+		    video->camss->version == CAMSS_8250) {
 		video->formats = formats_rdi_845;
 		video->nformats = ARRAY_SIZE(formats_rdi_845);
 	} else {
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index c08d6d6f6f90d..14a1a6e524345 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -662,6 +662,165 @@ static const struct resources vfe_res_845[] = {
 	}
 };
 
+static const struct resources csiphy_res_8250[] = {
+	/* CSIPHY0 */
+	{
+		.regulator = { NULL },
+		.clock = { "csiphy0", "csiphy0_timer" },
+		.clock_rate = { { 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy0" },
+		.interrupt = { "csiphy0" }
+	},
+	/* CSIPHY1 */
+	{
+		.regulator = { NULL },
+		.clock = { "csiphy1", "csiphy1_timer" },
+		.clock_rate = { { 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy1" },
+		.interrupt = { "csiphy1" }
+	},
+	/* CSIPHY2 */
+	{
+		.regulator = { NULL },
+		.clock = { "csiphy2", "csiphy2_timer" },
+		.clock_rate = { { 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy2" },
+		.interrupt = { "csiphy2" }
+	},
+	/* CSIPHY3 */
+	{
+		.regulator = { NULL },
+		.clock = { "csiphy3", "csiphy3_timer" },
+		.clock_rate = { { 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy3" },
+		.interrupt = { "csiphy3" }
+	},
+	/* CSIPHY4 */
+	{
+		.regulator = { NULL },
+		.clock = { "csiphy4", "csiphy4_timer" },
+		.clock_rate = { { 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy4" },
+		.interrupt = { "csiphy4" }
+	},
+	/* CSIPHY5 */
+	{
+		.regulator = { NULL },
+		.clock = { "csiphy5", "csiphy5_timer" },
+		.clock_rate = { { 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy5" },
+		.interrupt = { "csiphy5" }
+	}
+};
+
+static const struct resources csid_res_8250[] = {
+	/* CSID0 */
+	{
+		.regulator = { NULL },
+		.clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_areg", "vfe0_ahb" },
+		.clock_rate = { { 400000000 },
+				{ 400000000 },
+				{ 350000000, 475000000, 576000000, 720000000 },
+				{ 100000000, 200000000, 300000000, 400000000 },
+				{ 0 } },
+		.reg = { "csid0" },
+		.interrupt = { "csid0" }
+	},
+	/* CSID1 */
+	{
+		.regulator = { NULL },
+		.clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_areg", "vfe1_ahb" },
+		.clock_rate = { { 400000000 },
+				{ 400000000 },
+				{ 350000000, 475000000, 576000000, 720000000 },
+				{ 100000000, 200000000, 300000000, 400000000 },
+				{ 0 } },
+		.reg = { "csid1" },
+		.interrupt = { "csid1" }
+	},
+	/* CSID2 */
+	{
+		.regulator = { NULL },
+		.clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite",  "vfe_lite_ahb" },
+		.clock_rate = { { 400000000 },
+				{ 400000000 },
+				{ 400000000, 480000000 },
+				{ 0 } },
+		.reg = { "csid2" },
+		.interrupt = { "csid2" }
+	},
+	/* CSID3 */
+	{
+		.regulator = { NULL },
+		.clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite",  "vfe_lite_ahb" },
+		.clock_rate = { { 400000000 },
+				{ 400000000 },
+				{ 400000000, 480000000 },
+				{ 0 } },
+		.reg = { "csid3" },
+		.interrupt = { "csid3" }
+	}
+};
+
+static const struct resources vfe_res_8250[] = {
+	/* VFE0 */
+	{
+		.regulator = { NULL },
+		.clock = { "camnoc_axi", "vfe0_ahb", "vfe0_areg", "vfe0", "vfe0_axi", "cam_hf_axi" },
+		.clock_rate = { { 400000000, 480000000 },
+				{ 0 },
+				{ 100000000, 200000000, 300000000, 400000000 },
+				{ 350000000, 475000000, 576000000, 720000000 },
+				{ 0 },
+				{ 0 } },
+		.reg = { "vfe0" },
+		.interrupt = { "vfe0" }
+	},
+	/* VFE1 */
+	{
+		.regulator = { NULL },
+		.clock = { "camnoc_axi", "vfe1_ahb", "vfe1_areg", "vfe1", "vfe1_axi", "cam_hf_axi" },
+		.clock_rate = { { 400000000, 480000000 },
+				{ 0 },
+				{ 100000000, 200000000, 300000000, 400000000 },
+				{ 350000000, 475000000, 576000000, 720000000 },
+				{ 0 },
+				{ 0 } },
+		.reg = { "vfe1" },
+		.interrupt = { "vfe1" }
+	},
+	/* VFE2 (lite) */
+	{
+		.regulator = { NULL },
+		.clock = { "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi", "vfe_lite", "cam_hf_axi" },
+		.clock_rate = { { 400000000, 480000000 },
+				{ 0 },
+				{ 0 },
+				{ 400000000, 480000000 },
+				{ 0 } },
+		.reg = { "vfe_lite0" },
+		.interrupt = { "vfe_lite0" }
+	},
+	/* VFE3 (lite) */
+	{
+		.regulator = { NULL },
+		.clock = { "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi", "vfe_lite", "cam_hf_axi" },
+		.clock_rate = { { 400000000, 480000000 },
+				{ 0 },
+				{ 0 },
+				{ 400000000, 480000000 },
+				{ 0 } },
+		.reg = { "vfe_lite1" },
+		.interrupt = { "vfe_lite1" }
+	},
+};
+
 /*
  * camss_add_clock_margin - Add margin to clock frequency rate
  * @rate: Clock frequency rate
@@ -945,6 +1104,12 @@ static int camss_init_subdevices(struct camss *camss)
 		/* Titan VFEs don't have an ISPIF  */
 		ispif_res = NULL;
 		vfe_res = vfe_res_845;
+	} else if (camss->version == CAMSS_8250) {
+		csiphy_res = csiphy_res_8250;
+		csid_res = csid_res_8250;
+		/* Titan VFEs don't have an ISPIF  */
+		ispif_res = NULL;
+		vfe_res = vfe_res_8250;
 	} else {
 		return -EINVAL;
 	}
@@ -960,6 +1125,17 @@ static int camss_init_subdevices(struct camss *camss)
 		}
 	}
 
+	/* note: SM8250 requires VFE to be initialized before CSID */
+	for (i = 0; i < camss->vfe_num; i++) {
+		ret = msm_vfe_subdev_init(camss, &camss->vfe[i],
+					  &vfe_res[i], i);
+		if (ret < 0) {
+			dev_err(camss->dev,
+				"Fail to init vfe%d sub-device: %d\n", i, ret);
+			return ret;
+		}
+	}
+
 	for (i = 0; i < camss->csid_num; i++) {
 		ret = msm_csid_subdev_init(camss, &camss->csid[i],
 					   &csid_res[i], i);
@@ -978,16 +1154,6 @@ static int camss_init_subdevices(struct camss *camss)
 		return ret;
 	}
 
-	for (i = 0; i < camss->vfe_num; i++) {
-		ret = msm_vfe_subdev_init(camss, &camss->vfe[i],
-					  &vfe_res[i], i);
-		if (ret < 0) {
-			dev_err(camss->dev,
-				"Fail to init vfe%d sub-device: %d\n", i, ret);
-			return ret;
-		}
-	}
-
 	return 0;
 }
 
@@ -1250,7 +1416,8 @@ static int camss_configure_pd(struct camss *camss)
 	if (camss->version == CAMSS_8x96 ||
 	    camss->version == CAMSS_660)
 		nbr_pm_domains = PM_DOMAIN_GEN1_COUNT;
-	else if (camss->version == CAMSS_845)
+	else if (camss->version == CAMSS_845 ||
+		 camss->version == CAMSS_8250)
 		nbr_pm_domains = PM_DOMAIN_GEN2_COUNT;
 
 	for (i = 0; i < nbr_pm_domains; i++) {
@@ -1326,6 +1493,12 @@ static int camss_probe(struct platform_device *pdev)
 		camss->csiphy_num = 4;
 		camss->csid_num = 3;
 		camss->vfe_num = 3;
+	} else if (of_device_is_compatible(dev->of_node,
+					   "qcom,sm8250-camss")) {
+		camss->version = CAMSS_8250;
+		camss->csiphy_num = 6;
+		camss->csid_num = 4;
+		camss->vfe_num = 4;
 	} else {
 		ret = -EINVAL;
 		goto err_free;
@@ -1457,7 +1630,8 @@ void camss_delete(struct camss *camss)
 	if (camss->version == CAMSS_8x96 ||
 	    camss->version == CAMSS_660)
 		nbr_pm_domains = PM_DOMAIN_GEN1_COUNT;
-	else if (camss->version == CAMSS_845)
+	else if (camss->version == CAMSS_845 ||
+		 camss->version == CAMSS_8250)
 		nbr_pm_domains = PM_DOMAIN_GEN2_COUNT;
 
 	for (i = 0; i < nbr_pm_domains; i++) {
@@ -1493,6 +1667,7 @@ static const struct of_device_id camss_dt_match[] = {
 	{ .compatible = "qcom,msm8996-camss" },
 	{ .compatible = "qcom,sdm660-camss" },
 	{ .compatible = "qcom,sdm845-camss" },
+	{ .compatible = "qcom,sm8250-camss" },
 	{ }
 };
 
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 17/17] media: dt-bindings: media: camss: Add qcom,sm8250-camss binding
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (15 preceding siblings ...)
  2021-06-08 22:35 ` [PATCH 16/17] media: camss: add support for SM8250 camss Jonathan Marek
@ 2021-06-08 22:35 ` Jonathan Marek
  2021-06-09 16:16   ` Rob Herring
  2021-06-09 22:10   ` Rob Herring
  2021-06-16 18:16 ` [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Andrey Konovalov
  17 siblings, 2 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-08 22:35 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: robert.foss, andrey.konovalov, Andy Gross, Bjorn Andersson,
	Todor Tomov, Mauro Carvalho Chehab, Rob Herring,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

Add bindings for qcom,sm8250-camss in order to support the camera
subsystem for SM8250.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
---
 .../bindings/media/qcom,sm8250-camss.yaml     | 399 ++++++++++++++++++
 1 file changed, 399 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml

diff --git a/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
new file mode 100644
index 0000000000000..7180e52ee59a8
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
@@ -0,0 +1,399 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/media/qcom,sm8250-camss.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Qualcomm CAMSS ISP
+
+maintainers:
+  - Robert Foss <robert.foss@linaro.org>
+
+description: |
+  The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms
+
+properties:
+  compatible:
+    const: qcom,sm8250-camss
+
+  clocks:
+    minItems: 31
+    maxItems: 31
+
+  clock-names:
+    items:
+      - const: cam_hf_axi
+      - const: camnoc_axi
+      - const: csiphy0
+      - const: csiphy0_timer
+      - const: csiphy1
+      - const: csiphy1_timer
+      - const: csiphy2
+      - const: csiphy2_timer
+      - const: csiphy3
+      - const: csiphy3_timer
+      - const: csiphy4
+      - const: csiphy4_timer
+      - const: csiphy5
+      - const: csiphy5_timer
+      - const: vfe0_ahb
+      - const: vfe0_axi
+      - const: vfe0
+      - const: vfe0_cphy_rx
+      - const: vfe0_csid
+      - const: vfe0_areg
+      - const: vfe1_ahb
+      - const: vfe1_axi
+      - const: vfe1
+      - const: vfe1_cphy_rx
+      - const: vfe1_csid
+      - const: vfe1_areg
+      - const: vfe_lite_ahb
+      - const: vfe_lite_axi
+      - const: vfe_lite
+      - const: vfe_lite_cphy_rx
+      - const: vfe_lite_csid
+
+  interrupts:
+    minItems: 14
+    maxItems: 14
+
+  interrupt-names:
+    items:
+      - const: csid0
+      - const: csid1
+      - const: csid2
+      - const: csid3
+      - const: csiphy0
+      - const: csiphy1
+      - const: csiphy2
+      - const: csiphy3
+      - const: csiphy4
+      - const: csiphy5
+      - const: vfe0
+      - const: vfe1
+      - const: vfe_lite0
+      - const: vfe_lite1
+
+  iommus:
+    maxItems: 1
+
+  power-domains:
+    items:
+      - description: IFE0 GDSC - Image Front End, Global Distributed Switch Controller.
+      - description: IFE1 GDSC - Image Front End, Global Distributed Switch Controller.
+      - description: Titan GDSC - Titan ISP Block, Global Distributed Switch Controller.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    description:
+      CSI input ports.
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              clock-lanes:
+                maxItems: 1
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - clock-lanes
+              - data-lanes
+
+      port@1:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              clock-lanes:
+                maxItems: 1
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - clock-lanes
+              - data-lanes
+
+      port@2:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              clock-lanes:
+                maxItems: 1
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - clock-lanes
+              - data-lanes
+
+      port@3:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              clock-lanes:
+                maxItems: 1
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - clock-lanes
+              - data-lanes
+
+      port@4:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              clock-lanes:
+                maxItems: 1
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - clock-lanes
+              - data-lanes
+
+      port@5:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              clock-lanes:
+                maxItems: 1
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - clock-lanes
+              - data-lanes
+
+  reg:
+    minItems: 10
+    maxItems: 10
+
+  reg-names:
+    items:
+      - const: csiphy0
+      - const: csiphy1
+      - const: csiphy2
+      - const: csiphy3
+      - const: csiphy4
+      - const: csiphy5
+      - const: vfe0
+      - const: vfe1
+      - const: vfe_lite0
+      - const: vfe_lite1
+
+required:
+  - clock-names
+  - clocks
+  - compatible
+  - interrupt-names
+  - interrupts
+  - iommus
+  - power-domains
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/qcom,camcc-sm8250.h>
+    #include <dt-bindings/clock/qcom,gcc-sm8250.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      camss: camss@ac6a000 {
+        compatible = "qcom,sm8250-camss";
+
+        reg = <0 0xac6a000 0 0x2000>,
+          <0 0xac6c000 0 0x2000>,
+          <0 0xac6e000 0 0x1000>,
+          <0 0xac70000 0 0x1000>,
+          <0 0xac72000 0 0x1000>,
+          <0 0xac74000 0 0x1000>,
+          <0 0xacb4000 0 0xd000>,
+          <0 0xacc3000 0 0xd000>,
+          <0 0xacd9000 0 0x2200>,
+          <0 0xacdb200 0 0x2200>;
+        reg-names = "csiphy0",
+          "csiphy1",
+          "csiphy2",
+          "csiphy3",
+          "csiphy4",
+          "csiphy5",
+          "vfe0",
+          "vfe1",
+          "vfe_lite0",
+          "vfe_lite1";
+
+        interrupts = <GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH>,
+          <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>,
+          <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>,
+          <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>,
+          <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
+          <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+          <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>,
+          <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
+          <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
+          <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
+          <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>,
+          <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
+          <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>,
+          <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "csiphy0",
+          "csiphy1",
+          "csiphy2",
+          "csiphy3",
+          "csiphy4",
+          "csiphy5",
+          "csid0",
+          "csid1",
+          "csid2",
+          "csid3",
+          "vfe0",
+          "vfe1",
+          "vfe_lite0",
+          "vfe_lite1";
+
+        power-domains = <&camcc IFE_0_GDSC>,
+          <&camcc IFE_1_GDSC>,
+          <&camcc TITAN_TOP_GDSC>;
+
+        clocks = <&gcc GCC_CAMERA_HF_AXI_CLK>,
+          <&camcc CAM_CC_CSIPHY0_CLK>,
+          <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
+          <&camcc CAM_CC_CSIPHY1_CLK>,
+          <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
+          <&camcc CAM_CC_CSIPHY2_CLK>,
+          <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
+          <&camcc CAM_CC_CSIPHY3_CLK>,
+          <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
+          <&camcc CAM_CC_CSIPHY4_CLK>,
+          <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
+          <&camcc CAM_CC_CSIPHY5_CLK>,
+          <&camcc CAM_CC_CSI5PHYTIMER_CLK>,
+          <&camcc CAM_CC_IFE_0_AHB_CLK>,
+          <&camcc CAM_CC_IFE_0_AXI_CLK>,
+          <&camcc CAM_CC_IFE_0_CLK>,
+          <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+          <&camcc CAM_CC_IFE_0_CSID_CLK>,
+          <&camcc CAM_CC_IFE_0_AREG_CLK>,
+          <&camcc CAM_CC_IFE_1_AHB_CLK>,
+          <&camcc CAM_CC_IFE_1_AXI_CLK>,
+          <&camcc CAM_CC_IFE_1_CLK>,
+          <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+          <&camcc CAM_CC_IFE_1_CSID_CLK>,
+          <&camcc CAM_CC_IFE_1_AREG_CLK>,
+          <&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+          <&camcc CAM_CC_IFE_LITE_AXI_CLK>,
+          <&camcc CAM_CC_IFE_LITE_CLK>,
+          <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+          <&camcc CAM_CC_IFE_LITE_CSID_CLK>;
+
+        clock-names = "cam_hf_axi",
+          "csiphy0",
+          "csiphy0_timer",
+          "csiphy1",
+          "csiphy1_timer",
+          "csiphy2",
+          "csiphy2_timer",
+          "csiphy3",
+          "csiphy3_timer",
+          "csiphy4",
+          "csiphy4_timer",
+          "csiphy5",
+          "csiphy5_timer",
+          "vfe0_ahb",
+          "vfe0_axi",
+          "vfe0",
+          "vfe0_cphy_rx",
+          "vfe0_csid",
+          "vfe0_areg",
+          "vfe1_ahb",
+          "vfe1_axi",
+          "vfe1",
+          "vfe1_cphy_rx",
+          "vfe1_csid",
+          "vfe1_areg",
+          "vfe_lite_ahb",
+          "vfe_lite_axi",
+          "vfe_lite",
+          "vfe_lite_cphy_rx",
+          "vfe_lite_csid";
+
+        iommus = <&apps_smmu 0x800 0x400>;
+
+        ports {
+          #address-cells = <1>;
+          #size-cells = <0>;
+        };
+      };
+    };
-- 
2.26.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 12/17] media: camss: remove some vfe ops and clean up dead vfe-170 code
  2021-06-08 22:35 ` [PATCH 12/17] media: camss: remove some vfe ops and clean up dead vfe-170 code Jonathan Marek
@ 2021-06-09  3:23   ` kernel test robot
  2021-06-10  5:23   ` kernel test robot
  2021-06-10 12:37   ` Robert Foss
  2 siblings, 0 replies; 28+ messages in thread
From: kernel test robot @ 2021-06-09  3:23 UTC (permalink / raw)
  To: Jonathan Marek, linux-arm-msm
  Cc: kbuild-all, robert.foss, andrey.konovalov, Todor Tomov,
	Andy Gross, Bjorn Andersson, Mauro Carvalho Chehab, linux-media,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2596 bytes --]

Hi Jonathan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on v5.13-rc5]
[also build test WARNING on next-20210608]
[cannot apply to linuxtv-media/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jonathan-Marek/CAMSS-SM8250-support-and-some-fixes/20210609-064108
base:    614124bea77e452aa6df7a8714e8bc820b489922
config: sh-allmodconfig (attached as .config)
compiler: sh4-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/3c204c01a75526c1bc39788a012adb7e495c39f4
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jonathan-Marek/CAMSS-SM8250-support-and-some-fixes/20210609-064108
        git checkout 3c204c01a75526c1bc39788a012adb7e495c39f4
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=sh 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/media/platform/qcom/camss/camss-vfe-gen1.c:683: warning: expecting prototype for vfe_isr_comp_done(). Prototype was for vfe_gen1_isr_comp_done() instead

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for SND_ATMEL_SOC_PDC
   Depends on SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC && HAS_DMA
   Selected by
   - SND_ATMEL_SOC_SSC && SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC
   - SND_ATMEL_SOC_SSC_PDC && SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC && ATMEL_SSC


vim +683 drivers/media/platform/qcom/camss/camss-vfe-gen1.c

   676	
   677	/**
   678	 * vfe_isr_comp_done() - Process composite image done interrupt
   679	 * @vfe: VFE Device
   680	 * @comp: Composite image id
   681	 */
   682	void vfe_gen1_isr_comp_done(struct vfe_device *vfe, u8 comp)
 > 683	{
   684		unsigned int i;
   685	
   686		for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
   687			if (vfe->wm_output_map[i] == VFE_LINE_PIX) {
   688				vfe_gen1_isr_wm_done(vfe, i);
   689				break;
   690			}
   691	}
   692	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 54740 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 17/17] media: dt-bindings: media: camss: Add qcom,sm8250-camss binding
  2021-06-08 22:35 ` [PATCH 17/17] media: dt-bindings: media: camss: Add qcom,sm8250-camss binding Jonathan Marek
@ 2021-06-09 16:16   ` Rob Herring
  2021-06-09 22:10   ` Rob Herring
  1 sibling, 0 replies; 28+ messages in thread
From: Rob Herring @ 2021-06-09 16:16 UTC (permalink / raw)
  To: Jonathan Marek
  Cc: Bjorn Andersson, andrey.konovalov, linux-media, linux-arm-msm,
	linux-kernel, devicetree, Todor Tomov, Rob Herring, Andy Gross,
	robert.foss, Mauro Carvalho Chehab

On Tue, 08 Jun 2021 18:35:06 -0400, Jonathan Marek wrote:
> Add bindings for qcom,sm8250-camss in order to support the camera
> subsystem for SM8250.
> 
> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> ---
>  .../bindings/media/qcom,sm8250-camss.yaml     | 399 ++++++++++++++++++
>  1 file changed, 399 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/media/qcom,sm8250-camss.example.dts:20:18: fatal error: dt-bindings/clock/qcom,camcc-sm8250.h: No such file or directory
   20 |         #include <dt-bindings/clock/qcom,camcc-sm8250.h>
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/media/qcom,sm8250-camss.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1416: dt_binding_check] Error 2
\ndoc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1489658

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 17/17] media: dt-bindings: media: camss: Add qcom,sm8250-camss binding
  2021-06-08 22:35 ` [PATCH 17/17] media: dt-bindings: media: camss: Add qcom,sm8250-camss binding Jonathan Marek
  2021-06-09 16:16   ` Rob Herring
@ 2021-06-09 22:10   ` Rob Herring
  2021-06-09 22:32     ` Jonathan Marek
  1 sibling, 1 reply; 28+ messages in thread
From: Rob Herring @ 2021-06-09 22:10 UTC (permalink / raw)
  To: Jonathan Marek
  Cc: linux-arm-msm, robert.foss, andrey.konovalov, Andy Gross,
	Bjorn Andersson, Todor Tomov, Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

On Tue, Jun 08, 2021 at 06:35:06PM -0400, Jonathan Marek wrote:
> Add bindings for qcom,sm8250-camss in order to support the camera
> subsystem for SM8250.
> 
> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> ---
>  .../bindings/media/qcom,sm8250-camss.yaml     | 399 ++++++++++++++++++
>  1 file changed, 399 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
> new file mode 100644
> index 0000000000000..7180e52ee59a8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
> @@ -0,0 +1,399 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/media/qcom,sm8250-camss.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Qualcomm CAMSS ISP
> +
> +maintainers:
> +  - Robert Foss <robert.foss@linaro.org>
> +
> +description: |
> +  The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms
> +
> +properties:
> +  compatible:
> +    const: qcom,sm8250-camss
> +
> +  clocks:
> +    minItems: 31
> +    maxItems: 31
> +
> +  clock-names:
> +    items:
> +      - const: cam_hf_axi
> +      - const: camnoc_axi
> +      - const: csiphy0
> +      - const: csiphy0_timer
> +      - const: csiphy1
> +      - const: csiphy1_timer
> +      - const: csiphy2
> +      - const: csiphy2_timer
> +      - const: csiphy3
> +      - const: csiphy3_timer
> +      - const: csiphy4
> +      - const: csiphy4_timer
> +      - const: csiphy5
> +      - const: csiphy5_timer
> +      - const: vfe0_ahb
> +      - const: vfe0_axi
> +      - const: vfe0
> +      - const: vfe0_cphy_rx
> +      - const: vfe0_csid
> +      - const: vfe0_areg
> +      - const: vfe1_ahb
> +      - const: vfe1_axi
> +      - const: vfe1
> +      - const: vfe1_cphy_rx
> +      - const: vfe1_csid
> +      - const: vfe1_areg
> +      - const: vfe_lite_ahb
> +      - const: vfe_lite_axi
> +      - const: vfe_lite
> +      - const: vfe_lite_cphy_rx
> +      - const: vfe_lite_csid
> +
> +  interrupts:
> +    minItems: 14
> +    maxItems: 14
> +
> +  interrupt-names:
> +    items:
> +      - const: csid0
> +      - const: csid1
> +      - const: csid2
> +      - const: csid3
> +      - const: csiphy0
> +      - const: csiphy1
> +      - const: csiphy2
> +      - const: csiphy3
> +      - const: csiphy4
> +      - const: csiphy5
> +      - const: vfe0
> +      - const: vfe1
> +      - const: vfe_lite0
> +      - const: vfe_lite1
> +
> +  iommus:
> +    maxItems: 1
> +
> +  power-domains:
> +    items:
> +      - description: IFE0 GDSC - Image Front End, Global Distributed Switch Controller.
> +      - description: IFE1 GDSC - Image Front End, Global Distributed Switch Controller.
> +      - description: Titan GDSC - Titan ISP Block, Global Distributed Switch Controller.
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    description:
> +      CSI input ports.
> +
> +    properties:
> +      port@0:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false
> +        description:
> +          Input port for receiving CSI data.
> +
> +        properties:
> +          endpoint:
> +            $ref: video-interfaces.yaml#
> +            unevaluatedProperties: false
> +
> +            properties:
> +              clock-lanes:
> +                maxItems: 1
> +
> +              data-lanes:
> +                minItems: 1
> +                maxItems: 4
> +
> +            required:
> +              - clock-lanes
> +              - data-lanes
> +
> +      port@1:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false
> +        description:
> +          Input port for receiving CSI data.
> +
> +        properties:
> +          endpoint:
> +            $ref: video-interfaces.yaml#
> +            unevaluatedProperties: false
> +
> +            properties:
> +              clock-lanes:
> +                maxItems: 1
> +
> +              data-lanes:
> +                minItems: 1
> +                maxItems: 4
> +
> +            required:
> +              - clock-lanes
> +              - data-lanes
> +
> +      port@2:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false
> +        description:
> +          Input port for receiving CSI data.
> +
> +        properties:
> +          endpoint:
> +            $ref: video-interfaces.yaml#
> +            unevaluatedProperties: false
> +
> +            properties:
> +              clock-lanes:
> +                maxItems: 1
> +
> +              data-lanes:
> +                minItems: 1
> +                maxItems: 4
> +
> +            required:
> +              - clock-lanes
> +              - data-lanes
> +
> +      port@3:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false
> +        description:
> +          Input port for receiving CSI data.
> +
> +        properties:
> +          endpoint:
> +            $ref: video-interfaces.yaml#
> +            unevaluatedProperties: false
> +
> +            properties:
> +              clock-lanes:
> +                maxItems: 1
> +
> +              data-lanes:
> +                minItems: 1
> +                maxItems: 4
> +
> +            required:
> +              - clock-lanes
> +              - data-lanes
> +
> +      port@4:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false
> +        description:
> +          Input port for receiving CSI data.
> +
> +        properties:
> +          endpoint:
> +            $ref: video-interfaces.yaml#
> +            unevaluatedProperties: false
> +
> +            properties:
> +              clock-lanes:
> +                maxItems: 1
> +
> +              data-lanes:
> +                minItems: 1
> +                maxItems: 4
> +
> +            required:
> +              - clock-lanes
> +              - data-lanes
> +
> +      port@5:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false
> +        description:
> +          Input port for receiving CSI data.
> +
> +        properties:
> +          endpoint:
> +            $ref: video-interfaces.yaml#
> +            unevaluatedProperties: false
> +
> +            properties:
> +              clock-lanes:
> +                maxItems: 1
> +
> +              data-lanes:
> +                minItems: 1
> +                maxItems: 4
> +
> +            required:
> +              - clock-lanes
> +              - data-lanes
> +
> +  reg:
> +    minItems: 10
> +    maxItems: 10
> +
> +  reg-names:

Move these before ports. (DT) properties first then nodes.

> +    items:
> +      - const: csiphy0
> +      - const: csiphy1
> +      - const: csiphy2
> +      - const: csiphy3
> +      - const: csiphy4
> +      - const: csiphy5

Should be separate phy nodes? Same/similar DPHY or CPHY as QCom DSI PHY?

> +      - const: vfe0
> +      - const: vfe1
> +      - const: vfe_lite0
> +      - const: vfe_lite1
> +
> +required:
> +  - clock-names
> +  - clocks
> +  - compatible
> +  - interrupt-names
> +  - interrupts
> +  - iommus
> +  - power-domains
> +  - reg
> +  - reg-names
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/qcom,camcc-sm8250.h>
> +    #include <dt-bindings/clock/qcom,gcc-sm8250.h>
> +
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      camss: camss@ac6a000 {
> +        compatible = "qcom,sm8250-camss";
> +
> +        reg = <0 0xac6a000 0 0x2000>,
> +          <0 0xac6c000 0 0x2000>,
> +          <0 0xac6e000 0 0x1000>,
> +          <0 0xac70000 0 0x1000>,
> +          <0 0xac72000 0 0x1000>,
> +          <0 0xac74000 0 0x1000>,
> +          <0 0xacb4000 0 0xd000>,
> +          <0 0xacc3000 0 0xd000>,
> +          <0 0xacd9000 0 0x2200>,
> +          <0 0xacdb200 0 0x2200>;
> +        reg-names = "csiphy0",
> +          "csiphy1",
> +          "csiphy2",
> +          "csiphy3",
> +          "csiphy4",
> +          "csiphy5",
> +          "vfe0",
> +          "vfe1",
> +          "vfe_lite0",
> +          "vfe_lite1";
> +
> +        interrupts = <GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH>,
> +          <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>,
> +          <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>,
> +          <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>,
> +          <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
> +          <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
> +          <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>,
> +          <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
> +          <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
> +          <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
> +          <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>,
> +          <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
> +          <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>,
> +          <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
> +        interrupt-names = "csiphy0",
> +          "csiphy1",
> +          "csiphy2",
> +          "csiphy3",
> +          "csiphy4",
> +          "csiphy5",
> +          "csid0",
> +          "csid1",
> +          "csid2",
> +          "csid3",
> +          "vfe0",
> +          "vfe1",
> +          "vfe_lite0",
> +          "vfe_lite1";
> +
> +        power-domains = <&camcc IFE_0_GDSC>,
> +          <&camcc IFE_1_GDSC>,
> +          <&camcc TITAN_TOP_GDSC>;
> +
> +        clocks = <&gcc GCC_CAMERA_HF_AXI_CLK>,
> +          <&camcc CAM_CC_CSIPHY0_CLK>,
> +          <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
> +          <&camcc CAM_CC_CSIPHY1_CLK>,
> +          <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
> +          <&camcc CAM_CC_CSIPHY2_CLK>,
> +          <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
> +          <&camcc CAM_CC_CSIPHY3_CLK>,
> +          <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
> +          <&camcc CAM_CC_CSIPHY4_CLK>,
> +          <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
> +          <&camcc CAM_CC_CSIPHY5_CLK>,
> +          <&camcc CAM_CC_CSI5PHYTIMER_CLK>,
> +          <&camcc CAM_CC_IFE_0_AHB_CLK>,
> +          <&camcc CAM_CC_IFE_0_AXI_CLK>,
> +          <&camcc CAM_CC_IFE_0_CLK>,
> +          <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
> +          <&camcc CAM_CC_IFE_0_CSID_CLK>,
> +          <&camcc CAM_CC_IFE_0_AREG_CLK>,
> +          <&camcc CAM_CC_IFE_1_AHB_CLK>,
> +          <&camcc CAM_CC_IFE_1_AXI_CLK>,
> +          <&camcc CAM_CC_IFE_1_CLK>,
> +          <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
> +          <&camcc CAM_CC_IFE_1_CSID_CLK>,
> +          <&camcc CAM_CC_IFE_1_AREG_CLK>,
> +          <&camcc CAM_CC_IFE_LITE_AHB_CLK>,
> +          <&camcc CAM_CC_IFE_LITE_AXI_CLK>,
> +          <&camcc CAM_CC_IFE_LITE_CLK>,
> +          <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
> +          <&camcc CAM_CC_IFE_LITE_CSID_CLK>;
> +
> +        clock-names = "cam_hf_axi",
> +          "csiphy0",
> +          "csiphy0_timer",
> +          "csiphy1",
> +          "csiphy1_timer",
> +          "csiphy2",
> +          "csiphy2_timer",
> +          "csiphy3",
> +          "csiphy3_timer",
> +          "csiphy4",
> +          "csiphy4_timer",
> +          "csiphy5",
> +          "csiphy5_timer",
> +          "vfe0_ahb",
> +          "vfe0_axi",
> +          "vfe0",
> +          "vfe0_cphy_rx",
> +          "vfe0_csid",
> +          "vfe0_areg",
> +          "vfe1_ahb",
> +          "vfe1_axi",
> +          "vfe1",
> +          "vfe1_cphy_rx",
> +          "vfe1_csid",
> +          "vfe1_areg",
> +          "vfe_lite_ahb",
> +          "vfe_lite_axi",
> +          "vfe_lite",
> +          "vfe_lite_cphy_rx",
> +          "vfe_lite_csid";
> +
> +        iommus = <&apps_smmu 0x800 0x400>;
> +
> +        ports {
> +          #address-cells = <1>;
> +          #size-cells = <0>;
> +        };
> +      };
> +    };
> -- 
> 2.26.1

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 17/17] media: dt-bindings: media: camss: Add qcom,sm8250-camss binding
  2021-06-09 22:10   ` Rob Herring
@ 2021-06-09 22:32     ` Jonathan Marek
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Marek @ 2021-06-09 22:32 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-msm, robert.foss, andrey.konovalov, Andy Gross,
	Bjorn Andersson, Todor Tomov, Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

On 6/9/21 6:10 PM, Rob Herring wrote:
> On Tue, Jun 08, 2021 at 06:35:06PM -0400, Jonathan Marek wrote:
>> Add bindings for qcom,sm8250-camss in order to support the camera
>> subsystem for SM8250.

...

>> +    items:
>> +      - const: csiphy0
>> +      - const: csiphy1
>> +      - const: csiphy2
>> +      - const: csiphy3
>> +      - const: csiphy4
>> +      - const: csiphy5
> 
> Should be separate phy nodes? Same/similar DPHY or CPHY as QCom DSI PHY?
> 

This is not a new driver, this series only adds support for a new SoC - 
the design has already been decided (and this binding is similar to 
qcom,sdm845-camss.yaml).

The hardware supports D-PHY and C-PHY, but the driver isn't aware of 
this and assumes D-PHY. sdm845 and msm8996 hardware also support C-PHY, 
so it isn't a problem specific to this series.

>> +      - const: vfe0
>> +      - const: vfe1
>> +      - const: vfe_lite0
>> +      - const: vfe_lite1
>> +


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 12/17] media: camss: remove some vfe ops and clean up dead vfe-170 code
  2021-06-08 22:35 ` [PATCH 12/17] media: camss: remove some vfe ops and clean up dead vfe-170 code Jonathan Marek
  2021-06-09  3:23   ` kernel test robot
@ 2021-06-10  5:23   ` kernel test robot
  2021-06-10 12:37   ` Robert Foss
  2 siblings, 0 replies; 28+ messages in thread
From: kernel test robot @ 2021-06-10  5:23 UTC (permalink / raw)
  To: Jonathan Marek, linux-arm-msm
  Cc: kbuild-all, clang-built-linux, robert.foss, andrey.konovalov,
	Todor Tomov, Andy Gross, Bjorn Andersson, Mauro Carvalho Chehab,
	linux-media, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2436 bytes --]

Hi Jonathan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on v5.13-rc5]
[also build test WARNING on next-20210609]
[cannot apply to linuxtv-media/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jonathan-Marek/CAMSS-SM8250-support-and-some-fixes/20210609-064108
base:    614124bea77e452aa6df7a8714e8bc820b489922
config: x86_64-randconfig-a001-20210609 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project d2012d965d60c3258b3a69d024491698f8aec386)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # https://github.com/0day-ci/linux/commit/3c204c01a75526c1bc39788a012adb7e495c39f4
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jonathan-Marek/CAMSS-SM8250-support-and-some-fixes/20210609-064108
        git checkout 3c204c01a75526c1bc39788a012adb7e495c39f4
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/media/platform/qcom/camss/camss-vfe-gen1.c:683: warning: expecting prototype for vfe_isr_comp_done(). Prototype was for vfe_gen1_isr_comp_done() instead


vim +683 drivers/media/platform/qcom/camss/camss-vfe-gen1.c

   676	
   677	/**
   678	 * vfe_isr_comp_done() - Process composite image done interrupt
   679	 * @vfe: VFE Device
   680	 * @comp: Composite image id
   681	 */
   682	void vfe_gen1_isr_comp_done(struct vfe_device *vfe, u8 comp)
 > 683	{
   684		unsigned int i;
   685	
   686		for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
   687			if (vfe->wm_output_map[i] == VFE_LINE_PIX) {
   688				vfe_gen1_isr_wm_done(vfe, i);
   689				break;
   690			}
   691	}
   692	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 42897 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 09/17] media: camss: csid: allow csid to work without a regulator
  2021-06-08 22:34 ` [PATCH 09/17] media: camss: csid: allow csid to work without a regulator Jonathan Marek
@ 2021-06-10  8:01   ` Robert Foss
  0 siblings, 0 replies; 28+ messages in thread
From: Robert Foss @ 2021-06-10  8:01 UTC (permalink / raw)
  To: Jonathan Marek
  Cc: MSM, Andrey Konovalov, Todor Tomov, Andy Gross, Bjorn Andersson,
	Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

Hey Jonathan,

On Wed, 9 Jun 2021 at 00:37, Jonathan Marek <jonathan@marek.ca> wrote:
>
> At least for titan HW, CSID don't have an associated regulator. This change
> is necessary to be able to model this in the CSID resources.
>
> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> Reviewed-by: Robert Foss <robert.foss@linaro.org>
> ---
>  drivers/media/platform/qcom/camss/camss-csid.c | 17 +++++++++++------
>  1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
> index cc11fbfdae132..528674dea06ca 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.c
> +++ b/drivers/media/platform/qcom/camss/camss-csid.c
> @@ -162,7 +162,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
>                         return ret;
>                 }
>
> -               ret = regulator_enable(csid->vdda);
> +               ret = csid->vdda ? regulator_enable(csid->vdda) : 0;
>                 if (ret < 0) {
>                         pm_runtime_put_sync(dev);
>                         return ret;
> @@ -170,14 +170,16 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
>
>                 ret = csid_set_clock_rates(csid);
>                 if (ret < 0) {
> -                       regulator_disable(csid->vdda);
> +                       if (csid->vdda)
> +                               regulator_disable(csid->vdda);
>                         pm_runtime_put_sync(dev);
>                         return ret;
>                 }
>
>                 ret = camss_enable_clocks(csid->nclocks, csid->clock, dev);
>                 if (ret < 0) {
> -                       regulator_disable(csid->vdda);
> +                       if (csid->vdda)
> +                               regulator_disable(csid->vdda);
>                         pm_runtime_put_sync(dev);
>                         return ret;
>                 }
> @@ -188,7 +190,8 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
>                 if (ret < 0) {
>                         disable_irq(csid->irq);
>                         camss_disable_clocks(csid->nclocks, csid->clock);
> -                       regulator_disable(csid->vdda);
> +                       if (csid->vdda)
> +                               regulator_disable(csid->vdda);
>                         pm_runtime_put_sync(dev);
>                         return ret;
>                 }
> @@ -197,7 +200,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
>         } else {
>                 disable_irq(csid->irq);
>                 camss_disable_clocks(csid->nclocks, csid->clock);
> -               ret = regulator_disable(csid->vdda);
> +               ret = csid->vdda ? regulator_disable(csid->vdda) : 0;
>                 pm_runtime_put_sync(dev);
>         }
>
> @@ -634,7 +637,9 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
>
>         /* Regulator */
>
> -       csid->vdda = devm_regulator_get(dev, res->regulator[0]);
> +       csid->vdda = NULL;
> +       if (res->regulator[0])
> +               csid->vdda = devm_regulator_get(dev, res->regulator[0]);
>         if (IS_ERR(csid->vdda)) {
>                 dev_err(dev, "could not get regulator\n");
>                 return PTR_ERR(csid->vdda);
> --
> 2.26.1
>

This patch does not seem to apply on upstream-media/master.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 16/17] media: camss: add support for SM8250 camss
  2021-06-08 22:35 ` [PATCH 16/17] media: camss: add support for SM8250 camss Jonathan Marek
@ 2021-06-10  8:03   ` Robert Foss
  0 siblings, 0 replies; 28+ messages in thread
From: Robert Foss @ 2021-06-10  8:03 UTC (permalink / raw)
  To: Jonathan Marek
  Cc: MSM, Andrey Konovalov, Todor Tomov, Andy Gross, Bjorn Andersson,
	Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

Hey Jonathan,

On Wed, 9 Jun 2021 at 00:38, Jonathan Marek <jonathan@marek.ca> wrote:
>
> The Titan 480 camss found on SM8250 has 6 CSIPHY and 4 VFE/CSID.
>
> CSID is compatible with the Titan 170 CSID, but the Titan 480 CSID are
> inside the VFE region (between the "top" and "bus" registers), so a
> workaround is added to avoid ioremap failure.
>
> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> Reviewed-by: Robert Foss <robert.foss@linaro.org>
> ---
>  drivers/media/platform/qcom/camss/Makefile    |   2 +-
>  .../{camss-csid-170.c => camss-csid-gen2.c}   |   2 +-
>  .../media/platform/qcom/camss/camss-csid.c    |  28 ++-
>  .../media/platform/qcom/camss/camss-csid.h    |   2 +-
>  .../media/platform/qcom/camss/camss-csiphy.c  |   8 +-
>  drivers/media/platform/qcom/camss/camss-vfe.c |   9 +-
>  .../media/platform/qcom/camss/camss-video.c   |   3 +-
>  drivers/media/platform/qcom/camss/camss.c     | 199 ++++++++++++++++--
>  8 files changed, 227 insertions(+), 26 deletions(-)
>  rename drivers/media/platform/qcom/camss/{camss-csid-170.c => camss-csid-gen2.c} (99%)
>
> diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
> index 81dd56aff0f27..4e22223589739 100644
> --- a/drivers/media/platform/qcom/camss/Makefile
> +++ b/drivers/media/platform/qcom/camss/Makefile
> @@ -6,7 +6,7 @@ qcom-camss-objs += \
>                 camss-csid.o \
>                 camss-csid-4-1.o \
>                 camss-csid-4-7.o \
> -               camss-csid-170.o \
> +               camss-csid-gen2.o \
>                 camss-csiphy-2ph-1-0.o \
>                 camss-csiphy-3ph-1-0.o \
>                 camss-csiphy.o \
> diff --git a/drivers/media/platform/qcom/camss/camss-csid-170.c b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
> similarity index 99%
> rename from drivers/media/platform/qcom/camss/camss-csid-170.c
> rename to drivers/media/platform/qcom/camss/camss-csid-gen2.c
> index 9e54d251793fc..abbfbf4488934 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid-170.c
> +++ b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
> @@ -594,7 +594,7 @@ static void csid_subdev_init(struct csid_device *csid)
>         csid->testgen.nmodes = CSID_PAYLOAD_MODE_NUM_SUPPORTED_GEN2;
>  }
>
> -const struct csid_hw_ops csid_ops_170 = {
> +const struct csid_hw_ops csid_ops_gen2 = {
>         .configure_stream = csid_configure_stream,
>         .configure_testgen_pattern = csid_configure_testgen_pattern,
>         .hw_version = csid_hw_version,
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
> index 528674dea06ca..b4c068a152f73 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.c
> +++ b/drivers/media/platform/qcom/camss/camss-csid.c
> @@ -25,6 +25,10 @@
>  #include "camss-csid-gen1.h"
>  #include "camss.h"
>
> +/* offset of CSID registers in VFE region for VFE 480 */
> +#define VFE_480_CSID_OFFSET 0x1200
> +#define VFE_480_LITE_CSID_OFFSET 0x200
> +
>  #define MSM_CSID_NAME "msm_csid"
>
>  const char * const csid_testgen_modes[] = {
> @@ -560,8 +564,9 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
>         } else if (camss->version == CAMSS_8x96 ||
>                    camss->version == CAMSS_660) {
>                 csid->ops = &csid_ops_4_7;
> -       } else if (camss->version == CAMSS_845) {
> -               csid->ops = &csid_ops_170;
> +       } else if (camss->version == CAMSS_845 ||
> +                  camss->version == CAMSS_8250) {
> +               csid->ops = &csid_ops_gen2;
>         } else {
>                 return -EINVAL;
>         }
> @@ -569,10 +574,21 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
>
>         /* Memory */
>
> -       r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]);
> -       csid->base = devm_ioremap_resource(dev, r);
> -       if (IS_ERR(csid->base))
> -               return PTR_ERR(csid->base);
> +       if (camss->version == CAMSS_8250) {
> +               /* for titan 480, CSID registers are inside the VFE region,
> +                * between the VFE "top" and "bus" registers. this requires
> +                * VFE to be initialized before CSID
> +                */
> +               if (id >= 2) /* VFE/CSID lite */
> +                       csid->base = camss->vfe[id].base + VFE_480_LITE_CSID_OFFSET;
> +               else
> +                       csid->base = camss->vfe[id].base + VFE_480_CSID_OFFSET;
> +       } else {
> +               r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]);
> +               csid->base = devm_ioremap_resource(dev, r);
> +               if (IS_ERR(csid->base))
> +                       return PTR_ERR(csid->base);
> +       }
>
>         /* Interrupt */
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
> index 814ebc7c29d65..17a50fa426be1 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.h
> +++ b/drivers/media/platform/qcom/camss/camss-csid.h
> @@ -205,7 +205,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_170;
> +extern const struct csid_hw_ops csid_ops_gen2;
>
>
>  #endif /* QC_MSM_CAMSS_CSID_H */
> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
> index f82f1e2aa6883..1d10c816acf5c 100644
> --- a/drivers/media/platform/qcom/camss/camss-csiphy.c
> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
> @@ -582,7 +582,8 @@ int msm_csiphy_subdev_init(struct camss *camss,
>                 csiphy->ops = &csiphy_ops_3ph_1_0;
>                 csiphy->formats = csiphy_formats_8x96;
>                 csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x96);
> -       } else if (camss->version == CAMSS_845) {
> +       } else if (camss->version == CAMSS_845 ||
> +                  camss->version == CAMSS_8250) {
>                 csiphy->ops = &csiphy_ops_3ph_1_0;
>                 csiphy->formats = csiphy_formats_sdm845;
>                 csiphy->nformats = ARRAY_SIZE(csiphy_formats_sdm845);
> @@ -679,7 +680,10 @@ int msm_csiphy_subdev_init(struct camss *camss,
>
>                 if (!strcmp(clock->name, "csiphy0_timer") ||
>                     !strcmp(clock->name, "csiphy1_timer") ||
> -                   !strcmp(clock->name, "csiphy2_timer"))
> +                   !strcmp(clock->name, "csiphy2_timer") ||
> +                   !strcmp(clock->name, "csiphy3_timer") ||
> +                   !strcmp(clock->name, "csiphy4_timer") ||
> +                   !strcmp(clock->name, "csiphy5_timer"))
>                         csiphy->rate_set[i] = true;
>
>                 if (camss->version == CAMSS_660 &&
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
> index b08bded2344e6..48d05ece0dcc1 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
> @@ -220,7 +220,8 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
>                 }
>         else if (vfe->camss->version == CAMSS_8x96 ||
>                  vfe->camss->version == CAMSS_660 ||
> -                vfe->camss->version == CAMSS_845)
> +                vfe->camss->version == CAMSS_845 ||
> +                vfe->camss->version == CAMSS_8250)
>                 switch (sink_code) {
>                 case MEDIA_BUS_FMT_YUYV8_2X8:
>                 {
> @@ -1278,6 +1279,9 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
>         case CAMSS_845:
>                 vfe->ops = &vfe_ops_170;
>                 break;
> +       case CAMSS_8250:
> +               vfe->ops = &vfe_ops_480;
> +               break;
>         default:
>                 return -EINVAL;
>         }
> @@ -1389,7 +1393,8 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
>                                 l->formats = formats_rdi_8x96;
>                                 l->nformats = ARRAY_SIZE(formats_rdi_8x96);
>                         }
> -               } else if (camss->version == CAMSS_845) {
> +               } else if (camss->version == CAMSS_845 ||
> +                          camss->version == CAMSS_8250) {
>                         l->formats = formats_rdi_845;
>                         l->nformats = ARRAY_SIZE(formats_rdi_845);
>                 } else {
> diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
> index 54e77d30d452c..5dc1ddbe6d658 100644
> --- a/drivers/media/platform/qcom/camss/camss-video.c
> +++ b/drivers/media/platform/qcom/camss/camss-video.c
> @@ -1011,7 +1011,8 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
>                         video->formats = formats_rdi_8x96;
>                         video->nformats = ARRAY_SIZE(formats_rdi_8x96);
>                 }
> -       }  else if (video->camss->version == CAMSS_845) {
> +       }  else if (video->camss->version == CAMSS_845 ||
> +                   video->camss->version == CAMSS_8250) {
>                 video->formats = formats_rdi_845;
>                 video->nformats = ARRAY_SIZE(formats_rdi_845);
>         } else {
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index c08d6d6f6f90d..14a1a6e524345 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -662,6 +662,165 @@ static const struct resources vfe_res_845[] = {
>         }
>  };
>
> +static const struct resources csiphy_res_8250[] = {
> +       /* CSIPHY0 */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "csiphy0", "csiphy0_timer" },
> +               .clock_rate = { { 400000000 },
> +                               { 300000000 } },
> +               .reg = { "csiphy0" },
> +               .interrupt = { "csiphy0" }
> +       },
> +       /* CSIPHY1 */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "csiphy1", "csiphy1_timer" },
> +               .clock_rate = { { 400000000 },
> +                               { 300000000 } },
> +               .reg = { "csiphy1" },
> +               .interrupt = { "csiphy1" }
> +       },
> +       /* CSIPHY2 */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "csiphy2", "csiphy2_timer" },
> +               .clock_rate = { { 400000000 },
> +                               { 300000000 } },
> +               .reg = { "csiphy2" },
> +               .interrupt = { "csiphy2" }
> +       },
> +       /* CSIPHY3 */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "csiphy3", "csiphy3_timer" },
> +               .clock_rate = { { 400000000 },
> +                               { 300000000 } },
> +               .reg = { "csiphy3" },
> +               .interrupt = { "csiphy3" }
> +       },
> +       /* CSIPHY4 */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "csiphy4", "csiphy4_timer" },
> +               .clock_rate = { { 400000000 },
> +                               { 300000000 } },
> +               .reg = { "csiphy4" },
> +               .interrupt = { "csiphy4" }
> +       },
> +       /* CSIPHY5 */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "csiphy5", "csiphy5_timer" },
> +               .clock_rate = { { 400000000 },
> +                               { 300000000 } },
> +               .reg = { "csiphy5" },
> +               .interrupt = { "csiphy5" }
> +       }
> +};
> +
> +static const struct resources csid_res_8250[] = {
> +       /* CSID0 */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_areg", "vfe0_ahb" },
> +               .clock_rate = { { 400000000 },
> +                               { 400000000 },
> +                               { 350000000, 475000000, 576000000, 720000000 },
> +                               { 100000000, 200000000, 300000000, 400000000 },
> +                               { 0 } },
> +               .reg = { "csid0" },
> +               .interrupt = { "csid0" }
> +       },
> +       /* CSID1 */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_areg", "vfe1_ahb" },
> +               .clock_rate = { { 400000000 },
> +                               { 400000000 },
> +                               { 350000000, 475000000, 576000000, 720000000 },
> +                               { 100000000, 200000000, 300000000, 400000000 },
> +                               { 0 } },
> +               .reg = { "csid1" },
> +               .interrupt = { "csid1" }
> +       },
> +       /* CSID2 */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite",  "vfe_lite_ahb" },
> +               .clock_rate = { { 400000000 },
> +                               { 400000000 },
> +                               { 400000000, 480000000 },
> +                               { 0 } },
> +               .reg = { "csid2" },
> +               .interrupt = { "csid2" }
> +       },
> +       /* CSID3 */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx", "vfe_lite",  "vfe_lite_ahb" },
> +               .clock_rate = { { 400000000 },
> +                               { 400000000 },
> +                               { 400000000, 480000000 },
> +                               { 0 } },
> +               .reg = { "csid3" },
> +               .interrupt = { "csid3" }
> +       }
> +};
> +
> +static const struct resources vfe_res_8250[] = {
> +       /* VFE0 */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "camnoc_axi", "vfe0_ahb", "vfe0_areg", "vfe0", "vfe0_axi", "cam_hf_axi" },
> +               .clock_rate = { { 400000000, 480000000 },
> +                               { 0 },
> +                               { 100000000, 200000000, 300000000, 400000000 },
> +                               { 350000000, 475000000, 576000000, 720000000 },
> +                               { 0 },
> +                               { 0 } },
> +               .reg = { "vfe0" },
> +               .interrupt = { "vfe0" }
> +       },
> +       /* VFE1 */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "camnoc_axi", "vfe1_ahb", "vfe1_areg", "vfe1", "vfe1_axi", "cam_hf_axi" },
> +               .clock_rate = { { 400000000, 480000000 },
> +                               { 0 },
> +                               { 100000000, 200000000, 300000000, 400000000 },
> +                               { 350000000, 475000000, 576000000, 720000000 },
> +                               { 0 },
> +                               { 0 } },
> +               .reg = { "vfe1" },
> +               .interrupt = { "vfe1" }
> +       },
> +       /* VFE2 (lite) */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi", "vfe_lite", "cam_hf_axi" },
> +               .clock_rate = { { 400000000, 480000000 },
> +                               { 0 },
> +                               { 0 },
> +                               { 400000000, 480000000 },
> +                               { 0 } },
> +               .reg = { "vfe_lite0" },
> +               .interrupt = { "vfe_lite0" }
> +       },
> +       /* VFE3 (lite) */
> +       {
> +               .regulator = { NULL },
> +               .clock = { "camnoc_axi", "vfe_lite_ahb", "vfe_lite_axi", "vfe_lite", "cam_hf_axi" },
> +               .clock_rate = { { 400000000, 480000000 },
> +                               { 0 },
> +                               { 0 },
> +                               { 400000000, 480000000 },
> +                               { 0 } },
> +               .reg = { "vfe_lite1" },
> +               .interrupt = { "vfe_lite1" }
> +       },
> +};
> +
>  /*
>   * camss_add_clock_margin - Add margin to clock frequency rate
>   * @rate: Clock frequency rate
> @@ -945,6 +1104,12 @@ static int camss_init_subdevices(struct camss *camss)
>                 /* Titan VFEs don't have an ISPIF  */
>                 ispif_res = NULL;
>                 vfe_res = vfe_res_845;
> +       } else if (camss->version == CAMSS_8250) {
> +               csiphy_res = csiphy_res_8250;
> +               csid_res = csid_res_8250;
> +               /* Titan VFEs don't have an ISPIF  */
> +               ispif_res = NULL;
> +               vfe_res = vfe_res_8250;
>         } else {
>                 return -EINVAL;
>         }
> @@ -960,6 +1125,17 @@ static int camss_init_subdevices(struct camss *camss)
>                 }
>         }
>
> +       /* note: SM8250 requires VFE to be initialized before CSID */
> +       for (i = 0; i < camss->vfe_num; i++) {
> +               ret = msm_vfe_subdev_init(camss, &camss->vfe[i],
> +                                         &vfe_res[i], i);
> +               if (ret < 0) {
> +                       dev_err(camss->dev,
> +                               "Fail to init vfe%d sub-device: %d\n", i, ret);
> +                       return ret;
> +               }
> +       }
> +
>         for (i = 0; i < camss->csid_num; i++) {
>                 ret = msm_csid_subdev_init(camss, &camss->csid[i],
>                                            &csid_res[i], i);
> @@ -978,16 +1154,6 @@ static int camss_init_subdevices(struct camss *camss)
>                 return ret;
>         }
>
> -       for (i = 0; i < camss->vfe_num; i++) {
> -               ret = msm_vfe_subdev_init(camss, &camss->vfe[i],
> -                                         &vfe_res[i], i);
> -               if (ret < 0) {
> -                       dev_err(camss->dev,
> -                               "Fail to init vfe%d sub-device: %d\n", i, ret);
> -                       return ret;
> -               }
> -       }
> -
>         return 0;
>  }
>
> @@ -1250,7 +1416,8 @@ static int camss_configure_pd(struct camss *camss)
>         if (camss->version == CAMSS_8x96 ||
>             camss->version == CAMSS_660)
>                 nbr_pm_domains = PM_DOMAIN_GEN1_COUNT;
> -       else if (camss->version == CAMSS_845)
> +       else if (camss->version == CAMSS_845 ||
> +                camss->version == CAMSS_8250)
>                 nbr_pm_domains = PM_DOMAIN_GEN2_COUNT;
>
>         for (i = 0; i < nbr_pm_domains; i++) {
> @@ -1326,6 +1493,12 @@ static int camss_probe(struct platform_device *pdev)
>                 camss->csiphy_num = 4;
>                 camss->csid_num = 3;
>                 camss->vfe_num = 3;
> +       } else if (of_device_is_compatible(dev->of_node,
> +                                          "qcom,sm8250-camss")) {
> +               camss->version = CAMSS_8250;
> +               camss->csiphy_num = 6;
> +               camss->csid_num = 4;
> +               camss->vfe_num = 4;
>         } else {
>                 ret = -EINVAL;
>                 goto err_free;
> @@ -1457,7 +1630,8 @@ void camss_delete(struct camss *camss)
>         if (camss->version == CAMSS_8x96 ||
>             camss->version == CAMSS_660)
>                 nbr_pm_domains = PM_DOMAIN_GEN1_COUNT;
> -       else if (camss->version == CAMSS_845)
> +       else if (camss->version == CAMSS_845 ||
> +                camss->version == CAMSS_8250)
>                 nbr_pm_domains = PM_DOMAIN_GEN2_COUNT;
>
>         for (i = 0; i < nbr_pm_domains; i++) {
> @@ -1493,6 +1667,7 @@ static const struct of_device_id camss_dt_match[] = {
>         { .compatible = "qcom,msm8996-camss" },
>         { .compatible = "qcom,sdm660-camss" },
>         { .compatible = "qcom,sdm845-camss" },
> +       { .compatible = "qcom,sm8250-camss" },
>         { }
>  };
>

This patch does not seem to apply on upstream-media/master.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 12/17] media: camss: remove some vfe ops and clean up dead vfe-170 code
  2021-06-08 22:35 ` [PATCH 12/17] media: camss: remove some vfe ops and clean up dead vfe-170 code Jonathan Marek
  2021-06-09  3:23   ` kernel test robot
  2021-06-10  5:23   ` kernel test robot
@ 2021-06-10 12:37   ` Robert Foss
  2 siblings, 0 replies; 28+ messages in thread
From: Robert Foss @ 2021-06-10 12:37 UTC (permalink / raw)
  To: Jonathan Marek
  Cc: MSM, Andrey Konovalov, Todor Tomov, Andy Gross, Bjorn Andersson,
	Mauro Carvalho Chehab,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER, open list

Hey Jonathan,

On Wed, 9 Jun 2021 at 00:38, Jonathan Marek <jonathan@marek.ca> wrote:
>
> Delete vfe_isr_ops. In all cases the right function can just be called
> directly.
>
> From vfe_hw_ops:
>  - enable_irq_common is completely dead
>  - isr_read/violation_read dont need ops (call right function directly)
>  - reg_update/reg_update_clear moved to gen1 ops, vfe-170 can call the
>    right function directly
>
> This reveals dead function in vfe-170 which are deleted. comp_done IRQ
> handling is also removed for vfe-170 - only RDI is supported.
>
> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> ---
>  .../media/platform/qcom/camss/camss-vfe-170.c | 89 ++----------------
>  .../media/platform/qcom/camss/camss-vfe-4-1.c | 25 +++--
>  .../media/platform/qcom/camss/camss-vfe-4-7.c | 63 ++++++-------
>  .../media/platform/qcom/camss/camss-vfe-4-8.c | 65 ++++++-------
>  .../platform/qcom/camss/camss-vfe-gen1.c      | 94 ++++++++++---------
>  .../platform/qcom/camss/camss-vfe-gen1.h      | 39 +++++++-
>  drivers/media/platform/qcom/camss/camss-vfe.c | 16 ----
>  drivers/media/platform/qcom/camss/camss-vfe.h | 16 ----
>  8 files changed, 169 insertions(+), 238 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c
> index 8594d275b41d1..1de793b218194 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe-170.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c
> @@ -188,20 +188,6 @@ static void vfe_hw_version_read(struct vfe_device *vfe, struct device *dev)
>         dev_err(dev, "VFE HW Version = %u.%u.%u\n", gen, rev, step);
>  }
>
> -static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits)
> -{
> -       u32 bits = readl_relaxed(vfe->base + reg);
> -
> -       writel_relaxed(bits & ~clr_bits, vfe->base + reg);
> -}
> -
> -static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits)
> -{
> -       u32 bits = readl_relaxed(vfe->base + reg);
> -
> -       writel_relaxed(bits | set_bits, vfe->base + reg);
> -}
> -
>  static void vfe_global_reset(struct vfe_device *vfe)
>  {
>         u32 reset_bits = GLOBAL_RESET_CMD_CORE          |
> @@ -305,38 +291,16 @@ static inline void vfe_reg_update_clear(struct vfe_device *vfe,
>
>  static void vfe_enable_irq_common(struct vfe_device *vfe)
>  {
> -       vfe_reg_set(vfe, VFE_IRQ_MASK_0, ~0u);
> -       vfe_reg_set(vfe, VFE_IRQ_MASK_1, ~0u);
> +       writel_relaxed(~0u, vfe->base + VFE_IRQ_MASK_0);
> +       writel_relaxed(~0u, vfe->base + VFE_IRQ_MASK_1);
>
>         writel_relaxed(~0u, vfe->base + VFE_BUS_IRQ_MASK(0));
>         writel_relaxed(~0u, vfe->base + VFE_BUS_IRQ_MASK(1));
>         writel_relaxed(~0u, vfe->base + VFE_BUS_IRQ_MASK(2));
>  }
>
> -static void vfe_isr_halt_ack(struct vfe_device *vfe)
> -{
> -       complete(&vfe->halt_complete);
> -}
> -
> -static void vfe_isr_read(struct vfe_device *vfe, u32 *status0, u32 *status1)
> -{
> -       *status0 = readl_relaxed(vfe->base + VFE_IRQ_STATUS_0);
> -       *status1 = readl_relaxed(vfe->base + VFE_IRQ_STATUS_1);
> -
> -       writel_relaxed(*status0, vfe->base + VFE_IRQ_CLEAR_0);
> -       writel_relaxed(*status1, vfe->base + VFE_IRQ_CLEAR_1);
> -
> -       /* Enforce ordering between IRQ Clear and Global IRQ Clear */
> -       wmb();
> -       writel_relaxed(CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD);
> -}
> -
> -static void vfe_violation_read(struct vfe_device *vfe)
> -{
> -       u32 violation = readl_relaxed(vfe->base + VFE_VIOLATION_STATUS);
> -
> -       pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
> -}
> +static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id);
> +static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm);
>
>  /*
>   * vfe_isr - VFE module interrupt handler
> @@ -369,24 +333,16 @@ static irqreturn_t vfe_isr(int irq, void *dev)
>         writel_relaxed(1, vfe->base + VFE_BUS_IRQ_CLEAR_GLOBAL);
>
>         if (status0 & STATUS_0_RESET_ACK)
> -               vfe->isr_ops.reset_ack(vfe);
> +               vfe_isr_reset_ack(vfe);
>
>         for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
>                 if (status0 & STATUS_0_RDI_REG_UPDATE(i))
> -                       vfe->isr_ops.reg_update(vfe, i);
> -
> -       for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
> -               if (status0 & STATUS_1_RDI_SOF(i))
> -                       vfe->isr_ops.sof(vfe, i);
> -
> -       for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
> -               if (vfe_bus_status[0] & STATUS0_COMP_BUF_DONE(i))
> -                       vfe->isr_ops.comp_done(vfe, i);
> +                       vfe_isr_reg_update(vfe, i);
>
>         for (wm = 0; wm < MSM_VFE_IMAGE_MASTERS_NUM; wm++)
>                 if (status0 & BIT(9))
>                         if (vfe_bus_status[1] & STATUS1_WM_CLIENT_BUF_DONE(wm))
> -                               vfe->isr_ops.wm_done(vfe, wm);
> +                               vfe_isr_wm_done(vfe, wm);
>
>         return IRQ_HANDLED;
>  }
> @@ -456,7 +412,6 @@ static int vfe_enable_output(struct vfe_line *line)
>  {
>         struct vfe_device *vfe = to_vfe(line);
>         struct vfe_output *output = &line->output;
> -       const struct vfe_hw_ops *ops = vfe->ops;
>         struct media_entity *sensor;
>         unsigned long flags;
>         unsigned int frame_skip = 0;
> @@ -474,7 +429,7 @@ static int vfe_enable_output(struct vfe_line *line)
>
>         spin_lock_irqsave(&vfe->output_lock, flags);
>
> -       ops->reg_update_clear(vfe, line->id);
> +       vfe_reg_update_clear(vfe, line->id);
>
>         if (output->state != VFE_OUTPUT_OFF) {
>                 dev_err(vfe->camss->dev, "Output is not in reserved state %d\n",
> @@ -501,7 +456,7 @@ static int vfe_enable_output(struct vfe_line *line)
>                 vfe_wm_update(vfe, output->wm_idx[0], output->buf[i]->addr[0], line);
>         }
>
> -       ops->reg_update(vfe, line->id);
> +       vfe_reg_update(vfe, line->id);
>
>         spin_unlock_irqrestore(&vfe->output_lock, flags);
>
> @@ -607,16 +562,6 @@ static int vfe_disable(struct vfe_line *line)
>         return 0;
>  }
>
> -/*
> - * vfe_isr_sof - Process start of frame interrupt
> - * @vfe: VFE Device
> - * @line_id: VFE line
> - */
> -static void vfe_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id)
> -{
> -       /* nop */
> -}
> -
>  /*
>   * vfe_isr_reg_update - Process reg update interrupt
>   * @vfe: VFE Device
> @@ -628,7 +573,7 @@ static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
>         unsigned long flags;
>
>         spin_lock_irqsave(&vfe->output_lock, flags);
> -       vfe->ops->reg_update_clear(vfe, line_id);
> +       vfe_reg_update_clear(vfe, line_id);
>
>         output = &vfe->line[line_id].output;
>
> @@ -747,15 +692,6 @@ static int vfe_queue_buffer(struct camss_video *vid,
>         return 0;
>  }
>
> -static const struct vfe_isr_ops vfe_isr_ops_170 = {
> -       .reset_ack = vfe_isr_reset_ack,
> -       .halt_ack = vfe_isr_halt_ack,
> -       .reg_update = vfe_isr_reg_update,
> -       .sof = vfe_isr_sof,
> -       .comp_done = vfe_isr_comp_done,
> -       .wm_done = vfe_isr_wm_done,
> -};
> -
>  static const struct camss_video_ops vfe_video_ops_170 = {
>         .queue_buffer = vfe_queue_buffer,
>         .flush_buffers = vfe_flush_buffers,
> @@ -763,7 +699,6 @@ static const struct camss_video_ops vfe_video_ops_170 = {
>
>  static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
>  {
> -       vfe->isr_ops = vfe_isr_ops_170;
>         vfe->video_ops = vfe_video_ops_170;
>
>         vfe->line_num = VFE_LINE_NUM_GEN2;
> @@ -772,15 +707,11 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
>  const struct vfe_hw_ops vfe_ops_170 = {
>         .global_reset = vfe_global_reset,
>         .hw_version_read = vfe_hw_version_read,
> -       .isr_read = vfe_isr_read,
>         .isr = vfe_isr,
>         .pm_domain_off = vfe_pm_domain_off,
>         .pm_domain_on = vfe_pm_domain_on,
> -       .reg_update_clear = vfe_reg_update_clear,
> -       .reg_update = vfe_reg_update,
>         .subdev_init = vfe_subdev_init,
>         .vfe_disable = vfe_disable,
>         .vfe_enable = vfe_enable,
>         .vfe_halt = vfe_halt,
> -       .violation_read = vfe_violation_read,
>  };
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
> index 53c56a8d45458..873f348cf2fae 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
> @@ -898,34 +898,34 @@ static irqreturn_t vfe_isr(int irq, void *dev)
>         u32 value0, value1;
>         int i, j;
>
> -       vfe->ops->isr_read(vfe, &value0, &value1);
> +       vfe_isr_read(vfe, &value0, &value1);
>
>         dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
>                 value0, value1);
>
>         if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)
> -               vfe->isr_ops.reset_ack(vfe);
> +               vfe_isr_reset_ack(vfe);
>
>         if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
> -               vfe->ops->violation_read(vfe);
> +               vfe_violation_read(vfe);
>
>         if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
> -               vfe->isr_ops.halt_ack(vfe);
> +               vfe_gen1_isr_halt_ack(vfe);
>
>         for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++)
>                 if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
> -                       vfe->isr_ops.reg_update(vfe, i);
> +                       vfe_gen1_reg_update(vfe, i);
>
>         if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)
> -               vfe->isr_ops.sof(vfe, VFE_LINE_PIX);
> +               vfe_gen1_isr_sof(vfe, VFE_LINE_PIX);
>
>         for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
>                 if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))
> -                       vfe->isr_ops.sof(vfe, i);
> +                       vfe_gen1_isr_sof(vfe, i);
>
>         for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
>                 if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {
> -                       vfe->isr_ops.comp_done(vfe, i);
> +                       vfe_gen1_isr_comp_done(vfe, i);
>                         for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)
>                                 if (vfe->wm_output_map[j] == VFE_LINE_PIX)
>                                         value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);
> @@ -933,7 +933,7 @@ static irqreturn_t vfe_isr(int irq, void *dev)
>
>         for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)
>                 if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))
> -                       vfe->isr_ops.wm_done(vfe, i);
> +                       vfe_gen1_isr_wm_done(vfe, i);
>
>         return IRQ_HANDLED;
>  }
> @@ -991,11 +991,12 @@ static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_1 = {
>         .wm_set_pong_addr = vfe_wm_set_pong_addr,
>         .wm_set_subsample = vfe_wm_set_subsample,
>         .wm_set_ub_cfg = vfe_wm_set_ub_cfg,
> +       .reg_update_clear = vfe_reg_update_clear,
> +       .reg_update = vfe_reg_update,
>  };
>
>  static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
>  {
> -       vfe->isr_ops = vfe_isr_ops_gen1;
>         vfe->ops_gen1 = &vfe_ops_gen1_4_1;
>         vfe->video_ops = vfe_video_ops_gen1;
>
> @@ -1005,15 +1006,11 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
>  const struct vfe_hw_ops vfe_ops_4_1 = {
>         .global_reset = vfe_global_reset,
>         .hw_version_read = vfe_hw_version_read,
> -       .isr_read = vfe_isr_read,
>         .isr = vfe_isr,
>         .pm_domain_off = vfe_pm_domain_off,
>         .pm_domain_on = vfe_pm_domain_on,
> -       .reg_update_clear = vfe_reg_update_clear,
> -       .reg_update = vfe_reg_update,
>         .subdev_init = vfe_subdev_init,
>         .vfe_disable = vfe_gen1_disable,
>         .vfe_enable = vfe_gen1_enable,
>         .vfe_halt = vfe_gen1_halt,
> -       .violation_read = vfe_violation_read,
>  };
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
> index a596352177583..35178f66360eb 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
> @@ -1037,7 +1037,25 @@ static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev)
>         return ret;
>  }
>
> +static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
> +{
> +       *value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
> +       *value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
>
> +       writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
> +       writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
> +
> +       /* Enforce barrier between local & global IRQ clear */
> +       wmb();
> +       writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
> +}
> +
> +static void vfe_violation_read(struct vfe_device *vfe)
> +{
> +       u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
> +
> +       pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
> +}
>
>  /*
>   * vfe_isr - VFE module interrupt handler
> @@ -1052,34 +1070,34 @@ static irqreturn_t vfe_isr(int irq, void *dev)
>         u32 value0, value1;
>         int i, j;
>
> -       vfe->ops->isr_read(vfe, &value0, &value1);
> +       vfe_isr_read(vfe, &value0, &value1);
>
>         dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
>                 value0, value1);
>
>         if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)
> -               vfe->isr_ops.reset_ack(vfe);
> +               vfe_isr_reset_ack(vfe);
>
>         if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
> -               vfe->ops->violation_read(vfe);
> +               vfe_violation_read(vfe);
>
>         if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
> -               vfe->isr_ops.halt_ack(vfe);
> +               vfe_gen1_isr_halt_ack(vfe);
>
>         for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
>                 if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
> -                       vfe->isr_ops.reg_update(vfe, i);
> +                       vfe_gen1_reg_update(vfe, i);
>
>         if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)
> -               vfe->isr_ops.sof(vfe, VFE_LINE_PIX);
> +               vfe_gen1_isr_sof(vfe, VFE_LINE_PIX);
>
>         for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
>                 if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))
> -                       vfe->isr_ops.sof(vfe, i);
> +                       vfe_gen1_isr_sof(vfe, i);
>
>         for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
>                 if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {
> -                       vfe->isr_ops.comp_done(vfe, i);
> +                       vfe_gen1_isr_comp_done(vfe, i);
>                         for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)
>                                 if (vfe->wm_output_map[j] == VFE_LINE_PIX)
>                                         value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);
> @@ -1087,24 +1105,11 @@ static irqreturn_t vfe_isr(int irq, void *dev)
>
>         for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)
>                 if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))
> -                       vfe->isr_ops.wm_done(vfe, i);
> +                       vfe_gen1_isr_wm_done(vfe, i);
>
>         return IRQ_HANDLED;
>  }
>
> -static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
> -{
> -       *value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
> -       *value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
> -
> -       writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
> -       writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
> -
> -       /* Enforce barrier between local & global IRQ clear */
> -       wmb();
> -       writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
> -}
> -
>  /*
>   * vfe_pm_domain_off - Disable power domains specific to this VFE.
>   * @vfe: VFE Device
> @@ -1141,13 +1146,6 @@ static int vfe_pm_domain_on(struct vfe_device *vfe)
>         return 0;
>  }
>
> -static void vfe_violation_read(struct vfe_device *vfe)
> -{
> -       u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
> -
> -       pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
> -}
> -
>  static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_7 = {
>         .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi,
>         .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi,
> @@ -1183,11 +1181,12 @@ static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_7 = {
>         .wm_set_pong_addr = vfe_wm_set_pong_addr,
>         .wm_set_subsample = vfe_wm_set_subsample,
>         .wm_set_ub_cfg = vfe_wm_set_ub_cfg,
> +       .reg_update_clear = vfe_reg_update_clear,
> +       .reg_update = vfe_reg_update,
>  };
>
>  static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
>  {
> -       vfe->isr_ops = vfe_isr_ops_gen1;
>         vfe->ops_gen1 = &vfe_ops_gen1_4_7;
>         vfe->video_ops = vfe_video_ops_gen1;
>
> @@ -1197,15 +1196,11 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
>  const struct vfe_hw_ops vfe_ops_4_7 = {
>         .global_reset = vfe_global_reset,
>         .hw_version_read = vfe_hw_version_read,
> -       .isr_read = vfe_isr_read,
>         .isr = vfe_isr,
>         .pm_domain_off = vfe_pm_domain_off,
>         .pm_domain_on = vfe_pm_domain_on,
> -       .reg_update_clear = vfe_reg_update_clear,
> -       .reg_update = vfe_reg_update,
>         .subdev_init = vfe_subdev_init,
>         .vfe_disable = vfe_gen1_disable,
>         .vfe_enable = vfe_gen1_enable,
>         .vfe_halt = vfe_gen1_halt,
> -       .violation_read = vfe_violation_read,
>  };
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-8.c b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
> index 998429dbb65cd..d4ddbbf44f514 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
> @@ -968,6 +968,26 @@ static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev)
>         return ret;
>  }
>
> +static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
> +{
> +       *value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
> +       *value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
> +
> +       writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
> +       writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
> +
> +       /* Enforce barrier between local & global IRQ clear */
> +       wmb();
> +       writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
> +}
> +
> +static void vfe_violation_read(struct vfe_device *vfe)
> +{
> +       u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
> +
> +       pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
> +}
> +
>  /*
>   * vfe_isr - VFE module interrupt handler
>   * @irq: Interrupt line
> @@ -981,34 +1001,34 @@ static irqreturn_t vfe_isr(int irq, void *dev)
>         u32 value0, value1;
>         int i, j;
>
> -       vfe->ops->isr_read(vfe, &value0, &value1);
> +       vfe_isr_read(vfe, &value0, &value1);
>
>         dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
>                 value0, value1);
>
>         if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)
> -               vfe->isr_ops.reset_ack(vfe);
> +               vfe_isr_reset_ack(vfe);
>
>         if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
> -               vfe->ops->violation_read(vfe);
> +               vfe_violation_read(vfe);
>
>         if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
> -               vfe->isr_ops.halt_ack(vfe);
> +               vfe_gen1_isr_halt_ack(vfe);
>
>         for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
>                 if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
> -                       vfe->isr_ops.reg_update(vfe, i);
> +                       vfe_gen1_reg_update(vfe, i);
>
>         if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)
> -               vfe->isr_ops.sof(vfe, VFE_LINE_PIX);
> +               vfe_gen1_isr_sof(vfe, VFE_LINE_PIX);
>
>         for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
>                 if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))
> -                       vfe->isr_ops.sof(vfe, i);
> +                       vfe_gen1_isr_sof(vfe, i);
>
>         for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
>                 if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {
> -                       vfe->isr_ops.comp_done(vfe, i);
> +                       vfe_gen1_isr_comp_done(vfe, i);
>                         for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)
>                                 if (vfe->wm_output_map[j] == VFE_LINE_PIX)
>                                         value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);
> @@ -1016,7 +1036,7 @@ static irqreturn_t vfe_isr(int irq, void *dev)
>
>         for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)
>                 if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))
> -                       vfe->isr_ops.wm_done(vfe, i);
> +                       vfe_gen1_isr_wm_done(vfe, i);
>
>         return IRQ_HANDLED;
>  }
> @@ -1081,19 +1101,6 @@ static void vfe_set_ds(struct vfe_device *vfe)
>         writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16);
>  }
>
> -static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
> -{
> -       *value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
> -       *value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
> -
> -       writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
> -       writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
> -
> -       /* Enforce barrier between local & global IRQ clear */
> -       wmb();
> -       writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
> -}
> -
>  /*
>   * vfe_pm_domain_off - Disable power domains specific to this VFE.
>   * @vfe: VFE Device
> @@ -1125,13 +1132,6 @@ static int vfe_pm_domain_on(struct vfe_device *vfe)
>         return 0;
>  }
>
> -static void vfe_violation_read(struct vfe_device *vfe)
> -{
> -       u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
> -
> -       pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
> -}
> -
>  static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_8 = {
>         .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi,
>         .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi,
> @@ -1167,11 +1167,12 @@ static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_8 = {
>         .wm_set_pong_addr = vfe_wm_set_pong_addr,
>         .wm_set_subsample = vfe_wm_set_subsample,
>         .wm_set_ub_cfg = vfe_wm_set_ub_cfg,
> +       .reg_update_clear = vfe_reg_update_clear,
> +       .reg_update = vfe_reg_update,
>  };
>
>  static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
>  {
> -       vfe->isr_ops = vfe_isr_ops_gen1;
>         vfe->ops_gen1 = &vfe_ops_gen1_4_8;
>         vfe->video_ops = vfe_video_ops_gen1;
>
> @@ -1181,15 +1182,11 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
>  const struct vfe_hw_ops vfe_ops_4_8 = {
>         .global_reset = vfe_global_reset,
>         .hw_version_read = vfe_hw_version_read,
> -       .isr_read = vfe_isr_read,
>         .isr = vfe_isr,
>         .pm_domain_off = vfe_pm_domain_off,
>         .pm_domain_on = vfe_pm_domain_on,
> -       .reg_update_clear = vfe_reg_update_clear,
> -       .reg_update = vfe_reg_update,
>         .subdev_init = vfe_subdev_init,
>         .vfe_disable = vfe_gen1_disable,
>         .vfe_enable = vfe_gen1_enable,
>         .vfe_halt = vfe_gen1_halt,
> -       .violation_read = vfe_violation_read,
>  };
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-gen1.c b/drivers/media/platform/qcom/camss/camss-vfe-gen1.c
> index 4fd265d018834..2c0cd14bbdf8e 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe-gen1.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-gen1.c
> @@ -37,7 +37,6 @@ static int vfe_disable_output(struct vfe_line *line)
>  {
>         struct vfe_device *vfe = to_vfe(line);
>         struct vfe_output *output = &line->output;
> -       const struct vfe_hw_ops *ops = vfe->ops;
>         unsigned long flags;
>         unsigned long time;
>         unsigned int i;
> @@ -55,7 +54,7 @@ static int vfe_disable_output(struct vfe_line *line)
>         for (i = 0; i < output->wm_num; i++)
>                 vfe->ops_gen1->wm_enable(vfe, output->wm_idx[i], 0);
>
> -       ops->reg_update(vfe, line->id);
> +       vfe->ops_gen1->reg_update(vfe, line->id);
>         output->wait_reg_update = 1;
>         spin_unlock_irqrestore(&vfe->output_lock, flags);
>
> @@ -162,21 +161,21 @@ static void vfe_output_frame_drop(struct vfe_device *vfe,
>                 vfe->ops_gen1->wm_set_framedrop_pattern(vfe, output->wm_idx[i], drop_pattern);
>         }
>
> -       vfe->ops->reg_update(vfe, container_of(output, struct vfe_line, output)->id);
> +       vfe->ops_gen1->reg_update(vfe, container_of(output, struct vfe_line, output)->id);
>  }
>
>  static int vfe_enable_output(struct vfe_line *line)
>  {
>         struct vfe_device *vfe = to_vfe(line);
>         struct vfe_output *output = &line->output;
> -       const struct vfe_hw_ops *ops = vfe->ops;
> +       const struct vfe_hw_ops_gen1 *ops = vfe->ops_gen1;
>         struct media_entity *sensor;
>         unsigned long flags;
>         unsigned int frame_skip = 0;
>         unsigned int i;
>         u16 ub_size;
>
> -       ub_size = vfe->ops_gen1->get_ub_size(vfe->id);
> +       ub_size = ops->get_ub_size(vfe->id);
>         if (!ub_size)
>                 return -EINVAL;
>
> @@ -236,38 +235,38 @@ static int vfe_enable_output(struct vfe_line *line)
>         vfe_output_init_addrs(vfe, output, 0, line);
>
>         if (line->id != VFE_LINE_PIX) {
> -               vfe->ops_gen1->set_cgc_override(vfe, output->wm_idx[0], 1);
> -               vfe->ops_gen1->enable_irq_wm_line(vfe, output->wm_idx[0], line->id, 1);
> -               vfe->ops_gen1->bus_connect_wm_to_rdi(vfe, output->wm_idx[0], line->id);
> -               vfe->ops_gen1->wm_set_subsample(vfe, output->wm_idx[0]);
> -               vfe->ops_gen1->set_rdi_cid(vfe, line->id, 0);
> -               vfe->ops_gen1->wm_set_ub_cfg(vfe, output->wm_idx[0],
> +               ops->set_cgc_override(vfe, output->wm_idx[0], 1);
> +               ops->enable_irq_wm_line(vfe, output->wm_idx[0], line->id, 1);
> +               ops->bus_connect_wm_to_rdi(vfe, output->wm_idx[0], line->id);
> +               ops->wm_set_subsample(vfe, output->wm_idx[0]);
> +               ops->set_rdi_cid(vfe, line->id, 0);
> +               ops->wm_set_ub_cfg(vfe, output->wm_idx[0],
>                                             (ub_size + 1) * output->wm_idx[0], ub_size);
> -               vfe->ops_gen1->wm_frame_based(vfe, output->wm_idx[0], 1);
> -               vfe->ops_gen1->wm_enable(vfe, output->wm_idx[0], 1);
> -               vfe->ops_gen1->bus_reload_wm(vfe, output->wm_idx[0]);
> +               ops->wm_frame_based(vfe, output->wm_idx[0], 1);
> +               ops->wm_enable(vfe, output->wm_idx[0], 1);
> +               ops->bus_reload_wm(vfe, output->wm_idx[0]);
>         } else {
>                 ub_size /= output->wm_num;
>                 for (i = 0; i < output->wm_num; i++) {
> -                       vfe->ops_gen1->set_cgc_override(vfe, output->wm_idx[i], 1);
> -                       vfe->ops_gen1->wm_set_subsample(vfe, output->wm_idx[i]);
> -                       vfe->ops_gen1->wm_set_ub_cfg(vfe, output->wm_idx[i],
> +                       ops->set_cgc_override(vfe, output->wm_idx[i], 1);
> +                       ops->wm_set_subsample(vfe, output->wm_idx[i]);
> +                       ops->wm_set_ub_cfg(vfe, output->wm_idx[i],
>                                                      (ub_size + 1) * output->wm_idx[i], ub_size);
> -                       vfe->ops_gen1->wm_line_based(vfe, output->wm_idx[i],
> +                       ops->wm_line_based(vfe, output->wm_idx[i],
>                                                      &line->video_out.active_fmt.fmt.pix_mp, i, 1);
> -                       vfe->ops_gen1->wm_enable(vfe, output->wm_idx[i], 1);
> -                       vfe->ops_gen1->bus_reload_wm(vfe, output->wm_idx[i]);
> +                       ops->wm_enable(vfe, output->wm_idx[i], 1);
> +                       ops->bus_reload_wm(vfe, output->wm_idx[i]);
>                 }
> -               vfe->ops_gen1->enable_irq_pix_line(vfe, 0, line->id, 1);
> -               vfe->ops_gen1->set_module_cfg(vfe, 1);
> -               vfe->ops_gen1->set_camif_cfg(vfe, line);
> -               vfe->ops_gen1->set_realign_cfg(vfe, line, 1);
> -               vfe->ops_gen1->set_xbar_cfg(vfe, output, 1);
> -               vfe->ops_gen1->set_demux_cfg(vfe, line);
> -               vfe->ops_gen1->set_scale_cfg(vfe, line);
> -               vfe->ops_gen1->set_crop_cfg(vfe, line);
> -               vfe->ops_gen1->set_clamp_cfg(vfe);
> -               vfe->ops_gen1->set_camif_cmd(vfe, 1);
> +               ops->enable_irq_pix_line(vfe, 0, line->id, 1);
> +               ops->set_module_cfg(vfe, 1);
> +               ops->set_camif_cfg(vfe, line);
> +               ops->set_realign_cfg(vfe, line, 1);
> +               ops->set_xbar_cfg(vfe, output, 1);
> +               ops->set_demux_cfg(vfe, line);
> +               ops->set_scale_cfg(vfe, line);
> +               ops->set_crop_cfg(vfe, line);
> +               ops->set_clamp_cfg(vfe);
> +               ops->set_camif_cmd(vfe, 1);
>         }
>
>         ops->reg_update(vfe, line->id);
> @@ -508,7 +507,7 @@ static void vfe_buf_update_wm_on_new(struct vfe_device *vfe,
>   * vfe_isr_halt_ack - Process halt ack
>   * @vfe: VFE Device
>   */
> -static void vfe_isr_halt_ack(struct vfe_device *vfe)
> +void vfe_gen1_isr_halt_ack(struct vfe_device *vfe)
>  {
>         complete(&vfe->halt_complete);
>         vfe->ops_gen1->halt_clear(vfe);
> @@ -519,7 +518,7 @@ static void vfe_isr_halt_ack(struct vfe_device *vfe)
>   * @vfe: VFE Device
>   * @line_id: VFE line
>   */
> -static void vfe_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id)
> +void vfe_gen1_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id)
>  {
>         struct vfe_output *output;
>         unsigned long flags;
> @@ -538,14 +537,14 @@ static void vfe_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id)
>   * @vfe: VFE Device
>   * @line_id: VFE line
>   */
> -static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
> +void vfe_gen1_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
>  {
>         struct vfe_output *output;
>         struct vfe_line *line = &vfe->line[line_id];
>         unsigned long flags;
>
>         spin_lock_irqsave(&vfe->output_lock, flags);
> -       vfe->ops->reg_update_clear(vfe, line_id);
> +       vfe->ops_gen1->reg_update_clear(vfe, line_id);
>
>         output = &line->output;
>
> @@ -605,7 +604,7 @@ static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
>   * @vfe: VFE Device
>   * @wm: Write master id
>   */
> -static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm)
> +void vfe_gen1_isr_wm_done(struct vfe_device *vfe, u8 wm)
>  {
>         struct camss_buffer *ready_buf;
>         struct vfe_output *output;
> @@ -675,6 +674,22 @@ static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm)
>         spin_unlock_irqrestore(&vfe->output_lock, flags);
>  }
>
> +/**
> + * vfe_isr_comp_done() - Process composite image done interrupt
> + * @vfe: VFE Device
> + * @comp: Composite image id
> + */
> +void vfe_gen1_isr_comp_done(struct vfe_device *vfe, u8 comp)
> +{
> +       unsigned int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
> +               if (vfe->wm_output_map[i] == VFE_LINE_PIX) {
> +                       vfe_gen1_isr_wm_done(vfe, i);
> +                       break;
> +               }
> +}
> +
>  /*
>   * vfe_queue_buffer - Add empty buffer
>   * @vid: Video device structure
> @@ -727,15 +742,6 @@ int vfe_word_per_line(u32 format, u32 width)
>         return val;
>  }
>
> -const struct vfe_isr_ops vfe_isr_ops_gen1 = {
> -       .reset_ack = vfe_isr_reset_ack,
> -       .halt_ack = vfe_isr_halt_ack,
> -       .reg_update = vfe_isr_reg_update,
> -       .sof = vfe_isr_sof,
> -       .comp_done = vfe_isr_comp_done,
> -       .wm_done = vfe_isr_wm_done,
> -};
> -
>  const struct camss_video_ops vfe_video_ops_gen1 = {
>         .queue_buffer = vfe_queue_buffer,
>         .flush_buffers = vfe_flush_buffers,
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-gen1.h b/drivers/media/platform/qcom/camss/camss-vfe-gen1.h
> index 6d5f9656562c8..2619df66aa713 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe-gen1.h
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-gen1.h
> @@ -55,6 +55,9 @@ struct vfe_hw_ops_gen1 {
>         void (*wm_set_pong_addr)(struct vfe_device *vfe, u8 wm, u32 addr);
>         int (*wm_get_ping_pong_status)(struct vfe_device *vfe, u8 wm);
>         void (*wm_enable)(struct vfe_device *vfe, u8 wm, u8 enable);
> +       void (*reg_update)(struct vfe_device *vfe, enum vfe_line_id line_id);
> +       void (*reg_update_clear)(struct vfe_device *vfe,
> +                                enum vfe_line_id line_id);
>  };
>
>  /*
> @@ -95,13 +98,47 @@ int vfe_gen1_disable(struct vfe_line *line);
>  int vfe_gen1_enable(struct vfe_line *line);
>
>  /*
> - * vfe_gen1_enable - Halt VFE module
> + * vfe_gen1_halt - Halt VFE module
>   * @vfe: VFE device
>   *
>   * Return 0 on success
>   */
>  int vfe_gen1_halt(struct vfe_device *vfe);
>
> +/*
> + * vfe_gen1_isr_halt_ack - Process halt ack
> + * @vfe: VFE Device
> + */
> +void vfe_gen1_isr_halt_ack(struct vfe_device *vfe);
> +
> +/*
> + * vfe_gen1_isr_sof - Process start of frame interrupt
> + * @vfe: VFE Device
> + * @line_id: VFE line
> + */
> +void vfe_gen1_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id);
> +
> +/*
> + * vfe_gen1_reg_update - Process reg update interrupt
> + * @vfe: VFE Device
> + * @line_id: VFE line
> + */
> +void vfe_gen1_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id);
> +
> +/*
> + * vfe_gen1_isr_wm_done - Process write master done interrupt
> + * @vfe: VFE Device
> + * @wm: Write master id
> + */
> +void vfe_gen1_isr_wm_done(struct vfe_device *vfe, u8 wm);
> +
> +/**
> + * vfe_gen1_isr_comp_done() - Process composite image done interrupt
> + * @vfe: VFE Device
> + * @comp: Composite image id
> + */
> +void vfe_gen1_isr_comp_done(struct vfe_device *vfe, u8 comp);
> +
>  /*
>   * vfe_word_per_line - Calculate number of words per frame width
>   * @format: V4L2 format
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
> index dec89079c6ae4..3e467034710b9 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
> @@ -405,22 +405,6 @@ int vfe_put_output(struct vfe_line *line)
>         return 0;
>  }
>
> -/**
> - * vfe_isr_comp_done() - Process composite image done interrupt
> - * @vfe: VFE Device
> - * @comp: Composite image id
> - */
> -void vfe_isr_comp_done(struct vfe_device *vfe, u8 comp)
> -{
> -       unsigned int i;
> -
> -       for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++)
> -               if (vfe->wm_output_map[i] == VFE_LINE_PIX) {
> -                       vfe->isr_ops.wm_done(vfe, i);
> -                       break;
> -               }
> -}
> -
>  void vfe_isr_reset_ack(struct vfe_device *vfe)
>  {
>         complete(&vfe->reset_complete);
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
> index 844b9275031d9..97a1361996308 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.h
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.h
> @@ -101,30 +101,15 @@ struct vfe_line {
>  struct vfe_device;
>
>  struct vfe_hw_ops {
> -       void (*enable_irq_common)(struct vfe_device *vfe);
>         void (*global_reset)(struct vfe_device *vfe);
>         void (*hw_version_read)(struct vfe_device *vfe, struct device *dev);
>         irqreturn_t (*isr)(int irq, void *dev);
> -       void (*isr_read)(struct vfe_device *vfe, u32 *value0, u32 *value1);
>         void (*pm_domain_off)(struct vfe_device *vfe);
>         int (*pm_domain_on)(struct vfe_device *vfe);
> -       void (*reg_update)(struct vfe_device *vfe, enum vfe_line_id line_id);
> -       void (*reg_update_clear)(struct vfe_device *vfe,
> -                                enum vfe_line_id line_id);
>         void (*subdev_init)(struct device *dev, struct vfe_device *vfe);
>         int (*vfe_disable)(struct vfe_line *line);
>         int (*vfe_enable)(struct vfe_line *line);
>         int (*vfe_halt)(struct vfe_device *vfe);
> -       void (*violation_read)(struct vfe_device *vfe);
> -};
> -
> -struct vfe_isr_ops {
> -       void (*reset_ack)(struct vfe_device *vfe);
> -       void (*halt_ack)(struct vfe_device *vfe);
> -       void (*reg_update)(struct vfe_device *vfe, enum vfe_line_id line_id);
> -       void (*sof)(struct vfe_device *vfe, enum vfe_line_id line_id);
> -       void (*comp_done)(struct vfe_device *vfe, u8 comp);
> -       void (*wm_done)(struct vfe_device *vfe, u8 wm);
>  };
>
>  struct vfe_device {
> @@ -149,7 +134,6 @@ struct vfe_device {
>         u8 was_streaming;
>         const struct vfe_hw_ops *ops;
>         const struct vfe_hw_ops_gen1 *ops_gen1;
> -       struct vfe_isr_ops isr_ops;
>         struct camss_video_ops video_ops;
>  };
>

With the kernel test robot complaint fixed, I'm happy with this patch.

Reviewed-by: Robert Foss <robert.foss@linaro.org>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 14/17] media: camss: Add initial support for VFE hardware version Titan 480
  2021-06-08 22:35 ` [PATCH 14/17] media: camss: Add initial support for VFE hardware version Titan 480 Jonathan Marek
@ 2021-06-10 12:40   ` Robert Foss
  0 siblings, 0 replies; 28+ messages in thread
From: Robert Foss @ 2021-06-10 12:40 UTC (permalink / raw)
  To: Jonathan Marek
  Cc: MSM, Andrey Konovalov, Todor Tomov, Andy Gross, Bjorn Andersson,
	Mauro Carvalho Chehab, open list,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER

Hey Jonathan,

This patch has some checkpatch --strict warnings.

On Wed, 9 Jun 2021 at 00:38, Jonathan Marek <jonathan@marek.ca> wrote:
>
> Add support for VFE found on SM8250 (Titan 480). This implementation is
> based on the titan 170 implementation. It supports the normal and lite VFE,
> and only supports the RDI0 capture path.
>
> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> ---
>  drivers/media/platform/qcom/camss/Makefile    |   1 +
>  .../media/platform/qcom/camss/camss-vfe-480.c | 545 ++++++++++++++++++
>  drivers/media/platform/qcom/camss/camss-vfe.h |   1 +
>  3 files changed, 547 insertions(+)
>  create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-480.c
>
> diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
> index 0752c46ea37b5..81dd56aff0f27 100644
> --- a/drivers/media/platform/qcom/camss/Makefile
> +++ b/drivers/media/platform/qcom/camss/Makefile
> @@ -15,6 +15,7 @@ qcom-camss-objs += \
>                 camss-vfe-4-7.o \
>                 camss-vfe-4-8.o \
>                 camss-vfe-170.o \
> +               camss-vfe-480.o \
>                 camss-vfe-gen1.o \
>                 camss-vfe.o \
>                 camss-video.o \
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-480.c b/drivers/media/platform/qcom/camss/camss-vfe-480.c
> new file mode 100644
> index 0000000000000..6e6a4caee0a96
> --- /dev/null
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-480.c
> @@ -0,0 +1,545 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * camss-vfe-480.c
> + *
> + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v480 (SM8250)
> + *
> + * Copyright (C) 2020-2021 Linaro Ltd.
> + * Copyright (C) 2021 Jonathan Marek
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +
> +#include "camss.h"
> +#include "camss-vfe.h"
> +
> +/* VFE 2/3 are lite and have a different register layout */
> +#define IS_LITE                (vfe->id >= 2 ? 1 : 0)
> +
> +#define VFE_HW_VERSION                 (0x00)
> +
> +#define VFE_GLOBAL_RESET_CMD           (IS_LITE ? 0x0c : 0x1c)
> +#define            GLOBAL_RESET_HW_AND_REG     (IS_LITE ? BIT(1) : BIT(0))
> +
> +#define VFE_REG_UPDATE_CMD             (IS_LITE ? 0x20 : 0x34)
> +#define            REG_UPDATE_RDI(n)           (IS_LITE ? BIT(n) : BIT(1 + (n)))
> +#define VFE_IRQ_CMD                    (IS_LITE ? 0x24 : 0x38)
> +#define     IRQ_CMD_GLOBAL_CLEAR       BIT(0)
> +
> +#define VFE_IRQ_MASK(n)                        ((IS_LITE ? 0x28 : 0x3c) + (n) * 4)
> +#define            IRQ_MASK_0_RESET_ACK        (IS_LITE ? BIT(17) : BIT(0))
> +#define            IRQ_MASK_0_BUS_TOP_IRQ      (IS_LITE ? BIT(4) : BIT(7))
> +#define VFE_IRQ_CLEAR(n)               ((IS_LITE ? 0x34 : 0x48) + (n) * 4)
> +#define VFE_IRQ_STATUS(n)              ((IS_LITE ? 0x40 : 0x54) + (n) * 4)
> +
> +#define BUS_REG_BASE                   (IS_LITE ? 0x1a00 : 0xaa00)
> +
> +#define VFE_BUS_WM_CGC_OVERRIDE                (BUS_REG_BASE + 0x08)
> +#define                WM_CGC_OVERRIDE_ALL     (0x3FFFFFF)
> +
> +#define VFE_BUS_WM_TEST_BUS_CTRL       (BUS_REG_BASE + 0xdc)
> +
> +#define VFE_BUS_IRQ_MASK(n)            (BUS_REG_BASE + 0x18 + (n) * 4)
> +#define     BUS_IRQ_MASK_0_RDI_RUP(n)  (IS_LITE ? BIT(n) : BIT(3 + (n)))
> +#define     BUS_IRQ_MASK_0_COMP_DONE(n)        (IS_LITE ? BIT(4 + (n)) : BIT(6 + (n)))
> +#define VFE_BUS_IRQ_CLEAR(n)           (BUS_REG_BASE + 0x20 + (n) * 4)
> +#define VFE_BUS_IRQ_STATUS(n)          (BUS_REG_BASE + 0x28 + (n) * 4)
> +#define VFE_BUS_IRQ_CLEAR_GLOBAL       (BUS_REG_BASE + 0x30)
> +
> +#define VFE_BUS_WM_CFG(n)              (BUS_REG_BASE + 0x200 + (n) * 0x100)
> +#define                WM_CFG_EN                       (0)
> +#define                WM_CFG_MODE                     (16)

Is there an extra tab here                        ^^^

> +#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 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_SYSTEM_CACHE_CFG(n) (BUS_REG_BASE + 0x260 + (n) * 0x100)
> +#define VFE_BUS_WM_BURST_LIMIT(n)      (BUS_REG_BASE + 0x264 + (n) * 0x100)
> +
> +/* for titan 480, each bus client is hardcoded to a specific path
> + * and each bus client is part of a hardcoded "comp group"
> + */
> +#define RDI_WM(n)                      ((IS_LITE ? 0 : 23) + (n))
> +#define RDI_COMP_GROUP(n)              ((IS_LITE ? 0 : 11) + (n))
> +
> +static void vfe_hw_version_read(struct vfe_device *vfe, struct device *dev)
> +{
> +       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_dbg(dev, "VFE HW Version = %u.%u.%u\n", gen, rev, step);
> +}
> +
> +static void vfe_global_reset(struct vfe_device *vfe)
> +{
> +       writel_relaxed(IRQ_MASK_0_RESET_ACK, vfe->base + VFE_IRQ_MASK(0));
> +       writel_relaxed(GLOBAL_RESET_HW_AND_REG, vfe->base + VFE_GLOBAL_RESET_CMD);
> +}
> +
> +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(WM_CGC_OVERRIDE_ALL, vfe->base + VFE_BUS_WM_CGC_OVERRIDE);
> +
> +       writel_relaxed(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL);
> +
> +       writel_relaxed(pix->plane_fmt[0].bytesperline * pix->height,
> +                      vfe->base + VFE_BUS_WM_FRAME_INCR(wm));
> +       writel_relaxed(0xf, vfe->base + VFE_BUS_WM_BURST_LIMIT(wm));
> +       writel_relaxed(WM_IMAGE_CFG_0_DEFAULT_WIDTH,
> +                      vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm));
> +       writel_relaxed(pix->plane_fmt[0].bytesperline,
> +                      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 << 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, u32 addr,
> +                         struct vfe_line *line)
> +{
> +       wm = RDI_WM(wm); /* map to actual WM used (from wm=RDI index) */
> +       writel_relaxed(addr, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
> +}
> +
> +static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> +       vfe->reg_update |= REG_UPDATE_RDI(line_id);
> +       writel_relaxed(vfe->reg_update, vfe->base + VFE_REG_UPDATE_CMD);
> +}
> +
> +static inline void vfe_reg_update_clear(struct vfe_device *vfe,
> +                                       enum vfe_line_id line_id)
> +{
> +       vfe->reg_update &= ~REG_UPDATE_RDI(line_id);
> +}
> +
> +static void vfe_enable_irq_common(struct vfe_device *vfe)
> +{
> +       /* enable only the IRQs used: rup and comp_done irqs for RDI0 */
> +       writel_relaxed(IRQ_MASK_0_RESET_ACK | IRQ_MASK_0_BUS_TOP_IRQ,
> +                      vfe->base + VFE_IRQ_MASK(0));
> +       writel_relaxed(BUS_IRQ_MASK_0_RDI_RUP(0) | BUS_IRQ_MASK_0_COMP_DONE(RDI_COMP_GROUP(0)),
> +                      vfe->base + VFE_BUS_IRQ_MASK(0));
> +}
> +
> +static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id);
> +static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm);
> +
> +/*
> + * 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 & IRQ_MASK_0_RESET_ACK)
> +               vfe_isr_reset_ack(vfe);
> +
> +       if (status & IRQ_MASK_0_BUS_TOP_IRQ) {
> +               u32 status = readl_relaxed(vfe->base + VFE_BUS_IRQ_STATUS(0));
> +               writel_relaxed(status, vfe->base + VFE_BUS_IRQ_CLEAR(0));
> +               writel_relaxed(1, vfe->base + VFE_BUS_IRQ_CLEAR_GLOBAL);
> +
> +               if (status & BUS_IRQ_MASK_0_RDI_RUP(0))
> +                       vfe_isr_reg_update(vfe, 0);
> +
> +               if (status & BUS_IRQ_MASK_0_COMP_DONE(RDI_COMP_GROUP(0)))
> +                       vfe_isr_wm_done(vfe, 0);
> +       }
> +
> +       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;
> +       int wm_idx;
> +
> +       spin_lock_irqsave(&vfe->output_lock, flags);
> +
> +       output = &line->output;
> +       if (output->state != VFE_OUTPUT_OFF) {
> +               dev_err(vfe->camss->dev, "Output is running\n");
> +               goto error;
> +       }
> +
> +       output->wm_num = 1;
> +
> +       wm_idx = vfe_reserve_wm(vfe, line->id);
> +       if (wm_idx < 0) {
> +               dev_err(vfe->camss->dev, "Can not reserve wm\n");
> +               goto error_get_wm;
> +       }
> +       output->wm_idx[0] = wm_idx;
> +
> +       output->drop_update_idx = 0;
> +
> +       spin_unlock_irqrestore(&vfe->output_lock, flags);
> +
> +       return 0;
> +
> +error_get_wm:
> +       vfe_release_wm(vfe, output->wm_idx[0]);
> +       output->state = VFE_OUTPUT_OFF;
> +error:
> +       spin_unlock_irqrestore(&vfe->output_lock, flags);
> +
> +       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_OFF) {
> +               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;
> +       output->wait_reg_update = 0;
> +       reinit_completion(&output->reg_update);
> +
> +       vfe_wm_start(vfe, output->wm_idx[0], line);
> +
> +       for (i = 0; i < 2; 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;
> +}
> +
> +static int vfe_disable_output(struct vfe_line *line)
> +{
> +       struct vfe_device *vfe = to_vfe(line);
> +       struct vfe_output *output = &line->output;
> +       unsigned long flags;
> +       unsigned int i;
> +       bool done;
> +       int timeout = 0;
> +
> +       do {
> +               spin_lock_irqsave(&vfe->output_lock, flags);
> +               done = !output->gen2.active_num;
> +               spin_unlock_irqrestore(&vfe->output_lock, flags);
> +               usleep_range(10000, 20000);
> +
> +               if (timeout++ == 100) {
> +                       dev_err(vfe->camss->dev, "VFE idle timeout - resetting\n");
> +                       vfe_reset(vfe);
> +                       output->gen2.active_num = 0;
> +                       return 0;
> +               }
> +       } while (!done);
> +
> +       spin_lock_irqsave(&vfe->output_lock, flags);
> +       for (i = 0; i < output->wm_num; i++)
> +               vfe_wm_stop(vfe, output->wm_idx[i]);
> +       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);
> +
> +       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_disable - Disable streaming on VFE line
> + * @line: VFE line
> + *
> + * Return 0 on success or a negative error code otherwise
> + */
> +static int vfe_disable(struct vfe_line *line)
> +{
> +       struct vfe_device *vfe = to_vfe(line);
> +
> +       vfe_disable_output(line);
> +
> +       vfe_put_output(line);
> +
> +       mutex_lock(&vfe->stream_lock);
> +
> +       vfe->stream_count--;
> +
> +       mutex_unlock(&vfe->stream_lock);
> +
> +       return 0;
> +}
> +
> +/*
> + * vfe_isr_reg_update - Process reg update interrupt
> + * @vfe: VFE Device
> + * @line_id: VFE line
> + */
> +static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> +       struct vfe_output *output;
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&vfe->output_lock, flags);
> +       vfe_reg_update_clear(vfe, line_id);
> +
> +       output = &vfe->line[line_id].output;
> +
> +       if (output->wait_reg_update) {
> +               output->wait_reg_update = 0;
> +               complete(&output->reg_update);
> +       }
> +
> +       spin_unlock_irqrestore(&vfe->output_lock, flags);
> +}
> +
> +/*
> + * vfe_isr_wm_done - Process write master done interrupt
> + * @vfe: VFE Device
> + * @wm: Write master id
> + */
> +static void vfe_isr_wm_done(struct vfe_device *vfe, u8 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);
> +       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_pm_domain_off - Disable power domains specific to this VFE.
> + * @vfe: VFE Device
> + */
> +static void vfe_pm_domain_off(struct vfe_device *vfe)
> +{
> +       /* nop */
> +}
> +
> +/*
> + * vfe_pm_domain_on - Enable power domains specific to this VFE.
> + * @vfe: VFE Device
> + */
> +static int vfe_pm_domain_on(struct vfe_device *vfe)
> +{
> +       return 0;
> +}
> +
> +/*
> + * 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 < 2) {
> +               output->buf[output->gen2.active_num++] = buf;
> +               vfe_wm_update(vfe, output->wm_idx[0], buf->addr[0], line);
> +       } 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_480 = {
> +       .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_480;
> +       vfe->line_num = 1;
> +}
> +
> +const struct vfe_hw_ops vfe_ops_480 = {
> +       .global_reset = vfe_global_reset,
> +       .hw_version_read = vfe_hw_version_read,
> +       .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,
> +};
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
> index 97a1361996308..e80b482885d4a 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.h
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.h
> @@ -185,5 +185,6 @@ extern const struct vfe_hw_ops vfe_ops_4_1;
>  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;
>
>  #endif /* QC_MSM_CAMSS_VFE_H */

With the above issues fixed, this patch looks good.

Reviewed-by: Robert Foss <robert.foss@linaro.org>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 00/17] CAMSS: SM8250 support (and some fixes)
  2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
                   ` (16 preceding siblings ...)
  2021-06-08 22:35 ` [PATCH 17/17] media: dt-bindings: media: camss: Add qcom,sm8250-camss binding Jonathan Marek
@ 2021-06-16 18:16 ` Andrey Konovalov
  17 siblings, 0 replies; 28+ messages in thread
From: Andrey Konovalov @ 2021-06-16 18:16 UTC (permalink / raw)
  To: Jonathan Marek, linux-arm-msm
  Cc: robert.foss, Andy Gross, Bjorn Andersson,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Hans Verkuil, open list,
	open list:QUALCOMM CAMERA SUBSYSTEM DRIVER,
	Mauro Carvalho Chehab, Rob Herring, Todor Tomov

Hi Jonathan,

I've given this patchset a try on RB3 board (SDM845) with ov8856 camera sensor - works OK,
no regressions.

Thanks,
Andrey

On 09.06.2021 01:34, Jonathan Marek wrote:
> This adds initial support for SM8250 and its 4 VFEs and 6 CSIPHYs.
> The only big change is the added camss-vfe-480.c to support the
> Titan 480 VFE.
> 
> v2:
>   - Fixed some typos in commit messages (patches 02 and 08)
>   - patch 03 ("media: camss: csiphy-3ph: add support for SM8250 CSI DPHY"):
>     - moved definition of CAMSS_8250 to this patch,
>     - removed unused lane_enable variable
>     - added a default unreachable case to avoid a warning
>     - added a is_gen2 variable (minor rework)
>   - Undo DECODE_FORMAT_PAYLOAD_ONLY change, add comment instead (patch 04)
>   - "ops" reworks in addition to removing dead code (patch 12)
>   - renamed csid-170 to csid-gen2, added defines for offsets, add missing
>     camnoc_axi clock to sm8250 vfe resources (patch 16/17)
> 
> Jonathan Marek (17):
>    media: camss: csiphy-3ph: don't print HW version as an error
>    media: camss: csiphy-3ph: disable interrupts
>    media: camss: csiphy-3ph: add support for SM8250 CSI DPHY
>    media: camss: csid-170: fix non-10bit formats
>    media: camss: csid-170: don't enable unused irqs
>    media: camss: csid-170: remove stray comment
>    media: camss: csid-170: support more than one lite vfe
>    media: camss: csid-170: set the right HALT_CMD when disabled
>    media: camss: csid: allow csid to work without a regulator
>    media: camss: remove vdda-csiN from sdm845 resources
>    media: camss: fix VFE irq name
>    media: camss: remove some vfe ops and clean up dead vfe-170 code
>    media: camss: vfe-170: fix "VFE halt timeout" error
>    media: camss: Add initial support for VFE hardware version Titan 480
>    media: camss: add support for V4L2_PIX_FMT_GREY for sdm845 HW
>    media: camss: add support for SM8250 camss
>    media: dt-bindings: media: camss: Add qcom,sm8250-camss binding
> 
>   .../bindings/media/qcom,sm8250-camss.yaml     | 399 +++++++++++++
>   drivers/media/platform/qcom/camss/Makefile    |   3 +-
>   .../{camss-csid-170.c => camss-csid-gen2.c}   |  32 +-
>   .../media/platform/qcom/camss/camss-csid.c    |  45 +-
>   .../media/platform/qcom/camss/camss-csid.h    |   2 +-
>   .../qcom/camss/camss-csiphy-3ph-1-0.c         | 184 ++++--
>   .../media/platform/qcom/camss/camss-csiphy.c  |   9 +-
>   .../media/platform/qcom/camss/camss-vfe-170.c | 101 +---
>   .../media/platform/qcom/camss/camss-vfe-4-1.c |  25 +-
>   .../media/platform/qcom/camss/camss-vfe-4-7.c |  63 +-
>   .../media/platform/qcom/camss/camss-vfe-4-8.c |  65 +--
>   .../media/platform/qcom/camss/camss-vfe-480.c | 545 ++++++++++++++++++
>   .../platform/qcom/camss/camss-vfe-gen1.c      |  94 +--
>   .../platform/qcom/camss/camss-vfe-gen1.h      |  39 +-
>   drivers/media/platform/qcom/camss/camss-vfe.c |  29 +-
>   drivers/media/platform/qcom/camss/camss-vfe.h |  17 +-
>   .../media/platform/qcom/camss/camss-video.c   |   5 +-
>   drivers/media/platform/qcom/camss/camss.c     | 205 ++++++-
>   drivers/media/platform/qcom/camss/camss.h     |   1 +
>   19 files changed, 1523 insertions(+), 340 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
>   rename drivers/media/platform/qcom/camss/{camss-csid-170.c => camss-csid-gen2.c} (95%)
>   create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-480.c
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2021-06-16 18:16 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-08 22:34 [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Jonathan Marek
2021-06-08 22:34 ` [PATCH 01/17] media: camss: csiphy-3ph: don't print HW version as an error Jonathan Marek
2021-06-08 22:34 ` [PATCH 02/17] media: camss: csiphy-3ph: disable interrupts Jonathan Marek
2021-06-08 22:34 ` [PATCH 03/17] media: camss: csiphy-3ph: add support for SM8250 CSI DPHY Jonathan Marek
2021-06-08 22:34 ` [PATCH 04/17] media: camss: csid-170: fix non-10bit formats Jonathan Marek
2021-06-08 22:34 ` [PATCH 05/17] media: camss: csid-170: don't enable unused irqs Jonathan Marek
2021-06-08 22:34 ` [PATCH 06/17] media: camss: csid-170: remove stray comment Jonathan Marek
2021-06-08 22:34 ` [PATCH 07/17] media: camss: csid-170: support more than one lite vfe Jonathan Marek
2021-06-08 22:34 ` [PATCH 08/17] media: camss: csid-170: set the right HALT_CMD when disabled Jonathan Marek
2021-06-08 22:34 ` [PATCH 09/17] media: camss: csid: allow csid to work without a regulator Jonathan Marek
2021-06-10  8:01   ` Robert Foss
2021-06-08 22:34 ` [PATCH 10/17] media: camss: remove vdda-csiN from sdm845 resources Jonathan Marek
2021-06-08 22:35 ` [PATCH 11/17] media: camss: fix VFE irq name Jonathan Marek
2021-06-08 22:35 ` [PATCH 12/17] media: camss: remove some vfe ops and clean up dead vfe-170 code Jonathan Marek
2021-06-09  3:23   ` kernel test robot
2021-06-10  5:23   ` kernel test robot
2021-06-10 12:37   ` Robert Foss
2021-06-08 22:35 ` [PATCH 13/17] media: camss: vfe-170: fix "VFE halt timeout" error Jonathan Marek
2021-06-08 22:35 ` [PATCH 14/17] media: camss: Add initial support for VFE hardware version Titan 480 Jonathan Marek
2021-06-10 12:40   ` Robert Foss
2021-06-08 22:35 ` [PATCH 15/17] media: camss: add support for V4L2_PIX_FMT_GREY for sdm845 HW Jonathan Marek
2021-06-08 22:35 ` [PATCH 16/17] media: camss: add support for SM8250 camss Jonathan Marek
2021-06-10  8:03   ` Robert Foss
2021-06-08 22:35 ` [PATCH 17/17] media: dt-bindings: media: camss: Add qcom,sm8250-camss binding Jonathan Marek
2021-06-09 16:16   ` Rob Herring
2021-06-09 22:10   ` Rob Herring
2021-06-09 22:32     ` Jonathan Marek
2021-06-16 18:16 ` [PATCH 00/17] CAMSS: SM8250 support (and some fixes) Andrey Konovalov

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).