2021-01-28 00:02:48

by Robert Foss

[permalink] [raw]
Subject: [PATCH v3 00/22] Add support for the SDM845 Camera Subsystem

This series implements support for the camera subsystem found in
the SDM845 SOCs and the Titan 170 ISP. The support is partial
in that it implements CSIPHY, CSID, and partial VFE support.

The Titan generation of the ISP diverges a fair amount from the
design of the previous architecture generation, CAMSS. As a result
some pretty invasive refactoring is done in this series. It also
means that at this time we're unable to implement support for all
of the IP blocks contained. This is due to a combination of legal
considerations with respect to the IP and its owner Qualcomm and
time & man hour constrains on the Linaro side.

The CSIPHY (CSI Physical Layer) & CSID (CSI Decoder) support is
complete, but the VFE (Video Front End, which is referred to as IFE
(Image Front End) in the Titan generation of ISPs) only has support
for the RDI (Raw Dump Interface) which allows the raw output of
the CSID to be written to memory.

The 2nd interface implemented in the VFE silicon is the PIX
interface, and camss does not support it for this generation of ISPs.
The reason for this is that the PIX interface is used for sending
image data to the BPS (Bayer Processing Section) & IPE (Image
Processing Engine), but both of these units are beyond the scope
of enabling basic ISP functionality for the SDM845.

Since the Titan architecture generation diverges quite a bit from
the CAMSS generation, a lot of pretty major refactoring is carried
out in this series. Both the CSID & VFE core paths are made more
general and hardware version specific parts are broken out.
The CSIPHY didn't require quite as radical changes and therefore
keeps its current form.

Tested on:
- Qcom RB3 / db845c + camera mezzanine, which is SDM845 based
- db410c + D3 Camera mezzanine, which is APQ8016 based

Branch:
- https://git.linaro.org/people/robert.foss/linux.git/log/?h=camss_sdm845_v1
- https://git.linaro.org/people/robert.foss/linux.git/log/?h=camss_sdm845_v2
- https://git.linaro.org/people/robert.foss/linux.git/log/?h=camss_sdm845_v3


Due to the dt-bindings supporting sdm660-camss, this series depends
the sdm660 clock driver being upstreamed. I've linked this series below.

SDM630/660 Multimedia and GPU clock controllers
https://lkml.org/lkml/2020/9/26/166



Robert Foss (22):
media: camss: Fix vfe_isr_comp_done() documentation
media: camss: Fix vfe_isr comment typo
media: camss: Add CAMSS_845 camss version
media: camss: Make ISPIF subdevice optional
media: camss: Refactor VFE HW version support
media: camss: Add support for VFE hardware version Titan 170
media: camss: Add missing format identifiers
media: camss: Refactor CSID HW version support
media: camss: Add support for CSID hardware version Titan 170
media: camss: Add support for CSIPHY hardware version Titan 170
media: camss: Remove per VFE power domain toggling
media: camss: Enable SDM845
dt-bindings: media: camss: Add qcom,msm8916-camss binding
dt-bindings: media: camss: Add qcom,msm8996-camss binding
dt-bindings: media: camss: Add qcom,sdm660-camss binding
dt-bindings: media: camss: Add qcom,sdm845-camss binding
MAINTAINERS: Change CAMSS documentation to use dtschema bindings
media: dt-bindings: media: Remove qcom,camss documentation
arm64: defconfig: Build Qcom CAMSS as module
arm64: dts: sdm845: Add CAMSS ISP node
arm64: dts: sdm845-db845c: Configure regulators for camss node
arm64: dts: sdm845-db845c: Enable ov8856 sensor and connect to ISP

.../devicetree/bindings/media/qcom,camss.txt | 236 ----
.../bindings/media/qcom,msm8916-camss.yaml | 256 ++++
.../bindings/media/qcom,msm8996-camss.yaml | 387 ++++++
.../bindings/media/qcom,sdm660-camss.yaml | 398 ++++++
.../bindings/media/qcom,sdm845-camss.yaml | 370 ++++++
MAINTAINERS | 2 +-
arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 23 +-
arch/arm64/boot/dts/qcom/sdm845.dtsi | 130 ++
arch/arm64/configs/defconfig | 1 +
drivers/media/platform/qcom/camss/Makefile | 6 +
.../platform/qcom/camss/camss-csid-170.c | 602 +++++++++
.../platform/qcom/camss/camss-csid-4-1.c | 338 +++++
.../platform/qcom/camss/camss-csid-4-7.c | 406 ++++++
.../media/platform/qcom/camss/camss-csid.c | 620 +--------
.../media/platform/qcom/camss/camss-csid.h | 178 ++-
.../qcom/camss/camss-csiphy-3ph-1-0.c | 182 ++-
.../media/platform/qcom/camss/camss-csiphy.c | 66 +-
.../media/platform/qcom/camss/camss-ispif.c | 117 +-
.../media/platform/qcom/camss/camss-ispif.h | 3 +-
.../media/platform/qcom/camss/camss-vfe-170.c | 804 ++++++++++++
.../media/platform/qcom/camss/camss-vfe-4-1.c | 119 +-
.../media/platform/qcom/camss/camss-vfe-4-7.c | 240 ++--
.../media/platform/qcom/camss/camss-vfe-4-8.c | 1166 +++++++++++++++++
.../platform/qcom/camss/camss-vfe-gen1.c | 763 +++++++++++
.../platform/qcom/camss/camss-vfe-gen1.h | 110 ++
drivers/media/platform/qcom/camss/camss-vfe.c | 840 +-----------
drivers/media/platform/qcom/camss/camss-vfe.h | 118 +-
.../media/platform/qcom/camss/camss-video.c | 100 ++
drivers/media/platform/qcom/camss/camss.c | 419 ++++--
drivers/media/platform/qcom/camss/camss.h | 17 +-
30 files changed, 6959 insertions(+), 2058 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/media/qcom,camss.txt
create mode 100644 Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
create mode 100644 Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
create mode 100644 Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
create mode 100644 Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
create mode 100644 drivers/media/platform/qcom/camss/camss-csid-170.c
create mode 100644 drivers/media/platform/qcom/camss/camss-csid-4-1.c
create mode 100644 drivers/media/platform/qcom/camss/camss-csid-4-7.c
create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-170.c
create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-4-8.c
create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-gen1.c
create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-gen1.h

--
2.27.0


2021-01-28 00:02:49

by Robert Foss

[permalink] [raw]
Subject: [PATCH v3 12/22] media: camss: Enable SDM845

Enable support for SDM845 based Titan 170 ISPs.

Signed-off-by: Robert Foss <[email protected]>
---
drivers/media/platform/qcom/camss/camss.c | 17 +++++++++++++++++
drivers/media/platform/qcom/camss/camss.h | 6 ++++--
2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 22f9d7d7085a..5ce7cae2ab9b 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -897,6 +897,12 @@ static int camss_init_subdevices(struct camss *camss)
csid_res = csid_res_660;
ispif_res = &ispif_res_660;
vfe_res = vfe_res_660;
+ } else if (camss->version == CAMSS_845) {
+ csiphy_res = csiphy_res_845;
+ csid_res = csid_res_845;
+ /* Titan VFEs don't have an ISPIF */
+ ispif_res = NULL;
+ vfe_res = vfe_res_845;
} else {
return -EINVAL;
}
@@ -1203,6 +1209,8 @@ static int camss_configure_pd(struct camss *camss)
if (camss->version == CAMSS_8x96 ||
camss->version == CAMSS_660)
nbr_pm_domains = PM_DOMAIN_CAMSS_COUNT;
+ else if (camss->version == CAMSS_845)
+ nbr_pm_domains = PM_DOMAIN_TITAN_COUNT;

for (i = 0; i < nbr_pm_domains; i++) {
camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i);
@@ -1271,6 +1279,12 @@ static int camss_probe(struct platform_device *pdev)
camss->csiphy_num = 3;
camss->csid_num = 4;
camss->vfe_num = 2;
+ } else if (of_device_is_compatible(dev->of_node,
+ "qcom,sdm845-camss")) {
+ camss->version = CAMSS_845;
+ camss->csiphy_num = 4;
+ camss->csid_num = 3;
+ camss->vfe_num = 3;
} else {
ret = -EINVAL;
goto err_free;
@@ -1402,6 +1416,8 @@ void camss_delete(struct camss *camss)
if (camss->version == CAMSS_8x96 ||
camss->version == CAMSS_660)
nbr_pm_domains = PM_DOMAIN_CAMSS_COUNT;
+ else if (camss->version == CAMSS_845)
+ nbr_pm_domains = PM_DOMAIN_TITAN_COUNT;

for (i = 0; i < nbr_pm_domains; i++) {
device_link_del(camss->genpd_link[i]);
@@ -1435,6 +1451,7 @@ static const struct of_device_id camss_dt_match[] = {
{ .compatible = "qcom,msm8916-camss" },
{ .compatible = "qcom,msm8996-camss" },
{ .compatible = "qcom,sdm660-camss" },
+ { .compatible = "qcom,sdm845-camss" },
{ }
};

diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index 7560d85b3352..2f853557ed16 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -60,6 +60,8 @@ enum pm_domain {
PM_DOMAIN_VFE0 = 0,
PM_DOMAIN_VFE1 = 1,
PM_DOMAIN_CAMSS_COUNT = 2, /* CAMSS series of ISPs */
+ PM_DOMAIN_VFELITE = 2, /* VFELITE / TOP GDSC */
+ PM_DOMAIN_TITAN_COUNT = 3, /* Titan series of ISPs */
};

enum camss_version {
@@ -83,8 +85,8 @@ struct camss {
int vfe_num;
struct vfe_device *vfe;
atomic_t ref_count;
- struct device *genpd[PM_DOMAIN_CAMSS_COUNT];
- struct device_link *genpd_link[PM_DOMAIN_CAMSS_COUNT];
+ struct device *genpd[PM_DOMAIN_TITAN_COUNT];
+ struct device_link *genpd_link[PM_DOMAIN_TITAN_COUNT];
};

struct camss_camera_interface {
--
2.27.0

2021-01-28 00:02:58

by Robert Foss

[permalink] [raw]
Subject: [PATCH v3 22/22] arm64: dts: sdm845-db845c: Enable ov8856 sensor and connect to ISP

Enable camss & ov8856 DT nodes.

Signed-off-by: Robert Foss <[email protected]>
---
arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
index 5842ab65789c..d89286f6aacb 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
@@ -1108,6 +1108,21 @@ &cci {

&camss {
vdda-supply = <&vreg_l1a_0p875>;
+
+ status = "ok";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ csiphy0_ep: endpoint {
+ clock-lanes = <1>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&ov8856_ep>;
+ };
+ };
+ };
};

&cci_i2c0 {
@@ -1139,7 +1154,7 @@ camera@10 {
avdd-supply = <&cam0_avdd_2v8>;
dvdd-supply = <&cam0_dvdd_1v2>;

- status = "disable";
+ status = "ok";

port {
ov8856_ep: endpoint {
@@ -1147,7 +1162,7 @@ ov8856_ep: endpoint {
link-frequencies = /bits/ 64
<360000000 180000000>;
data-lanes = <1 2 3 4>;
-// remote-endpoint = <&csiphy0_ep>;
+ remote-endpoint = <&csiphy0_ep>;
};
};
};
--
2.27.0

2021-01-28 00:03:03

by Robert Foss

[permalink] [raw]
Subject: [PATCH v3 06/22] media: camss: Add support for VFE hardware version Titan 170

Add register definitions for version 170 of the Titan architecture
and implement support for the RDI output mode.

The RDI mode as opposed to the PIX output mode for the VFE unit does
not support any ISP functionality. This means essentially only
supporting dumping the output of the whatever the CSI decoder receives
from the sensor.

For example will a sensor outputting YUV pixel format frames, only
allow the VFE to dump those frames as they are received by the ISP
to memory through the RDI interface.

Signed-off-by: Robert Foss <[email protected]>
---

Changes since v1:
- Andrey: Removed commented out chunk
- Remove left over WIP comments


drivers/media/platform/qcom/camss/Makefile | 1 +
.../media/platform/qcom/camss/camss-vfe-170.c | 805 ++++++++++++++++++
drivers/media/platform/qcom/camss/camss-vfe.c | 59 +-
drivers/media/platform/qcom/camss/camss-vfe.h | 25 +-
.../media/platform/qcom/camss/camss-video.c | 100 +++
drivers/media/platform/qcom/camss/camss.c | 61 ++
6 files changed, 1031 insertions(+), 20 deletions(-)
create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-170.c

diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
index 940c0ae3e003..052c4f405fa3 100644
--- a/drivers/media/platform/qcom/camss/Makefile
+++ b/drivers/media/platform/qcom/camss/Makefile
@@ -11,6 +11,7 @@ qcom-camss-objs += \
camss-vfe-4-1.o \
camss-vfe-4-7.o \
camss-vfe-4-8.o \
+ camss-vfe-170.o \
camss-vfe-gen1.o \
camss-vfe.o \
camss-video.o \
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c
new file mode 100644
index 000000000000..b8ac3a137c8a
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c
@@ -0,0 +1,805 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-vfe-4-7.c
+ *
+ * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.7
+ *
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2015-2018 Linaro Ltd.
+ */
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+#include "camss.h"
+#include "camss-vfe.h"
+
+#define VFE_HW_VERSION (0x000)
+
+#define VFE_GLOBAL_RESET_CMD (0x018)
+#define GLOBAL_RESET_CMD_CORE BIT(0)
+#define GLOBAL_RESET_CMD_CAMIF BIT(1)
+#define GLOBAL_RESET_CMD_BUS BIT(2)
+#define GLOBAL_RESET_CMD_BUS_BDG BIT(3)
+#define GLOBAL_RESET_CMD_REGISTER BIT(4)
+#define GLOBAL_RESET_CMD_PM BIT(5)
+#define GLOBAL_RESET_CMD_BUS_MISR BIT(6)
+#define GLOBAL_RESET_CMD_TESTGEN BIT(7)
+#define GLOBAL_RESET_CMD_DSP BIT(8)
+#define GLOBAL_RESET_CMD_IDLE_CGC BIT(9)
+
+#define VFE_CORE_CFG (0x050)
+#define CFG_PIXEL_PATTERN_YCBYCR (0x4)
+#define CFG_PIXEL_PATTERN_YCRYCB (0x5)
+#define CFG_PIXEL_PATTERN_CBYCRY (0x6)
+#define CFG_PIXEL_PATTERN_CRYCBY (0x7)
+#define CFG_COMPOSITE_REG_UPDATE_EN BIT(4)
+
+#define VFE_IRQ_CMD (0x058)
+#define CMD_GLOBAL_CLEAR BIT(0)
+
+#define VFE_IRQ_MASK_0 (0x05c)
+#define MASK_0_CAMIF_SOF BIT(0)
+#define MASK_0_CAMIF_EOF BIT(1)
+#define MASK_0_RDIn_REG_UPDATE(n) BIT((n) + 5)
+#define MASK_0_line_n_REG_UPDATE(n) \
+ ((n) == VFE_LINE_PIX ? \
+ BIT(4) : MASK_0_RDIn_REG_UPDATE(n))
+#define MASK_0_IMAGE_MASTER_n_PING_PONG(n) BIT((n) + 8)
+#define MASK_0_IMAGE_COMPOSITE_DONE_n(n) BIT((n) + 25)
+#define MASK_0_RESET_ACK BIT(31)
+
+#define VFE_IRQ_MASK_1 (0x060)
+#define MASK_1_CAMIF_ERROR BIT(0)
+#define MASK_1_VIOLATION BIT(7)
+#define MASK_1_BUS_BDG_HALT_ACK BIT(8)
+#define MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n) BIT((n) + 9)
+#define MASK_1_RDIn_SOF(n) BIT((n) + 29)
+
+#define VFE_IRQ_CLEAR_0 (0x064)
+#define VFE_IRQ_CLEAR_1 (0x068)
+
+#define VFE_IRQ_STATUS_0 (0x06c)
+#define STATUS_0_CAMIF_SOF BIT(0)
+#define STATUS_0_RDIn_REG_UPDATE(n) BIT((n) + 5)
+#define STATUS_0_line_n_REG_UPDATE(n) \
+ ((n) == VFE_LINE_PIX ? \
+ BIT(4) : STATUS_0_RDIn_REG_UPDATE(n))
+#define STATUS_0_IMAGE_MASTER_n_PING_PONG(n) BIT((n) + 8)
+#define STATUS_0_IMAGE_COMPOSITE_DONE_n(n) BIT((n) + 25)
+#define STATUS_0_RESET_ACK BIT(31)
+
+#define VFE_IRQ_STATUS_1 (0x070)
+#define STATUS_1_VIOLATION BIT(7)
+#define STATUS_1_BUS_BDG_HALT_ACK BIT(8)
+#define STATUS_1_RDIn_SOF(n) BIT((n) + 27)
+
+#define VFE_VIOLATION_STATUS (0x07c)
+
+#define VFE_CAMIF_CMD (0x478)
+#define CMD_CLEAR_CAMIF_STATUS BIT(2)
+
+#define VFE_CAMIF_CFG (0x47c)
+#define CFG_VSYNC_SYNC_EDGE (0)
+#define VSYNC_ACTIVE_HIGH (0)
+#define VSYNC_ACTIVE_LOW (1)
+#define CFG_HSYNC_SYNC_EDGE (1)
+#define HSYNC_ACTIVE_HIGH (0)
+#define HSYNC_ACTIVE_LOW (1)
+#define CFG_VFE_SUBSAMPLE_ENABLE BIT(4)
+#define CFG_BUS_SUBSAMPLE_ENABLE BIT(5)
+#define CFG_VFE_OUTPUT_EN BIT(6)
+#define CFG_BUS_OUTPUT_EN BIT(7)
+#define CFG_BINNING_EN BIT(9)
+#define CFG_FRAME_BASED_EN BIT(10)
+#define CFG_RAW_CROP_EN BIT(22)
+
+// XXX different, don't exist in TITAN register docs
+#define VFE_0_CAMIF_FRAME_CFG 0x484
+#define VFE_0_CAMIF_WINDOW_WIDTH_CFG 0x488
+#define VFE_0_CAMIF_WINDOW_HEIGHT_CFG 0x48c
+#define VFE_0_CAMIF_SUBSAMPLE_CFG 0x490
+#define VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN 0x498
+#define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN 0x49c
+#define VFE_0_CAMIF_STATUS 0x4a4
+#define VFE_0_CAMIF_STATUS_HALT BIT(31)
+#define CAMIF_TIMEOUT_SLEEP_US 1000
+#define CAMIF_TIMEOUT_ALL_US 1000000
+
+#define VFE_REG_UPDATE_CMD (0x4ac)
+#define REG_UPDATE_RDIn(n) BIT(1 + (n))
+#define REG_UPDATE_line_n(n) \
+ ((n) == VFE_LINE_PIX ? 1 : REG_UPDATE_RDIn(n))
+
+
+#define VFE_BUS_IRQ_MASK(n) (0x2044 + (n) * 4)
+#define VFE_BUS_IRQ_CLEAR(n) (0x2050 + (n) * 4)
+
+#define VFE_BUS_IRQ_STATUS(n) (0x205c + (n) * 4)
+#define STATUS0_COMP_RESET_DONE BIT(0)
+#define STATUS0_COMP_REG_UPDATE0_DONE BIT(1)
+#define STATUS0_COMP_REG_UPDATE1_DONE BIT(2)
+#define STATUS0_COMP_REG_UPDATE2_DONE BIT(3)
+#define STATUS0_COMP_REG_UPDATE3_DONE BIT(4)
+#define STATUS0_COMP_REG_UPDATE_DONE(n) BIT(n + 1)
+#define STATUS0_COMP0_BUF_DONE BIT(5)
+#define STATUS0_COMP1_BUF_DONE BIT(6)
+#define STATUS0_COMP2_BUF_DONE BIT(7)
+#define STATUS0_COMP3_BUF_DONE BIT(8)
+#define STATUS0_COMP4_BUF_DONE BIT(9)
+#define STATUS0_COMP5_BUF_DONE BIT(10)
+#define STATUS0_COMP_BUF_DONE(n) BIT(n + 5)
+#define STATUS0_COMP_ERROR BIT(11)
+#define STATUS0_COMP_OVERWRITE BIT(12)
+#define STATUS0_OVERFLOW BIT(13)
+#define STATUS0_VIOLATION BIT(14)
+/* WM_CLIENT_BUF_DONE defined for buffers 0:19 */
+#define STATUS1_WM_CLIENT_BUF_DONE(n) BIT(n)
+#define STATUS1_EARLY_DONE BIT(24)
+#define STATUS2_DUAL_COMP0_BUF_DONE BIT(0)
+#define STATUS2_DUAL_COMP1_BUF_DONE BIT(1)
+#define STATUS2_DUAL_COMP2_BUF_DONE BIT(2)
+#define STATUS2_DUAL_COMP3_BUF_DONE BIT(3)
+#define STATUS2_DUAL_COMP4_BUF_DONE BIT(4)
+#define STATUS2_DUAL_COMP5_BUF_DONE BIT(5)
+#define STATUS2_DUAL_COMP_BUF_DONE(n) BIT(n)
+#define STATUS2_DUAL_COMP_ERROR BIT(6)
+#define STATUS2_DUAL_COMP_OVERWRITE BIT(7)
+
+#define VFE_BUS_IRQ_CLEAR_GLOBAL (0x2068)
+
+#define VFE_BUS_WM_DEBUG_STATUS_CFG (0x226c)
+#define DEBUG_STATUS_CFG_STATUS0(n) BIT(n)
+#define DEBUG_STATUS_CFG_STATUS1(n) BIT(8+n)
+
+#define VFE_BUS_WM_ADDR_SYNC_FRAME_HEADER (0x2080)
+
+#define VFE_BUS_WM_ADDR_SYNC_NO_SYNC (0x2084)
+#define BUS_VER2_MAX_CLIENTS (24)
+#define WM_ADDR_NO_SYNC_DEFAULT_VAL \
+ ((1 << BUS_VER2_MAX_CLIENTS) - 1)
+
+#define VFE_BUS_WM_CGC_OVERRIDE (0x200c)
+#define WM_CGC_OVERRIDE_ALL (0xFFFFF)
+
+#define VFE_BUS_WM_TEST_BUS_CTRL (0x211c)
+
+#define VFE_BUS_WM_STATUS0(n) (0x2200 + (n) * 0x100)
+#define VFE_BUS_WM_STATUS1(n) (0x2204 + (n) * 0x100)
+#define VFE_BUS_WM_CFG(n) (0x2208 + (n) * 0x100)
+#define WM_CFG_EN (0)
+#define WM_CFG_MODE (1)
+#define MODE_QCOM_PLAIN (0)
+#define MODE_MIPI_RAW (1)
+#define WM_CFG_VIRTUALFRAME (2)
+#define VFE_BUS_WM_HEADER_ADDR(n) (0x220c + (n) * 0x100)
+#define VFE_BUS_WM_HEADER_CFG(n) (0x2210 + (n) * 0x100)
+#define VFE_BUS_WM_IMAGE_ADDR(n) (0x2214 + (n) * 0x100)
+#define VFE_BUS_WM_IMAGE_ADDR_OFFSET(n) (0x2218 + (n) * 0x100)
+#define VFE_BUS_WM_BUFFER_WIDTH_CFG(n) (0x221c + (n) * 0x100)
+#define WM_BUFFER_DEFAULT_WIDTH (0xFF01)
+
+#define VFE_BUS_WM_BUFFER_HEIGHT_CFG(n) (0x2220 + (n) * 0x100)
+#define VFE_BUS_WM_PACKER_CFG(n) (0x2224 + (n) * 0x100)
+
+#define VFE_BUS_WM_STRIDE(n) (0x2228 + (n) * 0x100)
+#define WM_STRIDE_DEFAULT_STRIDE (0xFF01)
+
+#define VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(n) (0x2248 + (n) * 0x100)
+#define VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(n) (0x224c + (n) * 0x100)
+#define VFE_BUS_WM_FRAMEDROP_PERIOD(n) (0x2250 + (n) * 0x100)
+#define VFE_BUS_WM_FRAMEDROP_PATTERN(n) (0x2254 + (n) * 0x100)
+#define VFE_BUS_WM_FRAME_INC(n) (0x2258 + (n) * 0x100)
+#define VFE_BUS_WM_BURST_LIMIT(n) (0x225c + (n) * 0x100)
+
+
+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_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_IDLE_CGC |
+ GLOBAL_RESET_CMD_DSP |
+ GLOBAL_RESET_CMD_TESTGEN |
+ GLOBAL_RESET_CMD_BUS_MISR |
+ GLOBAL_RESET_CMD_PM |
+ GLOBAL_RESET_CMD_REGISTER |
+ GLOBAL_RESET_CMD_BUS_BDG |
+ GLOBAL_RESET_CMD_BUS |
+ GLOBAL_RESET_CMD_CAMIF |
+ GLOBAL_RESET_CMD_CORE;
+
+ reset_bits = 0x00003F9F;
+
+ writel_relaxed(BIT(31), vfe->base + VFE_IRQ_MASK_0);
+
+ /* Make sure IRQ mask has been written before resetting */
+ wmb();
+
+ writel_relaxed(reset_bits, vfe->base + VFE_GLOBAL_RESET_CMD);
+}
+
+static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line)
+{
+ u32 val;
+
+ /*Set Debug Registers*/
+ val = DEBUG_STATUS_CFG_STATUS0(1) |
+ DEBUG_STATUS_CFG_STATUS0(7);
+ writel_relaxed(val, vfe->base + VFE_BUS_WM_DEBUG_STATUS_CFG);
+
+ /* BUS_WM_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
+ writel_relaxed(0, vfe->base + VFE_BUS_WM_ADDR_SYNC_FRAME_HEADER);
+
+ /* no clock gating at bus input */
+ val = WM_CGC_OVERRIDE_ALL;
+ writel_relaxed(val, vfe->base + VFE_BUS_WM_CGC_OVERRIDE);
+
+ writel_relaxed(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL);
+
+ /* if addr_no_sync has default value then config the addr no sync reg */
+ val = WM_ADDR_NO_SYNC_DEFAULT_VAL;
+ writel_relaxed(val, vfe->base + VFE_BUS_WM_ADDR_SYNC_NO_SYNC);
+
+ writel_relaxed(0xf, vfe->base + VFE_BUS_WM_BURST_LIMIT(wm));
+
+ val = WM_BUFFER_DEFAULT_WIDTH;
+ writel_relaxed(val, vfe->base + VFE_BUS_WM_BUFFER_WIDTH_CFG(wm));
+
+ val = 0;
+ writel_relaxed(val, vfe->base + VFE_BUS_WM_BUFFER_HEIGHT_CFG(wm));
+
+ val = 0;
+ writel_relaxed(val, vfe->base + VFE_BUS_WM_PACKER_CFG(wm)); // XXX 1 for PLAIN8?
+
+ /* Configure stride for RDIs */
+ //val = pix->plane_fmt[0].bytesperline;
+ val = WM_STRIDE_DEFAULT_STRIDE;
+ writel_relaxed(val, vfe->base + VFE_BUS_WM_STRIDE(wm));
+
+ /* Enable WM */
+ val = 1 << WM_CFG_EN |
+ MODE_MIPI_RAW << WM_CFG_MODE;
+ writel_relaxed(val, vfe->base + VFE_BUS_WM_CFG(wm));
+}
+
+static void vfe_wm_stop(struct vfe_device *vfe, u8 wm)
+{
+ /* Disable WM */
+ 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)
+{
+ struct v4l2_pix_format_mplane *pix =
+ &line->video_out.active_fmt.fmt.pix_mp;
+ u32 stride = pix->plane_fmt[0].bytesperline;
+
+ writel_relaxed(addr, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
+ writel_relaxed(stride * pix->height, vfe->base + VFE_BUS_WM_FRAME_INC(wm));
+}
+
+static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+ vfe->reg_update |= REG_UPDATE_line_n(line_id);
+
+ /* Enforce ordering between previous reg writes and reg update */
+ wmb();
+
+ writel_relaxed(vfe->reg_update, vfe->base + VFE_REG_UPDATE_CMD);
+
+ /* Enforce ordering between reg update and subsequent reg writes */
+ wmb();
+}
+
+static inline void vfe_reg_update_clear(struct vfe_device *vfe,
+ enum vfe_line_id line_id)
+{
+ vfe->reg_update &= ~REG_UPDATE_line_n(line_id);
+}
+
+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_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);
+}
+
+/*
+ * 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 status0, status1, vfe_bus_status[3];
+ int i, wm;
+
+ 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);
+
+ for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++) {
+ vfe_bus_status[i] = readl_relaxed(vfe->base + VFE_BUS_IRQ_STATUS(i));
+ writel_relaxed(vfe_bus_status[i], vfe->base + VFE_BUS_IRQ_CLEAR(i));
+ }
+
+ /* Enforce ordering between IRQ reading and interpretation */
+ wmb();
+
+ writel_relaxed(CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD);
+ writel_relaxed(1, vfe->base + VFE_BUS_IRQ_CLEAR_GLOBAL);
+
+ if (status0 & STATUS_0_RESET_ACK)
+ vfe->isr_ops.reset_ack(vfe);
+
+ for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++)
+ if (status0 & STATUS_0_line_n_REG_UPDATE(i))
+ vfe->isr_ops.reg_update(vfe, i);
+
+ for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
+ if (status0 & STATUS_1_RDIn_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);
+
+ 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);
+
+ 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)
+{
+ unsigned long time;
+
+ return 0;
+
+ 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;
+ }
+
+ return 0;
+}
+
+static int vfe_get_output(struct vfe_line *line)
+{
+ struct vfe_device *vfe = to_vfe(line);
+ struct vfe_output *output;
+ struct v4l2_format *f = &line->video_out.active_fmt;
+ unsigned long flags;
+ int i;
+ 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;
+ }
+
+ switch (f->fmt.pix_mp.pixelformat) {
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_NV61:
+ output->wm_num = 2;
+ break;
+ default:
+ output->wm_num = 1;
+ break;
+ }
+
+ for (i = 0; i < output->wm_num; i++) {
+ 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[i] = wm_idx;
+ }
+
+ output->drop_update_idx = 0;
+
+ spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+ return 0;
+
+error_get_wm:
+ for (i--; i >= 0; i--)
+ vfe_release_wm(vfe, output->wm_idx[i]);
+ 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;
+ const struct vfe_hw_ops *ops = vfe->ops;
+ struct media_entity *sensor;
+ unsigned long flags;
+ unsigned int frame_skip = 0;
+ unsigned int i;
+
+ sensor = camss_find_sensor(&line->subdev.entity);
+ if (sensor) {
+ struct v4l2_subdev *subdev =
+ media_entity_to_v4l2_subdev(sensor);
+
+ v4l2_subdev_call(subdev, sensor, g_skip_frames, &frame_skip);
+ /* Max frame skip is 29 frames */
+ if (frame_skip > VFE_FRAME_DROP_VAL - 1)
+ frame_skip = VFE_FRAME_DROP_VAL - 1;
+ }
+
+ spin_lock_irqsave(&vfe->output_lock, flags);
+
+ ops->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);
+
+ if (line->id != VFE_LINE_PIX)
+ 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);
+ }
+
+ ops->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_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)
+{
+
+}
+
+/*
+ * 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->ops->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_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;
+}
+
+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,
+};
+
+static void vfe_subdev_init(struct vfe_device *vfe)
+{
+ vfe->isr_ops = vfe_isr_ops_170;
+ vfe->video_ops = vfe_video_ops_170;
+}
+
+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,
+ .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.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 75b4e866c01b..fa9629835e98 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -96,6 +96,39 @@ static const struct vfe_format formats_pix_8x96[] = {
{ MEDIA_BUS_FMT_YVYU8_2X8, 8 },
};

+static const struct vfe_format formats_rdi_845[] = {
+ { MEDIA_BUS_FMT_UYVY8_2X8, 8 },
+ { MEDIA_BUS_FMT_VYUY8_2X8, 8 },
+ { MEDIA_BUS_FMT_YUYV8_2X8, 8 },
+ { MEDIA_BUS_FMT_YVYU8_2X8, 8 },
+ { MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
+ { MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
+ { MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
+ { MEDIA_BUS_FMT_SRGGB8_1X8, 8 },
+ { MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
+ { MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
+ { MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
+ { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
+ { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16 },
+ { MEDIA_BUS_FMT_SBGGR12_1X12, 12 },
+ { MEDIA_BUS_FMT_SGBRG12_1X12, 12 },
+ { MEDIA_BUS_FMT_SGRBG12_1X12, 12 },
+ { MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
+ { MEDIA_BUS_FMT_SBGGR14_1X14, 14 },
+ { MEDIA_BUS_FMT_SGBRG14_1X14, 14 },
+ { MEDIA_BUS_FMT_SGRBG14_1X14, 14 },
+ { MEDIA_BUS_FMT_SRGGB14_1X14, 14 },
+ { MEDIA_BUS_FMT_Y10_1X10, 10 },
+ { MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16 },
+};
+
+static const struct vfe_format formats_pix_845[] = {
+ { MEDIA_BUS_FMT_UYVY8_2X8, 8 },
+ { MEDIA_BUS_FMT_VYUY8_2X8, 8 },
+ { MEDIA_BUS_FMT_YUYV8_2X8, 8 },
+ { MEDIA_BUS_FMT_YVYU8_2X8, 8 },
+};
+
/*
* vfe_get_bpp - map media bus format to bits per pixel
* @formats: supported media bus formats array
@@ -192,7 +225,8 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
return sink_code;
}
else if (vfe->camss->version == CAMSS_8x96 ||
- vfe->camss->version == CAMSS_660)
+ vfe->camss->version == CAMSS_660 ||
+ vfe->camss->version == CAMSS_845)
switch (sink_code) {
case MEDIA_BUS_FMT_YUYV8_2X8:
{
@@ -256,13 +290,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
return 0;
}

-/*
- * vfe_reset - Trigger reset on VFE module and wait to complete
- * @vfe: VFE device
- *
- * Return 0 on success or a negative error code otherwise
- */
-static int vfe_reset(struct vfe_device *vfe)
+int vfe_reset(struct vfe_device *vfe)
{
unsigned long time;

@@ -429,7 +457,8 @@ static int vfe_set_clock_rates(struct vfe_device *vfe)
struct camss_clock *clock = &vfe->clock[i];

if (!strcmp(clock->name, "vfe0") ||
- !strcmp(clock->name, "vfe1")) {
+ !strcmp(clock->name, "vfe1") ||
+ !strcmp(clock->name, "vfe_lite")) {
u64 min_rate = 0;
long rate;

@@ -1268,6 +1297,10 @@ 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;
default:
return -EINVAL;
}
@@ -1379,6 +1412,14 @@ 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) {
+ if (i == VFE_LINE_PIX) {
+ l->formats = formats_pix_845;
+ l->nformats = ARRAY_SIZE(formats_pix_845);
+ } else {
+ l->formats = formats_rdi_845;
+ l->nformats = ARRAY_SIZE(formats_rdi_845);
+ }
} else {
return -EINVAL;
}
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index 8629c833f130..a0b618c9cec8 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -19,7 +19,6 @@
#include "camss-video.h"
#include "camss-vfe-gen1.h"

-
#define MSM_VFE_PAD_SINK 0
#define MSM_VFE_PAD_SRC 1
#define MSM_VFE_PADS_NUM 2
@@ -39,14 +38,14 @@
#define to_vfe(ptr_line) \
container_of(vfe_line_array(ptr_line), struct vfe_device, line)

-
enum vfe_output_state {
VFE_OUTPUT_OFF,
VFE_OUTPUT_RESERVED,
VFE_OUTPUT_SINGLE,
VFE_OUTPUT_CONTINUOUS,
VFE_OUTPUT_IDLE,
- VFE_OUTPUT_STOPPING
+ VFE_OUTPUT_STOPPING,
+ VFE_OUTPUT_ON,
};

enum vfe_line_id {
@@ -72,6 +71,9 @@ struct vfe_output {
int active_buf;
int wait_sof;
} gen1;
+ struct {
+ int active_num;
+ } gen2;
};
enum vfe_output_state state;
unsigned int sequence;
@@ -169,14 +171,6 @@ void vfe_buf_add_pending(struct vfe_output *output, struct camss_buffer *buffer)

struct camss_buffer *vfe_buf_get_pending(struct vfe_output *output);

-/*
- * vfe_disable - Disable streaming on VFE line
- * @line: VFE line
- *
- * Return 0 on success or a negative error code otherwise
- */
-int vfe_disable(struct vfe_line *line);
-
int vfe_flush_buffers(struct camss_video *vid, enum vb2_buffer_state state);

/*
@@ -191,8 +185,17 @@ int vfe_put_output(struct vfe_line *line);
int vfe_release_wm(struct vfe_device *vfe, u8 wm);
int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id);

+/*
+ * vfe_reset - Trigger reset on VFE module and wait to complete
+ * @vfe: VFE device
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+int vfe_reset(struct vfe_device *vfe);
+
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;

#endif /* QC_MSM_CAMSS_VFE_H */
diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
index 97cea7c4d769..9c86edd81737 100644
--- a/drivers/media/platform/qcom/camss/camss-video.c
+++ b/drivers/media/platform/qcom/camss/camss-video.c
@@ -133,6 +133,55 @@ static const struct camss_format_info formats_rdi_8x96[] = {
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
};

+static const struct camss_format_info formats_rdi_845[] = {
+ { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
+ { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
+ { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
+ { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
+ { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 8 } },
+ { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 8 } },
+ { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 8 } },
+ { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 8 } },
+ { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10P, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
+ { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10P, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
+ { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10P, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
+ { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10P, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
+ { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_PIX_FMT_SBGGR10, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
+ { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12P, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
+ { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
+ { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
+ { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
+ { MEDIA_BUS_FMT_SBGGR14_1X14, V4L2_PIX_FMT_SBGGR14P, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 14 } },
+ { MEDIA_BUS_FMT_SGBRG14_1X14, V4L2_PIX_FMT_SGBRG14P, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 14 } },
+ { MEDIA_BUS_FMT_SGRBG14_1X14, V4L2_PIX_FMT_SGRBG14P, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 14 } },
+ { MEDIA_BUS_FMT_SRGGB14_1X14, V4L2_PIX_FMT_SRGGB14P, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 14 } },
+ { 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,
+ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
+};
+
static const struct camss_format_info formats_pix_8x16[] = {
{ MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV12, 1,
{ { 1, 1 } }, { { 2, 3 } }, { 8 } },
@@ -211,6 +260,49 @@ static const struct camss_format_info formats_pix_8x96[] = {
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
};

+static const struct camss_format_info formats_pix_845[] = {
+ { MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV12, 1,
+ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
+ { MEDIA_BUS_FMT_YVYU8_1_5X8, V4L2_PIX_FMT_NV12, 1,
+ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
+ { MEDIA_BUS_FMT_UYVY8_1_5X8, V4L2_PIX_FMT_NV12, 1,
+ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
+ { MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV12, 1,
+ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
+ { MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV21, 1,
+ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
+ { MEDIA_BUS_FMT_YVYU8_1_5X8, V4L2_PIX_FMT_NV21, 1,
+ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
+ { MEDIA_BUS_FMT_UYVY8_1_5X8, V4L2_PIX_FMT_NV21, 1,
+ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
+ { MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV21, 1,
+ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
+ { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_NV16, 1,
+ { { 1, 1 } }, { { 1, 2 } }, { 8 } },
+ { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_NV16, 1,
+ { { 1, 1 } }, { { 1, 2 } }, { 8 } },
+ { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_NV16, 1,
+ { { 1, 1 } }, { { 1, 2 } }, { 8 } },
+ { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_NV16, 1,
+ { { 1, 1 } }, { { 1, 2 } }, { 8 } },
+ { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_NV61, 1,
+ { { 1, 1 } }, { { 1, 2 } }, { 8 } },
+ { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_NV61, 1,
+ { { 1, 1 } }, { { 1, 2 } }, { 8 } },
+ { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_NV61, 1,
+ { { 1, 1 } }, { { 1, 2 } }, { 8 } },
+ { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_NV61, 1,
+ { { 1, 1 } }, { { 1, 2 } }, { 8 } },
+ { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
+ { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
+ { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
+ { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
+};
+
/* -----------------------------------------------------------------------------
* Helper functions
*/
@@ -960,6 +1052,14 @@ 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) {
+ if (is_pix) {
+ video->formats = formats_pix_845;
+ video->nformats = ARRAY_SIZE(formats_pix_845);
+ } else {
+ video->formats = formats_rdi_845;
+ video->nformats = ARRAY_SIZE(formats_rdi_845);
+ }
} else {
ret = -EINVAL;
goto error_video_register;
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index b966de344b5b..d710073e47a3 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -465,6 +465,67 @@ static const struct resources vfe_res_660[] = {
}
};

+static const struct resources vfe_res_845[] = {
+ /* VFE0 */
+ {
+ .regulator = { NULL },
+ .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
+ "soc_ahb", "vfe0", "vfe0_axi",
+ "vfe0_src", "csi0",
+ "csi0_src"},
+ .clock_rate = { { 0 },
+ { 0 },
+ { 80000000 },
+ { 0 },
+ { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
+ { 0 },
+ { 320000000 },
+ { 19200000, 75000000, 384000000, 538666667 },
+ { 384000000 } },
+ .reg = { "vfe0" },
+ .interrupt = { "vfe0" }
+ },
+
+ /* VFE1 */
+ {
+ .regulator = { NULL },
+ .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
+ "soc_ahb", "vfe1", "vfe1_axi",
+ "vfe1_src", "csi1",
+ "csi1_src"},
+ .clock_rate = { { 0 },
+ { 0 },
+ { 80000000 },
+ { 0 },
+ { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
+ { 0 },
+ { 320000000 },
+ { 19200000, 75000000, 384000000, 538666667 },
+ { 384000000 } },
+ .reg = { "vfe1" },
+ .interrupt = { "vfe1" }
+ },
+
+ /* VFE-lite */
+ {
+ .regulator = { NULL },
+ .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src",
+ "soc_ahb", "vfe_lite",
+ "vfe_lite_src", "csi2",
+ "csi2_src"},
+ .clock_rate = { { 0 },
+ { 0 },
+ { 80000000 },
+ { 0 },
+ { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 },
+ { 320000000 },
+ { 19200000, 75000000, 384000000, 538666667 },
+ { 384000000 } },
+ .reg = { "vfe_lite" },
+ .interrupt = { "vfe_lite" }
+ }
+};
+
/*
* camss_add_clock_margin - Add margin to clock frequency rate
* @rate: Clock frequency rate
--
2.27.0

2021-01-28 00:03:11

by Robert Foss

[permalink] [raw]
Subject: [PATCH v3 17/22] MAINTAINERS: Change CAMSS documentation to use dtschema bindings

Due to the complexity of describing multiple hardware generations
in one document, switch to using separate dt-bindings.

Signed-off-by: Robert Foss <[email protected]>
---
MAINTAINERS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index cdf1556c6007..7c5a494d9113 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14686,7 +14686,7 @@ M: Todor Tomov <[email protected]>
L: [email protected]
S: Maintained
F: Documentation/admin-guide/media/qcom_camss.rst
-F: Documentation/devicetree/bindings/media/qcom,camss.txt
+F: Documentation/devicetree/bindings/media/*camss*
F: drivers/media/platform/qcom/camss/

QUALCOMM CORE POWER REDUCTION (CPR) AVS DRIVER
--
2.27.0

2021-01-28 00:03:13

by Robert Foss

[permalink] [raw]
Subject: [PATCH v3 11/22] media: camss: Remove per VFE power domain toggling

For Titan ISPs clocks fail to re-enable during vfe_get()
after any vfe has been halted and its corresponding power
domain power has been detached.

Since all of the clocks depend on all of the PDs, per
VFE PD detaching is no option for this generation of HW.

Signed-off-by: Robert Foss <[email protected]>
---
.../media/platform/qcom/camss/camss-ispif.c | 11 ---
drivers/media/platform/qcom/camss/camss-vfe.c | 7 --
drivers/media/platform/qcom/camss/camss.c | 94 +++++++++++--------
drivers/media/platform/qcom/camss/camss.h | 12 +--
4 files changed, 60 insertions(+), 64 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c
index c36570042082..e41925850ba2 100644
--- a/drivers/media/platform/qcom/camss/camss-ispif.c
+++ b/drivers/media/platform/qcom/camss/camss-ispif.c
@@ -323,14 +323,6 @@ static int ispif_reset(struct ispif_device *ispif, u8 vfe_id)
struct camss *camss = ispif->camss;
int ret;

- ret = camss_pm_domain_on(camss, PM_DOMAIN_VFE0);
- if (ret < 0)
- return ret;
-
- ret = camss_pm_domain_on(camss, PM_DOMAIN_VFE1);
- if (ret < 0)
- return ret;
-
ret = camss_enable_clocks(ispif->nclocks_for_reset,
ispif->clock_for_reset,
camss->dev);
@@ -343,9 +335,6 @@ static int ispif_reset(struct ispif_device *ispif, u8 vfe_id)

camss_disable_clocks(ispif->nclocks_for_reset, ispif->clock_for_reset);

- camss_pm_domain_off(camss, PM_DOMAIN_VFE0);
- camss_pm_domain_off(camss, PM_DOMAIN_VFE1);
-
return ret;
}

diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index fa9629835e98..e41c22da4b9b 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -587,10 +587,6 @@ static int vfe_get(struct vfe_device *vfe)
mutex_lock(&vfe->power_lock);

if (vfe->power_count == 0) {
- ret = camss_pm_domain_on(vfe->camss, vfe->id);
- if (ret < 0)
- goto error_pm_domain;
-
ret = pm_runtime_get_sync(vfe->camss->dev);
if (ret < 0)
goto error_pm_runtime_get;
@@ -627,9 +623,7 @@ static int vfe_get(struct vfe_device *vfe)

error_pm_runtime_get:
pm_runtime_put_sync(vfe->camss->dev);
- camss_pm_domain_off(vfe->camss, vfe->id);

-error_pm_domain:
mutex_unlock(&vfe->power_lock);

return ret;
@@ -653,7 +647,6 @@ static void vfe_put(struct vfe_device *vfe)
}
camss_disable_clocks(vfe->nclocks, vfe->clock);
pm_runtime_put_sync(vfe->camss->dev);
- camss_pm_domain_off(vfe->camss, vfe->id);
}

vfe->power_count--;
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 7e7763f04b58..22f9d7d7085a 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -774,28 +774,6 @@ int camss_get_pixel_clock(struct media_entity *entity, u32 *pixel_clock)
return 0;
}

-int camss_pm_domain_on(struct camss *camss, int id)
-{
- if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660) {
- camss->genpd_link[id] = device_link_add(camss->dev,
- camss->genpd[id], DL_FLAG_STATELESS |
- DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
-
- if (!camss->genpd_link[id])
- return -EINVAL;
- }
-
- return 0;
-}
-
-void camss_pm_domain_off(struct camss *camss, int id)
-{
- if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660)
- device_link_del(camss->genpd_link[id]);
-}
-
/*
* camss_of_parse_endpoint_node - Parse port endpoint node
* @dev: Device
@@ -1214,6 +1192,48 @@ static const struct media_device_ops camss_media_ops = {
.link_notify = v4l2_pipeline_link_notify,
};

+
+static int camss_configure_pd(struct camss *camss)
+{
+ int nbr_pm_domains = 0;
+ int last_pm_domain = 0;
+ int i;
+ int ret;
+
+ if (camss->version == CAMSS_8x96 ||
+ camss->version == CAMSS_660)
+ nbr_pm_domains = PM_DOMAIN_CAMSS_COUNT;
+
+ for (i = 0; i < nbr_pm_domains; i++) {
+ camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i);
+ if (IS_ERR(camss->genpd[i])) {
+ ret = PTR_ERR(camss->genpd[i]);
+ goto fail_pm;
+ }
+
+ camss->genpd_link[i] = device_link_add(camss->dev, camss->genpd[i],
+ DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
+
+ if (!camss->genpd_link[i]) {
+ dev_pm_domain_detach(camss->genpd[i], true);
+ ret = -EINVAL;
+ goto fail_pm;
+ }
+
+ last_pm_domain = i;
+ }
+
+ return 0;
+
+fail_pm:
+ for (i = 0; i < last_pm_domain; i++) {
+ device_link_del(camss->genpd_link[i]);
+ dev_pm_domain_detach(camss->genpd[i], true);
+ }
+
+ return ret;
+}
+
/*
* camss_probe - Probe CAMSS platform device
* @pdev: Pointer to CAMSS platform device
@@ -1346,20 +1366,10 @@ static int camss_probe(struct platform_device *pdev)
}
}

- if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660) {
- camss->genpd[PM_DOMAIN_VFE0] = dev_pm_domain_attach_by_id(
- camss->dev, PM_DOMAIN_VFE0);
- if (IS_ERR(camss->genpd[PM_DOMAIN_VFE0]))
- return PTR_ERR(camss->genpd[PM_DOMAIN_VFE0]);
-
- camss->genpd[PM_DOMAIN_VFE1] = dev_pm_domain_attach_by_id(
- camss->dev, PM_DOMAIN_VFE1);
- if (IS_ERR(camss->genpd[PM_DOMAIN_VFE1])) {
- dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE0],
- true);
- return PTR_ERR(camss->genpd[PM_DOMAIN_VFE1]);
- }
+ ret = camss_configure_pd(camss);
+ if (ret < 0) {
+ dev_err(dev, "Failed to configure power domains: %d\n", ret);
+ return ret;
}

pm_runtime_enable(dev);
@@ -1380,6 +1390,9 @@ static int camss_probe(struct platform_device *pdev)

void camss_delete(struct camss *camss)
{
+ int nbr_pm_domains = 0;
+ int i;
+
v4l2_device_unregister(&camss->v4l2_dev);
media_device_unregister(&camss->media_dev);
media_device_cleanup(&camss->media_dev);
@@ -1387,9 +1400,12 @@ void camss_delete(struct camss *camss)
pm_runtime_disable(camss->dev);

if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660) {
- dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE0], true);
- dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE1], true);
+ camss->version == CAMSS_660)
+ nbr_pm_domains = PM_DOMAIN_CAMSS_COUNT;
+
+ for (i = 0; i < nbr_pm_domains; i++) {
+ device_link_del(camss->genpd_link[i]);
+ dev_pm_domain_detach(camss->genpd[i], true);
}

kfree(camss);
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index b7ad8e9f68a8..7560d85b3352 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -57,9 +57,9 @@ struct resources_ispif {
};

enum pm_domain {
- PM_DOMAIN_VFE0,
- PM_DOMAIN_VFE1,
- PM_DOMAIN_COUNT
+ PM_DOMAIN_VFE0 = 0,
+ PM_DOMAIN_VFE1 = 1,
+ PM_DOMAIN_CAMSS_COUNT = 2, /* CAMSS series of ISPs */
};

enum camss_version {
@@ -83,8 +83,8 @@ struct camss {
int vfe_num;
struct vfe_device *vfe;
atomic_t ref_count;
- struct device *genpd[PM_DOMAIN_COUNT];
- struct device_link *genpd_link[PM_DOMAIN_COUNT];
+ struct device *genpd[PM_DOMAIN_CAMSS_COUNT];
+ struct device_link *genpd_link[PM_DOMAIN_CAMSS_COUNT];
};

struct camss_camera_interface {
@@ -110,8 +110,6 @@ int camss_enable_clocks(int nclocks, struct camss_clock *clock,
void camss_disable_clocks(int nclocks, struct camss_clock *clock);
struct media_entity *camss_find_sensor(struct media_entity *entity);
int camss_get_pixel_clock(struct media_entity *entity, u32 *pixel_clock);
-int camss_pm_domain_on(struct camss *camss, int id);
-void camss_pm_domain_off(struct camss *camss, int id);
void camss_delete(struct camss *camss);

#endif /* QC_MSM_CAMSS_H */
--
2.27.0

2021-01-28 00:05:35

by Robert Foss

[permalink] [raw]
Subject: [PATCH v3 16/22] dt-bindings: media: camss: Add qcom,sdm845-camss binding

Add bindings for qcom,sdm845-camss in order to support the camera
subsystem for SDM845.

Signed-off-by: Robert Foss <[email protected]>
---

Changes since v2
- Rob: Removed extra empty lines at end of file
- Rob: Add new line at end of file
- Rob: Remove redundant descriptions
- Rob: Add power domain description
- Rob: Make clock-lanes a constant
- Rob: Rework to conform to new port schema
- Add max & minItems to data-lanes
- Remove ports requirement - endpoint & reg
- Add proper commit message
- Remove Todor as binding maintainer


.../bindings/media/qcom,sdm845-camss.yaml | 370 ++++++++++++++++++
1 file changed, 370 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml

diff --git a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
new file mode 100644
index 000000000000..637b9f683bd1
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
@@ -0,0 +1,370 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/media/qcom,sdm845-camss.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Qualcomm CAMSS ISP
+
+maintainers:
+ - Robert Foss <[email protected]>
+
+description: |
+ The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms
+
+properties:
+ compatible:
+ const: qcom,sdm845-camss
+
+ clocks:
+ minItems: 36
+ maxItems: 36
+
+ clock-names:
+ items:
+ - const: camnoc_axi
+ - const: cpas_ahb
+ - const: cphy_rx_src
+ - const: csi0
+ - const: csi0_src
+ - const: csi1
+ - const: csi1_src
+ - const: csi2
+ - const: csi2_src
+ - const: csiphy0
+ - const: csiphy0_timer
+ - const: csiphy0_timer_src
+ - const: csiphy1
+ - const: csiphy1_timer
+ - const: csiphy1_timer_src
+ - const: csiphy2
+ - const: csiphy2_timer
+ - const: csiphy2_timer_src
+ - const: csiphy3
+ - const: csiphy3_timer
+ - const: csiphy3_timer_src
+ - const: gcc_camera_ahb
+ - const: gcc_camera_axi
+ - const: slow_ahb_src
+ - const: soc_ahb
+ - const: vfe0_axi
+ - const: vfe0
+ - const: vfe0_cphy_rx
+ - const: vfe0_src
+ - const: vfe1_axi
+ - const: vfe1
+ - const: vfe1_cphy_rx
+ - const: vfe1_src
+ - const: vfe_lite
+ - const: vfe_lite_cphy_rx
+ - const: vfe_lite_src
+
+ interrupts:
+ minItems: 10
+ maxItems: 10
+
+ interrupt-names:
+ items:
+ - const: csid0
+ - const: csid1
+ - const: csid2
+ - const: csiphy0
+ - const: csiphy1
+ - const: csiphy2
+ - const: csiphy3
+ - const: vfe0
+ - const: vfe1
+ - const: vfe_lite
+
+ iommus:
+ maxItems: 4
+
+ 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
+
+ reg:
+ minItems: 10
+ maxItems: 10
+
+ reg-names:
+ items:
+ - const: csid0
+ - const: csid1
+ - const: csid2
+ - const: csiphy0
+ - const: csiphy1
+ - const: csiphy2
+ - const: csiphy3
+ - const: vfe0
+ - const: vfe1
+ - const: vfe_lite
+
+ vdda-supply:
+ description:
+ Definition of the regulator used as analog power supply.
+
+required:
+ - clock-names
+ - clocks
+ - compatible
+ - interrupt-names
+ - interrupts
+ - iommus
+ - power-domains
+ - reg
+ - reg-names
+ - vdda-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/qcom,camcc-sdm845.h>
+ #include <dt-bindings/clock/qcom,gcc-sdm845.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ camss: camss@a00000 {
+ compatible = "qcom,sdm845-camss";
+
+ clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_0_CSID_CLK>,
+ <&clock_camcc CAM_CC_IFE_0_CSID_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_1_CSID_CLK>,
+ <&clock_camcc CAM_CC_IFE_1_CSID_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_LITE_CSID_CLK>,
+ <&clock_camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSIPHY0_CLK>,
+ <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK>,
+ <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSIPHY1_CLK>,
+ <&clock_camcc CAM_CC_CSI1PHYTIMER_CLK>,
+ <&clock_camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSIPHY2_CLK>,
+ <&clock_camcc CAM_CC_CSI2PHYTIMER_CLK>,
+ <&clock_camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSIPHY3_CLK>,
+ <&clock_camcc CAM_CC_CSI3PHYTIMER_CLK>,
+ <&clock_camcc CAM_CC_CSI3PHYTIMER_CLK_SRC>,
+ <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_AXI_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_IFE_0_AXI_CLK>,
+ <&clock_camcc CAM_CC_IFE_0_CLK>,
+ <&clock_camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+ <&clock_camcc CAM_CC_IFE_0_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_1_AXI_CLK>,
+ <&clock_camcc CAM_CC_IFE_1_CLK>,
+ <&clock_camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+ <&clock_camcc CAM_CC_IFE_1_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_LITE_CLK>,
+ <&clock_camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+ <&clock_camcc CAM_CC_IFE_LITE_CLK_SRC>;
+
+ clock-names = "camnoc_axi",
+ "cpas_ahb",
+ "cphy_rx_src",
+ "csi0",
+ "csi0_src",
+ "csi1",
+ "csi1_src",
+ "csi2",
+ "csi2_src",
+ "csiphy0",
+ "csiphy0_timer",
+ "csiphy0_timer_src",
+ "csiphy1",
+ "csiphy1_timer",
+ "csiphy1_timer_src",
+ "csiphy2",
+ "csiphy2_timer",
+ "csiphy2_timer_src",
+ "csiphy3",
+ "csiphy3_timer",
+ "csiphy3_timer_src",
+ "gcc_camera_ahb",
+ "gcc_camera_axi",
+ "slow_ahb_src",
+ "soc_ahb",
+ "vfe0_axi",
+ "vfe0",
+ "vfe0_cphy_rx",
+ "vfe0_src",
+ "vfe1_axi",
+ "vfe1",
+ "vfe1_cphy_rx",
+ "vfe1_src",
+ "vfe_lite",
+ "vfe_lite_cphy_rx",
+ "vfe_lite_src";
+
+ interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 465 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 464 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>;
+
+ interrupt-names = "csid0",
+ "csid1",
+ "csid2",
+ "csiphy0",
+ "csiphy1",
+ "csiphy2",
+ "csiphy3",
+ "vfe0",
+ "vfe1",
+ "vfe_lite";
+
+ iommus = <&apps_smmu 0x0808 0x0>,
+ <&apps_smmu 0x0810 0x8>,
+ <&apps_smmu 0x0c08 0x0>,
+ <&apps_smmu 0x0c10 0x8>;
+
+ power-domains = <&clock_camcc IFE_0_GDSC>,
+ <&clock_camcc IFE_1_GDSC>,
+ <&clock_camcc TITAN_TOP_GDSC>;
+
+ reg = <0 0xacb3000 0 0x1000>,
+ <0 0xacba000 0 0x1000>,
+ <0 0xacc8000 0 0x1000>,
+ <0 0xac65000 0 0x1000>,
+ <0 0xac66000 0 0x1000>,
+ <0 0xac67000 0 0x1000>,
+ <0 0xac68000 0 0x1000>,
+ <0 0xacaf000 0 0x4000>,
+ <0 0xacb6000 0 0x4000>,
+ <0 0xacc4000 0 0x4000>;
+
+ reg-names = "csid0",
+ "csid1",
+ "csid2",
+ "csiphy0",
+ "csiphy1",
+ "csiphy2",
+ "csiphy3",
+ "vfe0",
+ "vfe1",
+ "vfe_lite";
+
+ vdda-supply = <&reg_2v8>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
--
2.27.0

2021-01-28 00:05:36

by Robert Foss

[permalink] [raw]
Subject: [PATCH v3 15/22] dt-bindings: media: camss: Add qcom,sdm660-camss binding

Add bindings for qcom,sdm660-camss in order to support the camera
subsystem on SDM630/660 and SDA variants.

Signed-off-by: Robert Foss <[email protected]>
---

Changes since v2
- Rob: Add new line at end of file
- Rob: Remove redundant descriptions
- Rob: Add power domain description
- Rob: Make clock-lanes a constant
- Rob: Rework to conform to new port schema
- Add max & minItems to data-lanes
- Remove ports requirement - endpoint & reg
- Added Angelo as binding maintainer
- Removed Todor as binding maintainer


.../bindings/media/qcom,sdm660-camss.yaml | 398 ++++++++++++++++++
1 file changed, 398 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml

diff --git a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
new file mode 100644
index 000000000000..841a1aafdd13
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
@@ -0,0 +1,398 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/media/qcom,sdm660-camss.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Qualcomm CAMSS ISP
+
+maintainers:
+ - Robert Foss <[email protected]>
+ - AngeloGioacchino Del Regno <[email protected]>
+
+description: |
+ The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms
+
+properties:
+ compatible:
+ const: qcom,sdm660-camss
+
+ clocks:
+ minItems: 42
+ maxItems: 42
+
+ clock-names:
+ items:
+ - const: ahb
+ - const: cphy_csid0
+ - const: cphy_csid1
+ - const: cphy_csid2
+ - const: cphy_csid3
+ - const: csi0_ahb
+ - const: csi0
+ - const: csi0_phy
+ - const: csi0_pix
+ - const: csi0_rdi
+ - const: csi1_ahb
+ - const: csi1
+ - const: csi1_phy
+ - const: csi1_pix
+ - const: csi1_rdi
+ - const: csi2_ahb
+ - const: csi2
+ - const: csi2_phy
+ - const: csi2_pix
+ - const: csi2_rdi
+ - const: csi3_ahb
+ - const: csi3
+ - const: csi3_phy
+ - const: csi3_pix
+ - const: csi3_rdi
+ - const: csiphy0_timer
+ - const: csiphy1_timer
+ - const: csiphy2_timer
+ - const: csiphy_ahb2crif
+ - const: csi_vfe0
+ - const: csi_vfe1
+ - const: ispif_ahb
+ - const: throttle_axi
+ - const: top_ahb
+ - const: vfe0_ahb
+ - const: vfe0
+ - const: vfe0_stream
+ - const: vfe1_ahb
+ - const: vfe1
+ - const: vfe1_stream
+ - const: vfe_ahb
+ - const: vfe_axi
+
+ interrupts:
+ minItems: 10
+ maxItems: 10
+
+ interrupt-names:
+ items:
+ - const: csid0
+ - const: csid1
+ - const: csid2
+ - const: csid3
+ - const: csiphy0
+ - const: csiphy1
+ - const: csiphy2
+ - const: ispif
+ - const: vfe0
+ - const: vfe1
+
+ iommus:
+ maxItems: 4
+
+ power-domains:
+ items:
+ - description: VFE0 GDSC - Video Front End, Global Distributed Switch Controller.
+ - description: VFE1 GDSC - Video Front End, 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:
+ items:
+ - const: 7
+
+ 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:
+ items:
+ - const: 7
+
+ 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:
+ items:
+ - const: 7
+
+ 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:
+ items:
+ - const: 7
+
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ required:
+ - clock-lanes
+ - data-lanes
+
+ reg:
+ minItems: 14
+ maxItems: 14
+
+ reg-names:
+ items:
+ - const: csi_clk_mux
+ - const: csid0
+ - const: csid1
+ - const: csid2
+ - const: csid3
+ - const: csiphy0
+ - const: csiphy0_clk_mux
+ - const: csiphy1
+ - const: csiphy1_clk_mux
+ - const: csiphy2
+ - const: csiphy2_clk_mux
+ - const: ispif
+ - const: vfe0
+ - const: vfe1
+
+ vdda-supply:
+ description:
+ Definition of the regulator used as analog power supply.
+
+required:
+ - clock-names
+ - clocks
+ - compatible
+ - interrupt-names
+ - interrupts
+ - iommus
+ - power-domains
+ - reg
+ - reg-names
+ - vdda-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/qcom,gcc-sdm660.h>
+ #include <dt-bindings/clock/qcom,mmcc-sdm660.h>
+
+ camss: camss@ca00000 {
+ compatible = "qcom,sdm660-camss";
+
+ clocks = <&mmcc CAMSS_AHB_CLK>,
+ <&mmcc CAMSS_CPHY_CSID0_CLK>,
+ <&mmcc CAMSS_CPHY_CSID1_CLK>,
+ <&mmcc CAMSS_CPHY_CSID2_CLK>,
+ <&mmcc CAMSS_CPHY_CSID3_CLK>,
+ <&mmcc CAMSS_CSI0_AHB_CLK>,
+ <&mmcc CAMSS_CSI0_CLK>,
+ <&mmcc CAMSS_CPHY_CSID0_CLK>,
+ <&mmcc CAMSS_CSI0PIX_CLK>,
+ <&mmcc CAMSS_CSI0RDI_CLK>,
+ <&mmcc CAMSS_CSI1_AHB_CLK>,
+ <&mmcc CAMSS_CSI1_CLK>,
+ <&mmcc CAMSS_CPHY_CSID1_CLK>,
+ <&mmcc CAMSS_CSI1PIX_CLK>,
+ <&mmcc CAMSS_CSI1RDI_CLK>,
+ <&mmcc CAMSS_CSI2_AHB_CLK>,
+ <&mmcc CAMSS_CSI2_CLK>,
+ <&mmcc CAMSS_CPHY_CSID2_CLK>,
+ <&mmcc CAMSS_CSI2PIX_CLK>,
+ <&mmcc CAMSS_CSI2RDI_CLK>,
+ <&mmcc CAMSS_CSI3_AHB_CLK>,
+ <&mmcc CAMSS_CSI3_CLK>,
+ <&mmcc CAMSS_CPHY_CSID3_CLK>,
+ <&mmcc CAMSS_CSI3PIX_CLK>,
+ <&mmcc CAMSS_CSI3RDI_CLK>,
+ <&mmcc CAMSS_CSI0PHYTIMER_CLK>,
+ <&mmcc CAMSS_CSI1PHYTIMER_CLK>,
+ <&mmcc CAMSS_CSI2PHYTIMER_CLK>,
+ <&mmcc CSIPHY_AHB2CRIF_CLK>,
+ <&mmcc CAMSS_CSI_VFE0_CLK>,
+ <&mmcc CAMSS_CSI_VFE1_CLK>,
+ <&mmcc CAMSS_ISPIF_AHB_CLK>,
+ <&mmcc THROTTLE_CAMSS_AXI_CLK>,
+ <&mmcc CAMSS_TOP_AHB_CLK>,
+ <&mmcc CAMSS_VFE0_AHB_CLK>,
+ <&mmcc CAMSS_VFE0_CLK>,
+ <&mmcc CAMSS_VFE0_STREAM_CLK>,
+ <&mmcc CAMSS_VFE1_AHB_CLK>,
+ <&mmcc CAMSS_VFE1_CLK>,
+ <&mmcc CAMSS_VFE1_STREAM_CLK>,
+ <&mmcc CAMSS_VFE_VBIF_AHB_CLK>,
+ <&mmcc CAMSS_VFE_VBIF_AXI_CLK>;
+
+ clock-names = "ahb",
+ "cphy_csid0",
+ "cphy_csid1",
+ "cphy_csid2",
+ "cphy_csid3",
+ "csi0_ahb",
+ "csi0",
+ "csi0_phy",
+ "csi0_pix",
+ "csi0_rdi",
+ "csi1_ahb",
+ "csi1",
+ "csi1_phy",
+ "csi1_pix",
+ "csi1_rdi",
+ "csi2_ahb",
+ "csi2",
+ "csi2_phy",
+ "csi2_pix",
+ "csi2_rdi",
+ "csi3_ahb",
+ "csi3",
+ "csi3_phy",
+ "csi3_pix",
+ "csi3_rdi",
+ "csiphy0_timer",
+ "csiphy1_timer",
+ "csiphy2_timer",
+ "csiphy_ahb2crif",
+ "csi_vfe0",
+ "csi_vfe1",
+ "ispif_ahb",
+ "throttle_axi",
+ "top_ahb",
+ "vfe0_ahb",
+ "vfe0",
+ "vfe0_stream",
+ "vfe1_ahb",
+ "vfe1",
+ "vfe1_stream",
+ "vfe_ahb",
+ "vfe_axi";
+
+ interrupts = <GIC_SPI 296 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 297 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 298 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 299 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 78 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 79 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 80 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 309 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 314 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 315 IRQ_TYPE_EDGE_RISING>;
+
+ interrupt-names = "csid0",
+ "csid1",
+ "csid2",
+ "csid3",
+ "csiphy0",
+ "csiphy1",
+ "csiphy2",
+ "ispif",
+ "vfe0",
+ "vfe1";
+
+ iommus = <&mmss_smmu 0xc00>,
+ <&mmss_smmu 0xc01>,
+ <&mmss_smmu 0xc02>,
+ <&mmss_smmu 0xc03>;
+
+ power-domains = <&mmcc CAMSS_VFE0_GDSC>,
+ <&mmcc CAMSS_VFE1_GDSC>;
+
+ reg = <0x0ca00020 0x10>,
+ <0x0ca30000 0x100>,
+ <0x0ca30400 0x100>,
+ <0x0ca30800 0x100>,
+ <0x0ca30c00 0x100>,
+ <0x0c824000 0x1000>,
+ <0x0ca00120 0x4>,
+ <0x0c825000 0x1000>,
+ <0x0ca00124 0x4>,
+ <0x0c826000 0x1000>,
+ <0x0ca00128 0x4>,
+ <0x0ca31000 0x500>,
+ <0x0ca10000 0x1000>,
+ <0x0ca14000 0x1000>;
+
+ reg-names = "csi_clk_mux",
+ "csid0",
+ "csid1",
+ "csid2",
+ "csid3",
+ "csiphy0",
+ "csiphy0_clk_mux",
+ "csiphy1",
+ "csiphy1_clk_mux",
+ "csiphy2",
+ "csiphy2_clk_mux",
+ "ispif",
+ "vfe0",
+ "vfe1";
+
+ vdda-supply = <&reg_2v8>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
--
2.27.0

2021-01-28 00:05:36

by Robert Foss

[permalink] [raw]
Subject: [PATCH v3 13/22] dt-bindings: media: camss: Add qcom,msm8916-camss binding

Add bindings for qcom,msm8916-camss in order to support the camera
subsystem on MSM8916.

Signed-off-by: Robert Foss <[email protected]>
---

Changes since v2:
- Remove redundant descriptions
- Add power domain description
- Make clock-lanes a constant
- Add max & minItems to data-lanes
- Remove ports requirement - endpoint & reg
- Rework to conform to new port schema


.../bindings/media/qcom,msm8916-camss.yaml | 256 ++++++++++++++++++
1 file changed, 256 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml

diff --git a/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
new file mode 100644
index 000000000000..304908072d72
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
@@ -0,0 +1,256 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/media/qcom,msm8916-camss.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Qualcomm CAMSS ISP
+
+maintainers:
+ - Robert Foss <[email protected]>
+ - Todor Tomov <[email protected]>
+
+description: |
+ The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms
+
+properties:
+ compatible:
+ const: qcom,msm8916-camss
+
+ clocks:
+ minItems: 19
+ maxItems: 19
+
+ clock-names:
+ items:
+ - const: top_ahb
+ - const: ispif_ahb
+ - const: csiphy0_timer
+ - const: csiphy1_timer
+ - const: csi0_ahb
+ - const: csi0
+ - const: csi0_phy
+ - const: csi0_pix
+ - const: csi0_rdi
+ - const: csi1_ahb
+ - const: csi1
+ - const: csi1_phy
+ - const: csi1_pix
+ - const: csi1_rdi
+ - const: ahb
+ - const: vfe0
+ - const: csi_vfe0
+ - const: vfe_ahb
+ - const: vfe_axi
+
+ interrupts:
+ minItems: 6
+ maxItems: 6
+
+ interrupt-names:
+ items:
+ - const: csiphy0
+ - const: csiphy1
+ - const: csid0
+ - const: csid1
+ - const: ispif
+ - const: vfe0
+
+ iommus:
+ maxItems: 1
+
+ power-domains:
+ items:
+ - description: VFE GDSC - Video Front End, 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:
+ items:
+ - const: 1
+
+ data-lanes:
+ description:
+ An array of physical data lanes indexes.
+ Position of an entry determines the logical
+ lane number, while the value of an entry
+ indicates physical lane index. Lane swapping
+ is supported. Physical lane indexes;
+ 0, 2, 3, 4.
+ 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:
+ items:
+ - const: 1
+
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ required:
+ - clock-lanes
+ - data-lanes
+
+ reg:
+ minItems: 9
+ maxItems: 9
+
+ reg-names:
+ items:
+ - const: csiphy0
+ - const: csiphy0_clk_mux
+ - const: csiphy1
+ - const: csiphy1_clk_mux
+ - const: csid0
+ - const: csid1
+ - const: ispif
+ - const: csi_clk_mux
+ - const: vfe0
+
+ vdda-supply:
+ description:
+ Definition of the regulator used as analog power supply.
+
+required:
+ - clock-names
+ - clocks
+ - compatible
+ - interrupt-names
+ - interrupts
+ - iommus
+ - power-domains
+ - reg
+ - reg-names
+ - vdda-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/qcom,gcc-msm8916.h>
+
+ camss: camss@1b00000 {
+ compatible = "qcom,msm8916-camss";
+
+ clocks = <&gcc GCC_CAMSS_TOP_AHB_CLK>,
+ <&gcc GCC_CAMSS_ISPIF_AHB_CLK>,
+ <&gcc GCC_CAMSS_CSI0PHYTIMER_CLK>,
+ <&gcc GCC_CAMSS_CSI1PHYTIMER_CLK>,
+ <&gcc GCC_CAMSS_CSI0_AHB_CLK>,
+ <&gcc GCC_CAMSS_CSI0_CLK>,
+ <&gcc GCC_CAMSS_CSI0PHY_CLK>,
+ <&gcc GCC_CAMSS_CSI0PIX_CLK>,
+ <&gcc GCC_CAMSS_CSI0RDI_CLK>,
+ <&gcc GCC_CAMSS_CSI1_AHB_CLK>,
+ <&gcc GCC_CAMSS_CSI1_CLK>,
+ <&gcc GCC_CAMSS_CSI1PHY_CLK>,
+ <&gcc GCC_CAMSS_CSI1PIX_CLK>,
+ <&gcc GCC_CAMSS_CSI1RDI_CLK>,
+ <&gcc GCC_CAMSS_AHB_CLK>,
+ <&gcc GCC_CAMSS_VFE0_CLK>,
+ <&gcc GCC_CAMSS_CSI_VFE0_CLK>,
+ <&gcc GCC_CAMSS_VFE_AHB_CLK>,
+ <&gcc GCC_CAMSS_VFE_AXI_CLK>;
+
+ clock-names = "top_ahb",
+ "ispif_ahb",
+ "csiphy0_timer",
+ "csiphy1_timer",
+ "csi0_ahb",
+ "csi0",
+ "csi0_phy",
+ "csi0_pix",
+ "csi0_rdi",
+ "csi1_ahb",
+ "csi1",
+ "csi1_phy",
+ "csi1_pix",
+ "csi1_rdi",
+ "ahb",
+ "vfe0",
+ "csi_vfe0",
+ "vfe_ahb",
+ "vfe_axi";
+
+ interrupts = <GIC_SPI 78 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 79 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 51 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 52 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 55 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 57 IRQ_TYPE_EDGE_RISING>;
+
+ interrupt-names = "csiphy0",
+ "csiphy1",
+ "csid0",
+ "csid1",
+ "ispif",
+ "vfe0";
+
+ iommus = <&apps_iommu 3>;
+
+ power-domains = <&gcc VFE_GDSC>;
+
+ reg = <0x01b0ac00 0x200>,
+ <0x01b00030 0x4>,
+ <0x01b0b000 0x200>,
+ <0x01b00038 0x4>,
+ <0x01b08000 0x100>,
+ <0x01b08400 0x100>,
+ <0x01b0a000 0x500>,
+ <0x01b00020 0x10>,
+ <0x01b10000 0x1000>;
+
+ reg-names = "csiphy0",
+ "csiphy0_clk_mux",
+ "csiphy1",
+ "csiphy1_clk_mux",
+ "csid0",
+ "csid1",
+ "ispif",
+ "csi_clk_mux",
+ "vfe0";
+
+ vdda-supply = <&reg_2v8>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ };
--
2.27.0

2021-01-28 00:05:41

by Robert Foss

[permalink] [raw]
Subject: [PATCH v3 14/22] dt-bindings: media: camss: Add qcom,msm8996-camss binding

Add bindings for qcom,msm8996-camss in order to support the camera
subsystem on MSM8996.

Signed-off-by: Robert Foss <[email protected]>
---

Changes since v2
- Rob: Add new line at end of file
- Rob: Remove redundant descriptions
- Rob: Add power domain description
- Rob: Make clock-lanes a constant
- Rob: Rework to conform to new port schema
- Add max & minItems to data-lanes
- Remove ports requirement - endpoint & reg


.../bindings/media/qcom,msm8996-camss.yaml | 387 ++++++++++++++++++
1 file changed, 387 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml

diff --git a/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
new file mode 100644
index 000000000000..38be41e932f0
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
@@ -0,0 +1,387 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/media/qcom,msm8996-camss.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Qualcomm CAMSS ISP
+
+maintainers:
+ - Robert Foss <[email protected]>
+ - Todor Tomov <[email protected]>
+
+description: |
+ The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms
+
+properties:
+ compatible:
+ const: qcom,msm8996-camss
+
+ clocks:
+ minItems: 36
+ maxItems: 36
+
+ clock-names:
+ items:
+ - const: top_ahb
+ - const: ispif_ahb
+ - const: csiphy0_timer
+ - const: csiphy1_timer
+ - const: csiphy2_timer
+ - const: csi0_ahb
+ - const: csi0
+ - const: csi0_phy
+ - const: csi0_pix
+ - const: csi0_rdi
+ - const: csi1_ahb
+ - const: csi1
+ - const: csi1_phy
+ - const: csi1_pix
+ - const: csi1_rdi
+ - const: csi2_ahb
+ - const: csi2
+ - const: csi2_phy
+ - const: csi2_pix
+ - const: csi2_rdi
+ - const: csi3_ahb
+ - const: csi3
+ - const: csi3_phy
+ - const: csi3_pix
+ - const: csi3_rdi
+ - const: ahb
+ - const: vfe0
+ - const: csi_vfe0
+ - const: vfe0_ahb
+ - const: vfe0_stream
+ - const: vfe1
+ - const: csi_vfe1
+ - const: vfe1_ahb
+ - const: vfe1_stream
+ - const: vfe_ahb
+ - const: vfe_axi
+
+ interrupts:
+ minItems: 10
+ maxItems: 10
+
+ interrupt-names:
+ items:
+ - const: csiphy0
+ - const: csiphy1
+ - const: csiphy2
+ - const: csid0
+ - const: csid1
+ - const: csid2
+ - const: csid3
+ - const: ispif
+ - const: vfe0
+ - const: vfe1
+
+ iommus:
+ maxItems: 4
+
+ power-domains:
+ items:
+ - description: VFE0 GDSC - Video Front End, Global Distributed Switch Controller.
+ - description: VFE1 GDSC - Video Front End, 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:
+ items:
+ - const: 7
+
+ data-lanes:
+ description:
+ An array of physical data lanes indexes.
+ Position of an entry determines the logical
+ lane number, while the value of an entry
+ indicates physical lane index. Lane swapping
+ is supported. Physical lane indexes are;
+ 0, 1, 2, 3
+ 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:
+ items:
+ - const: 7
+
+ 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:
+ items:
+ - const: 7
+
+ 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:
+ items:
+ - const: 7
+
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ required:
+ - clock-lanes
+ - data-lanes
+
+ reg:
+ minItems: 14
+ maxItems: 14
+
+ reg-names:
+ items:
+ - const: csiphy0
+ - const: csiphy0_clk_mux
+ - const: csiphy1
+ - const: csiphy1_clk_mux
+ - const: csiphy2
+ - const: csiphy2_clk_mux
+ - const: csid0
+ - const: csid1
+ - const: csid2
+ - const: csid3
+ - const: ispif
+ - const: csi_clk_mux
+ - const: vfe0
+ - const: vfe1
+
+ vdda-supply:
+ description:
+ Definition of the regulator used as analog power supply.
+
+required:
+ - clock-names
+ - clocks
+ - compatible
+ - interrupt-names
+ - interrupts
+ - iommus
+ - power-domains
+ - reg
+ - reg-names
+ - vdda-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/qcom,gcc-msm8996.h>
+ #include <dt-bindings/clock/qcom,mmcc-msm8996.h>
+
+ camss: camss@a00000 {
+ compatible = "qcom,msm8996-camss";
+
+ clocks = <&mmcc CAMSS_TOP_AHB_CLK>,
+ <&mmcc CAMSS_ISPIF_AHB_CLK>,
+ <&mmcc CAMSS_CSI0PHYTIMER_CLK>,
+ <&mmcc CAMSS_CSI1PHYTIMER_CLK>,
+ <&mmcc CAMSS_CSI2PHYTIMER_CLK>,
+ <&mmcc CAMSS_CSI0_AHB_CLK>,
+ <&mmcc CAMSS_CSI0_CLK>,
+ <&mmcc CAMSS_CSI0PHY_CLK>,
+ <&mmcc CAMSS_CSI0PIX_CLK>,
+ <&mmcc CAMSS_CSI0RDI_CLK>,
+ <&mmcc CAMSS_CSI1_AHB_CLK>,
+ <&mmcc CAMSS_CSI1_CLK>,
+ <&mmcc CAMSS_CSI1PHY_CLK>,
+ <&mmcc CAMSS_CSI1PIX_CLK>,
+ <&mmcc CAMSS_CSI1RDI_CLK>,
+ <&mmcc CAMSS_CSI2_AHB_CLK>,
+ <&mmcc CAMSS_CSI2_CLK>,
+ <&mmcc CAMSS_CSI2PHY_CLK>,
+ <&mmcc CAMSS_CSI2PIX_CLK>,
+ <&mmcc CAMSS_CSI2RDI_CLK>,
+ <&mmcc CAMSS_CSI3_AHB_CLK>,
+ <&mmcc CAMSS_CSI3_CLK>,
+ <&mmcc CAMSS_CSI3PHY_CLK>,
+ <&mmcc CAMSS_CSI3PIX_CLK>,
+ <&mmcc CAMSS_CSI3RDI_CLK>,
+ <&mmcc CAMSS_AHB_CLK>,
+ <&mmcc CAMSS_VFE0_CLK>,
+ <&mmcc CAMSS_CSI_VFE0_CLK>,
+ <&mmcc CAMSS_VFE0_AHB_CLK>,
+ <&mmcc CAMSS_VFE0_STREAM_CLK>,
+ <&mmcc CAMSS_VFE1_CLK>,
+ <&mmcc CAMSS_CSI_VFE1_CLK>,
+ <&mmcc CAMSS_VFE1_AHB_CLK>,
+ <&mmcc CAMSS_VFE1_STREAM_CLK>,
+ <&mmcc CAMSS_VFE_AHB_CLK>,
+ <&mmcc CAMSS_VFE_AXI_CLK>;
+
+ clock-names = "top_ahb",
+ "ispif_ahb",
+ "csiphy0_timer",
+ "csiphy1_timer",
+ "csiphy2_timer",
+ "csi0_ahb",
+ "csi0",
+ "csi0_phy",
+ "csi0_pix",
+ "csi0_rdi",
+ "csi1_ahb",
+ "csi1",
+ "csi1_phy",
+ "csi1_pix",
+ "csi1_rdi",
+ "csi2_ahb",
+ "csi2",
+ "csi2_phy",
+ "csi2_pix",
+ "csi2_rdi",
+ "csi3_ahb",
+ "csi3",
+ "csi3_phy",
+ "csi3_pix",
+ "csi3_rdi",
+ "ahb",
+ "vfe0",
+ "csi_vfe0",
+ "vfe0_ahb",
+ "vfe0_stream",
+ "vfe1",
+ "csi_vfe1",
+ "vfe1_ahb",
+ "vfe1_stream",
+ "vfe_ahb",
+ "vfe_axi";
+
+ interrupts = <GIC_SPI 78 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 79 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 80 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 296 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 297 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 298 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 299 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 309 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 314 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 315 IRQ_TYPE_EDGE_RISING>;
+
+ interrupt-names = "csiphy0",
+ "csiphy1",
+ "csiphy2",
+ "csid0",
+ "csid1",
+ "csid2",
+ "csid3",
+ "ispif",
+ "vfe0",
+ "vfe1";
+
+ iommus = <&vfe_smmu 0>,
+ <&vfe_smmu 1>,
+ <&vfe_smmu 2>,
+ <&vfe_smmu 3>;
+
+ power-domains = <&mmcc VFE0_GDSC>,
+ <&mmcc VFE1_GDSC>;
+
+ reg = <0x00a34000 0x1000>,
+ <0x00a00030 0x4>,
+ <0x00a35000 0x1000>,
+ <0x00a00038 0x4>,
+ <0x00a36000 0x1000>,
+ <0x00a00040 0x4>,
+ <0x00a30000 0x100>,
+ <0x00a30400 0x100>,
+ <0x00a30800 0x100>,
+ <0x00a30c00 0x100>,
+ <0x00a31000 0x500>,
+ <0x00a00020 0x10>,
+ <0x00a10000 0x1000>,
+ <0x00a14000 0x1000>;
+
+ reg-names = "csiphy0",
+ "csiphy0_clk_mux",
+ "csiphy1",
+ "csiphy1_clk_mux",
+ "csiphy2",
+ "csiphy2_clk_mux",
+ "csid0",
+ "csid1",
+ "csid2",
+ "csid3",
+ "ispif",
+ "csi_clk_mux",
+ "vfe0",
+ "vfe1";
+
+ vdda-supply = <&reg_2v8>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
--
2.27.0

2021-01-28 00:05:50

by Robert Foss

[permalink] [raw]
Subject: [PATCH v3 08/22] media: camss: Refactor CSID HW version support

In order to support Qualcomm ISP hardware architectures that diverge
from older architectures, the CSID subdevice drivers needs to be refactored
to better abstract the different ISP hardware architectures.

Signed-off-by: Robert Foss <[email protected]>
---

Changes since v1
- kernel test robot: Add missing include, interrupt.h


drivers/media/platform/qcom/camss/Makefile | 2 +
.../platform/qcom/camss/camss-csid-4-1.c | 338 ++++++++++
.../platform/qcom/camss/camss-csid-4-7.c | 406 ++++++++++++
.../media/platform/qcom/camss/camss-csid.c | 616 +-----------------
.../media/platform/qcom/camss/camss-csid.h | 126 +++-
5 files changed, 898 insertions(+), 590 deletions(-)
create mode 100644 drivers/media/platform/qcom/camss/camss-csid-4-1.c
create mode 100644 drivers/media/platform/qcom/camss/camss-csid-4-7.c

diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
index 052c4f405fa3..cff388b653ba 100644
--- a/drivers/media/platform/qcom/camss/Makefile
+++ b/drivers/media/platform/qcom/camss/Makefile
@@ -4,6 +4,8 @@
qcom-camss-objs += \
camss.o \
camss-csid.o \
+ camss-csid-4-1.o \
+ camss-csid-4-7.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-4-1.c b/drivers/media/platform/qcom/camss/camss-csid-4-1.c
new file mode 100644
index 000000000000..84b415137555
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-csid-4-1.c
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-csid-4-1.c
+ *
+ * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
+ *
+ * Copyright (C) 2020 Linaro Ltd.
+ */
+ #include <linux/completion.h>
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
+ #include <linux/of.h>
+
+#include "camss-csid.h"
+#include "camss.h"
+
+#define CAMSS_CSID_HW_VERSION 0x0
+#define CAMSS_CSID_CORE_CTRL_0 0x004
+#define CAMSS_CSID_CORE_CTRL_1 0x008
+#define CAMSS_CSID_RST_CMD 0x00c
+#define CAMSS_CSID_CID_LUT_VC_n(n) (0x010 + 0x4 * (n))
+#define CAMSS_CSID_CID_n_CFG(n) (0x020 + 0x4 * (n))
+#define CAMSS_CSID_CID_n_CFG_ISPIF_EN BIT(0)
+#define CAMSS_CSID_CID_n_CFG_RDI_EN BIT(1)
+#define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT 4
+#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8 (0 << 8)
+#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (1 << 8)
+#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB (0 << 9)
+#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB (1 << 9)
+#define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP (0 << 10)
+#define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING (1 << 10)
+#define CAMSS_CSID_IRQ_CLEAR_CMD 0x060
+#define CAMSS_CSID_IRQ_MASK 0x064
+#define CAMSS_CSID_IRQ_STATUS 0x068
+#define CAMSS_CSID_TG_CTRL 0x0a0
+#define CAMSS_CSID_TG_CTRL_DISABLE 0xa06436
+#define CAMSS_CSID_TG_CTRL_ENABLE 0xa06437
+#define CAMSS_CSID_TG_VC_CFG 0x0a4
+#define CAMSS_CSID_TG_VC_CFG_H_BLANKING 0x3ff
+#define CAMSS_CSID_TG_VC_CFG_V_BLANKING 0x7f
+#define CAMSS_CSID_TG_DT_n_CGG_0(n) (0x0ac + 0xc * (n))
+#define CAMSS_CSID_TG_DT_n_CGG_1(n) (0x0b0 + 0xc * (n))
+#define CAMSS_CSID_TG_DT_n_CGG_2(n) (0x0b4 + 0xc * (n))
+
+
+enum csid_testgen_pattern {
+ TESTGEN_PATTERN_INCREMENTING = 0,
+ TESTGEN_PATTERN_ALTERNATING_55_AA = 1,
+ TESTGEN_PATTERN_ALL_ZEROES = 2,
+ TESTGEN_PATTERN_ALL_ONES = 3,
+ TESTGEN_PATTERN_RANDOM = 4,
+ TESTGEN_PATTERN_USER_SPECIFIED = 5,
+};
+
+static const struct csid_format csid_formats[] = {
+ {
+ MEDIA_BUS_FMT_UYVY8_2X8,
+ DATA_TYPE_YUV422_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 2,
+ },
+ {
+ MEDIA_BUS_FMT_VYUY8_2X8,
+ DATA_TYPE_YUV422_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 2,
+ },
+ {
+ MEDIA_BUS_FMT_YUYV8_2X8,
+ DATA_TYPE_YUV422_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 2,
+ },
+ {
+ MEDIA_BUS_FMT_YVYU8_2X8,
+ DATA_TYPE_YUV422_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 2,
+ },
+ {
+ MEDIA_BUS_FMT_SBGGR8_1X8,
+ DATA_TYPE_RAW_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGBRG8_1X8,
+ DATA_TYPE_RAW_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGRBG8_1X8,
+ DATA_TYPE_RAW_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SRGGB8_1X8,
+ DATA_TYPE_RAW_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SBGGR10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGBRG10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGRBG10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SRGGB10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SBGGR12_1X12,
+ DATA_TYPE_RAW_12BIT,
+ DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+ 12,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGBRG12_1X12,
+ DATA_TYPE_RAW_12BIT,
+ DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+ 12,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGRBG12_1X12,
+ DATA_TYPE_RAW_12BIT,
+ DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+ 12,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SRGGB12_1X12,
+ DATA_TYPE_RAW_12BIT,
+ DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+ 12,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_Y10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+};
+
+static void csid_configure_stream(struct csid_device *csid, u8 enable)
+{
+ struct csid_testgen_config *tg = &csid->testgen;
+ u32 val;
+
+ if (enable) {
+ struct v4l2_mbus_framefmt *input_format;
+ const struct csid_format *format;
+ u8 vc = 0; /* Virtual Channel 0 */
+ u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */
+ u8 dt_shift;
+
+ if (tg->enabled) {
+ /* Config Test Generator */
+ u32 num_lines, num_bytes_per_line;
+
+ input_format = &csid->fmt[MSM_CSID_PAD_SRC];
+ format = csid_get_fmt_entry(csid->formats, csid->nformats,
+ input_format->code);
+ num_bytes_per_line = input_format->width * format->bpp * format->spp / 8;
+ num_lines = input_format->height;
+
+ /* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */
+ /* 1:0 VC */
+ val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) |
+ ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13);
+ writel_relaxed(val, csid->base + CAMSS_CSID_TG_VC_CFG);
+
+ /* 28:16 bytes per lines, 12:0 num of lines */
+ val = ((num_bytes_per_line & 0x1fff) << 16) |
+ (num_lines & 0x1fff);
+ writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_0(0));
+
+ /* 5:0 data type */
+ val = format->data_type;
+ writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_1(0));
+
+ /* 2:0 output test pattern */
+ val = tg->mode;
+ writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_2(0));
+ } else {
+ struct csid_phy_config *phy = &csid->phy;
+
+ input_format = &csid->fmt[MSM_CSID_PAD_SINK];
+ format = csid_get_fmt_entry(csid->formats, csid->nformats,
+ input_format->code);
+
+ val = phy->lane_cnt - 1;
+ val |= phy->lane_assign << 4;
+
+ writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_0);
+
+ val = phy->csiphy_id << 17;
+ val |= 0x9;
+
+ writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_1);
+ }
+
+ /* Config LUT */
+
+ dt_shift = (cid % 4) * 8;
+ val = readl_relaxed(csid->base + CAMSS_CSID_CID_LUT_VC_n(vc));
+ val &= ~(0xff << dt_shift);
+ val |= format->data_type << dt_shift;
+ writel_relaxed(val, csid->base + CAMSS_CSID_CID_LUT_VC_n(vc));
+
+ val = CAMSS_CSID_CID_n_CFG_ISPIF_EN;
+ val |= CAMSS_CSID_CID_n_CFG_RDI_EN;
+ val |= format->decode_format << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT;
+ val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP;
+ writel_relaxed(val, csid->base + CAMSS_CSID_CID_n_CFG(cid));
+
+ if (tg->enabled) {
+ val = CAMSS_CSID_TG_CTRL_ENABLE;
+ writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL);
+ }
+ } else {
+ if (tg->enabled) {
+ val = CAMSS_CSID_TG_CTRL_DISABLE;
+ writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL);
+ }
+ }
+}
+
+static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val)
+{
+ s32 regval = val - 1;
+
+ if (regval > 0 || regval <= CSID_PAYLOAD_MODE_MAX_SUPPORTED_4_1)
+ csid->testgen.mode = regval;
+
+ return 0;
+}
+
+static u32 csid_hw_version(struct csid_device *csid)
+{
+ u32 hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION);
+
+ dev_dbg(csid->camss->dev, "CSID HW Version = 0x%08x\n", hw_version);
+
+ return hw_version;
+}
+
+static irqreturn_t csid_isr(int irq, void *dev)
+{
+ struct csid_device *csid = dev;
+ u32 value;
+
+ value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS);
+ writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD);
+
+ if ((value >> 11) & 0x1)
+ complete(&csid->reset_complete);
+
+ return IRQ_HANDLED;
+}
+
+static int csid_reset(struct csid_device *csid)
+{
+ unsigned long time;
+
+ reinit_completion(&csid->reset_complete);
+
+ writel_relaxed(0x7fff, csid->base + CAMSS_CSID_RST_CMD);
+
+ time = wait_for_completion_timeout(&csid->reset_complete,
+ msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
+ if (!time) {
+ dev_err(csid->camss->dev, "CSID reset timeout\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
+ unsigned int match_format_idx, u32 match_code)
+{
+ if (match_format_idx > 0)
+ return 0;
+
+ return sink_code;
+}
+
+static void csid_subdev_init(struct csid_device *csid)
+{
+ csid->formats = csid_formats;
+ csid->nformats = ARRAY_SIZE(csid_formats);
+ csid->testgen.modes = csid_testgen_modes;
+ csid->testgen.nmodes = CSID_PAYLOAD_MODE_MAX_SUPPORTED_4_1;
+}
+
+const struct csid_hw_ops csid_ops_4_1 = {
+ .configure_stream = csid_configure_stream,
+ .configure_testgen_pattern = csid_configure_testgen_pattern,
+ .hw_version = csid_hw_version,
+ .isr = csid_isr,
+ .reset = csid_reset,
+ .src_pad_code = csid_src_pad_code,
+ .subdev_init = csid_subdev_init,
+};
diff --git a/drivers/media/platform/qcom/camss/camss-csid-4-7.c b/drivers/media/platform/qcom/camss/camss-csid-4-7.c
new file mode 100644
index 000000000000..16a69b140f4e
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-csid-4-7.c
@@ -0,0 +1,406 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-csid-4-7.c
+ *
+ * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
+ *
+ * Copyright (C) 2020 Linaro Ltd.
+ */
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+#include "camss-csid.h"
+#include "camss.h"
+
+#define CAMSS_CSID_HW_VERSION 0x0
+#define CAMSS_CSID_CORE_CTRL_0 0x004
+#define CAMSS_CSID_CORE_CTRL_1 0x008
+#define CAMSS_CSID_RST_CMD 0x010
+#define CAMSS_CSID_CID_LUT_VC_n(n) (0x014 + 0x4 * (n))
+#define CAMSS_CSID_CID_n_CFG(n) (0x024 + 0x4 * (n))
+#define CAMSS_CSID_CID_n_CFG_ISPIF_EN BIT(0)
+#define CAMSS_CSID_CID_n_CFG_RDI_EN BIT(1)
+#define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT 4
+#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8 (0 << 8)
+#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (1 << 8)
+#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB (0 << 9)
+#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB (1 << 9)
+#define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP (0 << 10)
+#define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING (1 << 10)
+#define CAMSS_CSID_IRQ_CLEAR_CMD 0x064
+#define CAMSS_CSID_IRQ_MASK 0x068
+#define CAMSS_CSID_IRQ_STATUS 0x06c
+#define CAMSS_CSID_TG_CTRL 0x0a8
+#define CAMSS_CSID_TG_CTRL_DISABLE 0xa06436
+#define CAMSS_CSID_TG_CTRL_ENABLE 0xa06437
+#define CAMSS_CSID_TG_VC_CFG 0x0ac
+#define CAMSS_CSID_TG_VC_CFG_H_BLANKING 0x3ff
+#define CAMSS_CSID_TG_VC_CFG_V_BLANKING 0x7f
+#define CAMSS_CSID_TG_DT_n_CGG_0(n) (0x0b4 + 0xc * (n))
+#define CAMSS_CSID_TG_DT_n_CGG_1(n) (0x0b8 + 0xc * (n))
+#define CAMSS_CSID_TG_DT_n_CGG_2(n) (0x0bc + 0xc * (n))
+
+
+static const struct csid_format csid_formats[] = {
+ {
+ MEDIA_BUS_FMT_UYVY8_2X8,
+ DATA_TYPE_YUV422_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 2,
+ },
+ {
+ MEDIA_BUS_FMT_VYUY8_2X8,
+ DATA_TYPE_YUV422_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 2,
+ },
+ {
+ MEDIA_BUS_FMT_YUYV8_2X8,
+ DATA_TYPE_YUV422_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 2,
+ },
+ {
+ MEDIA_BUS_FMT_YVYU8_2X8,
+ DATA_TYPE_YUV422_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 2,
+ },
+ {
+ MEDIA_BUS_FMT_SBGGR8_1X8,
+ DATA_TYPE_RAW_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGBRG8_1X8,
+ DATA_TYPE_RAW_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGRBG8_1X8,
+ DATA_TYPE_RAW_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SRGGB8_1X8,
+ DATA_TYPE_RAW_8BIT,
+ DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+ 8,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SBGGR10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGBRG10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGRBG10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SRGGB10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SBGGR12_1X12,
+ DATA_TYPE_RAW_12BIT,
+ DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+ 12,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGBRG12_1X12,
+ DATA_TYPE_RAW_12BIT,
+ DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+ 12,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGRBG12_1X12,
+ DATA_TYPE_RAW_12BIT,
+ DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+ 12,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SRGGB12_1X12,
+ DATA_TYPE_RAW_12BIT,
+ DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+ 12,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SBGGR14_1X14,
+ DATA_TYPE_RAW_14BIT,
+ DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+ 14,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGBRG14_1X14,
+ DATA_TYPE_RAW_14BIT,
+ DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+ 14,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SGRBG14_1X14,
+ DATA_TYPE_RAW_14BIT,
+ DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+ 14,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_SRGGB14_1X14,
+ DATA_TYPE_RAW_14BIT,
+ DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+ 14,
+ 1,
+ },
+ {
+ MEDIA_BUS_FMT_Y10_1X10,
+ DATA_TYPE_RAW_10BIT,
+ DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+ 10,
+ 1,
+ },
+};
+
+static void csid_configure_stream(struct csid_device *csid, u8 enable)
+{
+ struct csid_testgen_config *tg = &csid->testgen;
+ u32 sink_code = csid->fmt[MSM_CSID_PAD_SINK].code;
+ u32 src_code = csid->fmt[MSM_CSID_PAD_SRC].code;
+ u32 val;
+
+ if (enable) {
+ struct v4l2_mbus_framefmt *input_format;
+ const struct csid_format *format;
+ u8 vc = 0; /* Virtual Channel 0 */
+ u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */
+ u8 dt_shift;
+
+ if (tg->enabled) {
+ /* Config Test Generator */
+ u32 num_bytes_per_line, num_lines;
+
+ input_format = &csid->fmt[MSM_CSID_PAD_SRC];
+ format = csid_get_fmt_entry(csid->formats, csid->nformats,
+ input_format->code);
+ num_bytes_per_line = input_format->width * format->bpp * format->spp / 8;
+ num_lines = input_format->height;
+
+ /* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */
+ /* 1:0 VC */
+ val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) |
+ ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13);
+ writel_relaxed(val, csid->base + CAMSS_CSID_TG_VC_CFG);
+
+ /* 28:16 bytes per lines, 12:0 num of lines */
+ val = ((num_bytes_per_line & 0x1fff) << 16) |
+ (num_lines & 0x1fff);
+ writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_0(0));
+
+ /* 5:0 data type */
+ val = format->data_type;
+ writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_1(0));
+
+ /* 2:0 output test pattern */
+ val = tg->mode;
+ writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_2(0));
+ } else {
+ struct csid_phy_config *phy = &csid->phy;
+
+ input_format = &csid->fmt[MSM_CSID_PAD_SINK];
+ format = csid_get_fmt_entry(csid->formats, csid->nformats,
+ input_format->code);
+
+ val = phy->lane_cnt - 1;
+ val |= phy->lane_assign << 4;
+
+ writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_0);
+
+ val = phy->csiphy_id << 17;
+ val |= 0x9;
+
+ writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_1);
+ }
+
+ /* Config LUT */
+
+ dt_shift = (cid % 4) * 8;
+
+ val = readl_relaxed(csid->base + CAMSS_CSID_CID_LUT_VC_n(vc));
+ val &= ~(0xff << dt_shift);
+ val |= format->data_type << dt_shift;
+ writel_relaxed(val, csid->base + CAMSS_CSID_CID_LUT_VC_n(vc));
+
+ val = CAMSS_CSID_CID_n_CFG_ISPIF_EN;
+ val |= CAMSS_CSID_CID_n_CFG_RDI_EN;
+ val |= format->decode_format << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT;
+ val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP;
+
+ if ((sink_code == MEDIA_BUS_FMT_SBGGR10_1X10 &&
+ src_code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) ||
+ (sink_code == MEDIA_BUS_FMT_Y10_1X10 &&
+ src_code == MEDIA_BUS_FMT_Y10_2X8_PADHI_LE)) {
+ val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING;
+ val |= CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16;
+ val |= CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB;
+ }
+
+ writel_relaxed(val, csid->base + CAMSS_CSID_CID_n_CFG(cid));
+
+ if (tg->enabled) {
+ val = CAMSS_CSID_TG_CTRL_ENABLE;
+ writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL);
+ }
+ } else {
+ if (tg->enabled) {
+ val = CAMSS_CSID_TG_CTRL_DISABLE;
+ writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL);
+ }
+ }
+}
+
+static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val)
+{
+ s32 regval = val - 1;
+
+ if (regval > 0 || regval <= CSID_PAYLOAD_MODE_MAX_SUPPORTED_4_7)
+ csid->testgen.mode = regval;
+
+ return 0;
+}
+
+static u32 csid_hw_version(struct csid_device *csid)
+{
+ u32 hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION);
+
+ dev_dbg(csid->camss->dev, "CSID HW Version = 0x%08x\n", hw_version);
+
+ return hw_version;
+}
+
+/*
+ * isr - CSID module interrupt service routine
+ * @irq: Interrupt line
+ * @dev: CSID device
+ *
+ * Return IRQ_HANDLED on success
+ */
+static irqreturn_t csid_isr(int irq, void *dev)
+{
+ struct csid_device *csid = dev;
+ u32 value;
+
+ value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS);
+ writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD);
+
+ if ((value >> 11) & 0x1)
+ complete(&csid->reset_complete);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * csid_reset - Trigger reset on CSID module and wait to complete
+ * @csid: CSID device
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int csid_reset(struct csid_device *csid)
+{
+ unsigned long time;
+
+ reinit_completion(&csid->reset_complete);
+
+ writel_relaxed(0x7fff, csid->base + CAMSS_CSID_RST_CMD);
+
+ time = wait_for_completion_timeout(&csid->reset_complete,
+ msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
+ if (!time) {
+ dev_err(csid->camss->dev, "CSID reset timeout\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
+ unsigned int match_format_idx, u32 match_code)
+{
+ switch (sink_code) {
+ case MEDIA_BUS_FMT_SBGGR10_1X10:
+ {
+ u32 src_code[] = {
+ MEDIA_BUS_FMT_SBGGR10_1X10,
+ MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE,
+ };
+
+ return csid_find_code(src_code, ARRAY_SIZE(src_code),
+ match_format_idx, match_code);
+ }
+ case MEDIA_BUS_FMT_Y10_1X10:
+ {
+ u32 src_code[] = {
+ MEDIA_BUS_FMT_Y10_1X10,
+ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE,
+ };
+
+ return csid_find_code(src_code, ARRAY_SIZE(src_code),
+ match_format_idx, match_code);
+ }
+ default:
+ if (match_format_idx > 0)
+ return 0;
+
+ return sink_code;
+ }
+}
+
+static void csid_subdev_init(struct csid_device *csid)
+{
+ csid->formats = csid_formats;
+ csid->nformats = ARRAY_SIZE(csid_formats);
+ csid->testgen.modes = csid_testgen_modes;
+ csid->testgen.nmodes = CSID_PAYLOAD_MODE_MAX_SUPPORTED_4_7;
+}
+
+const struct csid_hw_ops csid_ops_4_7 = {
+ .configure_stream = csid_configure_stream,
+ .configure_testgen_pattern = csid_configure_testgen_pattern,
+ .hw_version = csid_hw_version,
+ .isr = csid_isr,
+ .reset = csid_reset,
+ .src_pad_code = csid_src_pad_code,
+ .subdev_init = csid_subdev_init,
+};
diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index be3fe76f3dc3..601bd810f2b0 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -26,405 +26,35 @@

#define MSM_CSID_NAME "msm_csid"

-#define CAMSS_CSID_HW_VERSION 0x0
-#define CAMSS_CSID_CORE_CTRL_0 0x004
-#define CAMSS_CSID_CORE_CTRL_1 0x008
-#define CAMSS_CSID_RST_CMD(v) ((v) == CAMSS_8x16 ? 0x00c : 0x010)
-#define CAMSS_CSID_CID_LUT_VC_n(v, n) \
- (((v) == CAMSS_8x16 ? 0x010 : 0x014) + 0x4 * (n))
-#define CAMSS_CSID_CID_n_CFG(v, n) \
- (((v) == CAMSS_8x16 ? 0x020 : 0x024) + 0x4 * (n))
-#define CAMSS_CSID_CID_n_CFG_ISPIF_EN BIT(0)
-#define CAMSS_CSID_CID_n_CFG_RDI_EN BIT(1)
-#define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT 4
-#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8 (0 << 8)
-#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (1 << 8)
-#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB (0 << 9)
-#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB (1 << 9)
-#define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP (0 << 10)
-#define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING (1 << 10)
-#define CAMSS_CSID_IRQ_CLEAR_CMD(v) ((v) == CAMSS_8x16 ? 0x060 : 0x064)
-#define CAMSS_CSID_IRQ_MASK(v) ((v) == CAMSS_8x16 ? 0x064 : 0x068)
-#define CAMSS_CSID_IRQ_STATUS(v) ((v) == CAMSS_8x16 ? 0x068 : 0x06c)
-#define CAMSS_CSID_TG_CTRL(v) ((v) == CAMSS_8x16 ? 0x0a0 : 0x0a8)
-#define CAMSS_CSID_TG_CTRL_DISABLE 0xa06436
-#define CAMSS_CSID_TG_CTRL_ENABLE 0xa06437
-#define CAMSS_CSID_TG_VC_CFG(v) ((v) == CAMSS_8x16 ? 0x0a4 : 0x0ac)
-#define CAMSS_CSID_TG_VC_CFG_H_BLANKING 0x3ff
-#define CAMSS_CSID_TG_VC_CFG_V_BLANKING 0x7f
-#define CAMSS_CSID_TG_DT_n_CGG_0(v, n) \
- (((v) == CAMSS_8x16 ? 0x0ac : 0x0b4) + 0xc * (n))
-#define CAMSS_CSID_TG_DT_n_CGG_1(v, n) \
- (((v) == CAMSS_8x16 ? 0x0b0 : 0x0b8) + 0xc * (n))
-#define CAMSS_CSID_TG_DT_n_CGG_2(v, n) \
- (((v) == CAMSS_8x16 ? 0x0b4 : 0x0bc) + 0xc * (n))
-
-#define DATA_TYPE_EMBEDDED_DATA_8BIT 0x12
-#define DATA_TYPE_YUV422_8BIT 0x1e
-#define DATA_TYPE_RAW_6BIT 0x28
-#define DATA_TYPE_RAW_8BIT 0x2a
-#define DATA_TYPE_RAW_10BIT 0x2b
-#define DATA_TYPE_RAW_12BIT 0x2c
-#define DATA_TYPE_RAW_14BIT 0x2d
-
-#define DECODE_FORMAT_UNCOMPRESSED_6_BIT 0x0
-#define DECODE_FORMAT_UNCOMPRESSED_8_BIT 0x1
-#define DECODE_FORMAT_UNCOMPRESSED_10_BIT 0x2
-#define DECODE_FORMAT_UNCOMPRESSED_12_BIT 0x3
-#define DECODE_FORMAT_UNCOMPRESSED_14_BIT 0x8
-
-#define CSID_RESET_TIMEOUT_MS 500
-
-struct csid_format {
- u32 code;
- u8 data_type;
- u8 decode_format;
- u8 bpp;
- u8 spp; /* bus samples per pixel */
-};
-
-static const struct csid_format csid_formats_8x16[] = {
- {
- MEDIA_BUS_FMT_UYVY8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_VYUY8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_YUYV8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_YVYU8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_SBGGR8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SBGGR10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SBGGR12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_Y10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
-};
-
-static const struct csid_format csid_formats_8x96[] = {
- {
- MEDIA_BUS_FMT_UYVY8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_VYUY8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_YUYV8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_YVYU8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_SBGGR8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SBGGR10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SBGGR12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SBGGR14_1X14,
- DATA_TYPE_RAW_14BIT,
- DECODE_FORMAT_UNCOMPRESSED_14_BIT,
- 14,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG14_1X14,
- DATA_TYPE_RAW_14BIT,
- DECODE_FORMAT_UNCOMPRESSED_14_BIT,
- 14,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG14_1X14,
- DATA_TYPE_RAW_14BIT,
- DECODE_FORMAT_UNCOMPRESSED_14_BIT,
- 14,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB14_1X14,
- DATA_TYPE_RAW_14BIT,
- DECODE_FORMAT_UNCOMPRESSED_14_BIT,
- 14,
- 1,
- },
- {
- MEDIA_BUS_FMT_Y10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
-};

-static u32 csid_find_code(u32 *code, unsigned int n_code,
- unsigned int index, u32 req_code)
+u32 csid_find_code(u32 *codes, unsigned int ncodes,
+ unsigned int match_format_idx, u32 match_code)
{
int i;

- if (!req_code && (index >= n_code))
+ if (!match_code && (match_format_idx >= ncodes))
return 0;

- for (i = 0; i < n_code; i++)
- if (req_code) {
- if (req_code == code[i])
- return req_code;
+ for (i = 0; i < ncodes; i++)
+ if (match_code) {
+ if (codes[i] == match_code)
+ return match_code;
} else {
- if (i == index)
- return code[i];
- }
-
- return code[0];
-}
-
-static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
- unsigned int index, u32 src_req_code)
-{
- if (csid->camss->version == CAMSS_8x16) {
- if (index > 0)
- return 0;
-
- return sink_code;
- } else if (csid->camss->version == CAMSS_8x96 ||
- csid->camss->version == CAMSS_660) {
- switch (sink_code) {
- case MEDIA_BUS_FMT_SBGGR10_1X10:
- {
- u32 src_code[] = {
- MEDIA_BUS_FMT_SBGGR10_1X10,
- MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE,
- };
-
- return csid_find_code(src_code, ARRAY_SIZE(src_code),
- index, src_req_code);
- }
- case MEDIA_BUS_FMT_Y10_1X10:
- {
- u32 src_code[] = {
- MEDIA_BUS_FMT_Y10_1X10,
- MEDIA_BUS_FMT_Y10_2X8_PADHI_LE,
- };
-
- return csid_find_code(src_code, ARRAY_SIZE(src_code),
- index, src_req_code);
+ if (i == match_format_idx)
+ return codes[i];
}
- default:
- if (index > 0)
- return 0;

- return sink_code;
- }
- } else {
- return 0;
- }
+ return codes[0];
}

-static const struct csid_format *csid_get_fmt_entry(
+const struct csid_format *csid_get_fmt_entry(
const struct csid_format *formats,
- unsigned int nformat,
+ unsigned int nformats,
u32 code)
{
unsigned int i;

- for (i = 0; i < nformat; i++)
+ for (i = 0; i < nformats; i++)
if (code == formats[i].code)
return &formats[i];

@@ -433,28 +63,6 @@ static const struct csid_format *csid_get_fmt_entry(
return &formats[0];
}

-/*
- * csid_isr - CSID module interrupt handler
- * @irq: Interrupt line
- * @dev: CSID device
- *
- * Return IRQ_HANDLED on success
- */
-static irqreturn_t csid_isr(int irq, void *dev)
-{
- struct csid_device *csid = dev;
- enum camss_version ver = csid->camss->version;
- u32 value;
-
- value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS(ver));
- writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD(ver));
-
- if ((value >> 11) & 0x1)
- complete(&csid->reset_complete);
-
- return IRQ_HANDLED;
-}
-
/*
* csid_set_clock_rates - Calculate and set clock rates on CSID module
* @csiphy: CSID device
@@ -521,31 +129,6 @@ static int csid_set_clock_rates(struct csid_device *csid)
return 0;
}

-/*
- * csid_reset - Trigger reset on CSID module and wait to complete
- * @csid: CSID device
- *
- * Return 0 on success or a negative error code otherwise
- */
-static int csid_reset(struct csid_device *csid)
-{
- unsigned long time;
-
- reinit_completion(&csid->reset_complete);
-
- writel_relaxed(0x7fff, csid->base +
- CAMSS_CSID_RST_CMD(csid->camss->version));
-
- time = wait_for_completion_timeout(&csid->reset_complete,
- msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
- if (!time) {
- dev_err(csid->camss->dev, "CSID reset timeout\n");
- return -EIO;
- }
-
- return 0;
-}
-
/*
* csid_set_power - Power on/off CSID module
* @sd: CSID V4L2 subdevice
@@ -560,8 +143,6 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
int ret;

if (on) {
- u32 hw_version;
-
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
pm_runtime_put_sync(dev);
@@ -590,7 +171,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)

enable_irq(csid->irq);

- ret = csid_reset(csid);
+ ret = csid->ops->reset(csid);
if (ret < 0) {
disable_irq(csid->irq);
camss_disable_clocks(csid->nclocks, csid->clock);
@@ -599,8 +180,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
return ret;
}

- hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION);
- dev_dbg(dev, "CSID HW Version = 0x%08x\n", hw_version);
+ csid->ops->hw_version(csid);
} else {
disable_irq(csid->irq);
camss_disable_clocks(csid->nclocks, csid->clock);
@@ -623,16 +203,9 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
static int csid_set_stream(struct v4l2_subdev *sd, int enable)
{
struct csid_device *csid = v4l2_get_subdevdata(sd);
- struct csid_testgen_config *tg = &csid->testgen;
- enum camss_version ver = csid->camss->version;
- u32 val;
+ int ret;

if (enable) {
- u8 vc = 0; /* Virtual Channel 0 */
- u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */
- u8 dt, dt_shift, df;
- int ret;
-
ret = v4l2_ctrl_handler_setup(&csid->ctrls);
if (ret < 0) {
dev_err(csid->camss->dev,
@@ -640,116 +213,13 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable)
return ret;
}

- if (!tg->enabled &&
+ if (!csid->testgen.enabled &&
!media_entity_remote_pad(&csid->pads[MSM_CSID_PAD_SINK]))
return -ENOLINK;
-
- if (tg->enabled) {
- /* Config Test Generator */
- struct v4l2_mbus_framefmt *f =
- &csid->fmt[MSM_CSID_PAD_SRC];
- const struct csid_format *format = csid_get_fmt_entry(
- csid->formats, csid->nformats, f->code);
- u32 num_bytes_per_line =
- f->width * format->bpp * format->spp / 8;
- u32 num_lines = f->height;
-
- /* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */
- /* 1:0 VC */
- val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) |
- ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13);
- writel_relaxed(val, csid->base +
- CAMSS_CSID_TG_VC_CFG(ver));
-
- /* 28:16 bytes per lines, 12:0 num of lines */
- val = ((num_bytes_per_line & 0x1fff) << 16) |
- (num_lines & 0x1fff);
- writel_relaxed(val, csid->base +
- CAMSS_CSID_TG_DT_n_CGG_0(ver, 0));
-
- dt = format->data_type;
-
- /* 5:0 data type */
- val = dt;
- writel_relaxed(val, csid->base +
- CAMSS_CSID_TG_DT_n_CGG_1(ver, 0));
-
- /* 2:0 output test pattern */
- val = tg->payload_mode;
- writel_relaxed(val, csid->base +
- CAMSS_CSID_TG_DT_n_CGG_2(ver, 0));
-
- df = format->decode_format;
- } else {
- struct v4l2_mbus_framefmt *f =
- &csid->fmt[MSM_CSID_PAD_SINK];
- const struct csid_format *format = csid_get_fmt_entry(
- csid->formats, csid->nformats, f->code);
- struct csid_phy_config *phy = &csid->phy;
-
- val = phy->lane_cnt - 1;
- val |= phy->lane_assign << 4;
-
- writel_relaxed(val,
- csid->base + CAMSS_CSID_CORE_CTRL_0);
-
- val = phy->csiphy_id << 17;
- val |= 0x9;
-
- writel_relaxed(val,
- csid->base + CAMSS_CSID_CORE_CTRL_1);
-
- dt = format->data_type;
- df = format->decode_format;
- }
-
- /* Config LUT */
-
- dt_shift = (cid % 4) * 8;
-
- val = readl_relaxed(csid->base +
- CAMSS_CSID_CID_LUT_VC_n(ver, vc));
- val &= ~(0xff << dt_shift);
- val |= dt << dt_shift;
- writel_relaxed(val, csid->base +
- CAMSS_CSID_CID_LUT_VC_n(ver, vc));
-
- val = CAMSS_CSID_CID_n_CFG_ISPIF_EN;
- val |= CAMSS_CSID_CID_n_CFG_RDI_EN;
- val |= df << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT;
- val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP;
-
- if (csid->camss->version == CAMSS_8x96 ||
- csid->camss->version == CAMSS_660) {
- u32 sink_code = csid->fmt[MSM_CSID_PAD_SINK].code;
- u32 src_code = csid->fmt[MSM_CSID_PAD_SRC].code;
-
- if ((sink_code == MEDIA_BUS_FMT_SBGGR10_1X10 &&
- src_code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) ||
- (sink_code == MEDIA_BUS_FMT_Y10_1X10 &&
- src_code == MEDIA_BUS_FMT_Y10_2X8_PADHI_LE)) {
- val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING;
- val |= CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16;
- val |= CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB;
- }
- }
-
- writel_relaxed(val, csid->base +
- CAMSS_CSID_CID_n_CFG(ver, cid));
-
- if (tg->enabled) {
- val = CAMSS_CSID_TG_CTRL_ENABLE;
- writel_relaxed(val, csid->base +
- CAMSS_CSID_TG_CTRL(ver));
- }
- } else {
- if (tg->enabled) {
- val = CAMSS_CSID_TG_CTRL_DISABLE;
- writel_relaxed(val, csid->base +
- CAMSS_CSID_TG_CTRL(ver));
- }
}

+ csid->ops->configure_stream(csid, enable);
+
return 0;
}

@@ -818,7 +288,7 @@ static void csid_try_format(struct csid_device *csid,

*fmt = *__csid_get_format(csid, cfg,
MSM_CSID_PAD_SINK, which);
- fmt->code = csid_src_pad_code(csid, fmt->code, 0, code);
+ fmt->code = csid->ops->src_pad_code(csid, fmt->code, 0, code);
} else {
/* Test generator is enabled, set format on source */
/* pad to allow test generator usage */
@@ -868,7 +338,7 @@ static int csid_enum_mbus_code(struct v4l2_subdev *sd,
MSM_CSID_PAD_SINK,
code->which);

- code->code = csid_src_pad_code(csid, sink_fmt->code,
+ code->code = csid->ops->src_pad_code(csid, sink_fmt->code,
code->index, 0);
if (!code->code)
return -EINVAL;
@@ -1004,15 +474,6 @@ static int csid_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
return csid_set_format(sd, fh ? fh->pad : NULL, &format);
}

-static const char * const csid_test_pattern_menu[] = {
- "Disabled",
- "Incrementing",
- "Alternating 0x55/0xAA",
- "All Zeros 0x00",
- "All Ones 0xFF",
- "Pseudo-random Data",
-};
-
/*
* csid_set_test_pattern - Set test generator's pattern mode
* @csid: CSID device
@@ -1030,25 +491,7 @@ static int csid_set_test_pattern(struct csid_device *csid, s32 value)

tg->enabled = !!value;

- switch (value) {
- case 1:
- tg->payload_mode = CSID_PAYLOAD_MODE_INCREMENTING;
- break;
- case 2:
- tg->payload_mode = CSID_PAYLOAD_MODE_ALTERNATING_55_AA;
- break;
- case 3:
- tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ZEROES;
- break;
- case 4:
- tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ONES;
- break;
- case 5:
- tg->payload_mode = CSID_PAYLOAD_MODE_RANDOM;
- break;
- }
-
- return 0;
+ return csid->ops->configure_testgen_pattern(csid, value);
}

/*
@@ -1097,17 +540,14 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
csid->id = id;

if (camss->version == CAMSS_8x16) {
- csid->formats = csid_formats_8x16;
- csid->nformats =
- ARRAY_SIZE(csid_formats_8x16);
+ csid->ops = &csid_ops_4_1;
} else if (camss->version == CAMSS_8x96 ||
camss->version == CAMSS_660) {
- csid->formats = csid_formats_8x96;
- csid->nformats =
- ARRAY_SIZE(csid_formats_8x96);
+ csid->ops = &csid_ops_4_7;
} else {
return -EINVAL;
}
+ csid->ops->subdev_init(csid);

/* Memory */

@@ -1130,7 +570,7 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
csid->irq = r->start;
snprintf(csid->irq_name, sizeof(csid->irq_name), "%s_%s%d",
dev_name(dev), MSM_CSID_NAME, csid->id);
- ret = devm_request_irq(dev, csid->irq, csid_isr,
+ ret = devm_request_irq(dev, csid->irq, csid->ops->isr,
IRQF_TRIGGER_RISING, csid->irq_name, csid);
if (ret < 0) {
dev_err(dev, "request_irq failed: %d\n", ret);
@@ -1341,8 +781,8 @@ int msm_csid_register_entity(struct csid_device *csid,

csid->testgen_mode = v4l2_ctrl_new_std_menu_items(&csid->ctrls,
&csid_ctrl_ops, V4L2_CID_TEST_PATTERN,
- ARRAY_SIZE(csid_test_pattern_menu) - 1, 0, 0,
- csid_test_pattern_menu);
+ csid->testgen.nmodes, 0, 0,
+ csid->testgen.modes);

if (csid->ctrls.error) {
dev_err(dev, "Failed to init ctrl: %d\n", csid->ctrls.error);
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index 02fc34ee8a41..d40194e2bed3 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -11,6 +11,7 @@
#define QC_MSM_CAMSS_CSID_H

#include <linux/clk.h>
+#include <linux/interrupt.h>
#include <media/media-entity.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
@@ -70,19 +71,50 @@
#define PLAIN_FORMAT_PLAIN16 0x1 /* supports DPCM, UNCOMPRESSED_10/16_BIT */
#define PLAIN_FORMAT_PLAIN32 0x2 /* supports UNCOMPRESSED_20_BIT */

+#define CSID_RESET_TIMEOUT_MS 500

-enum csid_payload_mode {
+
+enum csid_testgen_mode {
CSID_PAYLOAD_MODE_INCREMENTING = 0,
CSID_PAYLOAD_MODE_ALTERNATING_55_AA = 1,
CSID_PAYLOAD_MODE_ALL_ZEROES = 2,
CSID_PAYLOAD_MODE_ALL_ONES = 3,
CSID_PAYLOAD_MODE_RANDOM = 4,
CSID_PAYLOAD_MODE_USER_SPECIFIED = 5,
+ CSID_PAYLOAD_MODE_MAX_SUPPORTED_4_1 = 5,
+ CSID_PAYLOAD_MODE_MAX_SUPPORTED_4_7 = 5,
+ CSID_PAYLOAD_MODE_COMPLEX_PATTERN = 6,
+ CSID_PAYLOAD_MODE_COLOR_BOX = 7,
+ CSID_PAYLOAD_MODE_COLOR_BARS = 8,
+ CSID_PAYLOAD_MODE_MAX_SUPPORTED_170 = 8,
+};
+
+static const char * const csid_testgen_modes[] = {
+ "Disabled",
+ "Incrementing",
+ "Alternating 0x55/0xAA",
+ "All Zeros 0x00",
+ "All Ones 0xFF",
+ "Pseudo-random Data",
+ "User Specified",
+ "Complex pattern",
+ "Color box",
+ "Color bars",
+};
+
+struct csid_format {
+ u32 code;
+ u8 data_type;
+ u8 decode_format;
+ u8 bpp;
+ u8 spp; /* bus samples per pixel */
};

struct csid_testgen_config {
+ enum csid_testgen_mode mode;
+ const char * const*modes;
+ u8 nmodes;
u8 enabled;
- enum csid_payload_mode payload_mode;
};

struct csid_phy_config {
@@ -91,6 +123,65 @@ struct csid_phy_config {
u32 lane_assign;
};

+struct csid_device;
+
+struct csid_hw_ops {
+ /*
+ * configure_stream - Configures and starts CSID input stream
+ * @csid: CSID device
+ */
+ void (*configure_stream)(struct csid_device *csid, u8 enable);
+
+ /*
+ * configure_testgen_pattern - Validates and configures output pattern mode
+ * of test pattern generator
+ * @csid: CSID device
+ */
+ int (*configure_testgen_pattern)(struct csid_device *csid, s32 val);
+
+ /*
+ * hw_version - Read hardware version register from hardware
+ * @csid: CSID device
+ */
+ u32 (*hw_version)(struct csid_device *csid);
+
+ /*
+ * isr - CSID module interrupt service routine
+ * @irq: Interrupt line
+ * @dev: CSID device
+ *
+ * Return IRQ_HANDLED on success
+ */
+ irqreturn_t (*isr)(int irq, void *dev);
+
+ /*
+ * reset - Trigger reset on CSID module and wait to complete
+ * @csid: CSID device
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+ int (*reset)(struct csid_device *csid);
+
+ /*
+ * src_pad_code - Pick an output/src format based on the input/sink format
+ * @csid: CSID device
+ * @sink_code: The sink format of the input
+ * @match_format_idx: Request preferred index, as defined by subdevice csid_format.
+ * Set @match_code to 0 if used.
+ * @match_code: Request preferred code, set @match_format_idx to 0 if used
+ *
+ * Return 0 on failure or src format code otherwise
+ */
+ u32 (*src_pad_code)(struct csid_device *csid, u32 sink_code,
+ unsigned int match_format_idx, u32 match_code);
+
+ /*
+ * subdev_init - Initialize CSID device according for hardware revision
+ * @csid: CSID device
+ */
+ void (*subdev_init)(struct csid_device *csid);
+};
+
struct csid_device {
struct camss *camss;
u8 id;
@@ -110,10 +201,37 @@ struct csid_device {
struct v4l2_ctrl *testgen_mode;
const struct csid_format *formats;
unsigned int nformats;
+ const struct csid_hw_ops *ops;
};

struct resources;

+
+/*
+ * csid_find_code - Find a format code in an array using array index or format code
+ * @codes: Array of format codes
+ * @ncodes: Length of @code array
+ * @req_format_idx: Request preferred index, as defined by subdevice csid_format.
+ * Set @match_code to 0 if used.
+ * @match_code: Request preferred code, set @req_format_idx to 0 if used
+ *
+ * Return 0 on failure or format code otherwise
+ */
+u32 csid_find_code(u32 *codes, unsigned int ncode,
+ unsigned int match_format_idx, u32 match_code);
+
+/*
+ * csid_get_fmt_entry - Find csid_format entry with matching format code
+ * @formats: Array of format csid_format entries
+ * @nformats: Length of @nformats array
+ * @code: Desired format code
+ *
+ * Return formats[0] on failure to find code
+ */
+const struct csid_format *csid_get_fmt_entry(const struct csid_format *formats,
+ unsigned int nformats,
+ u32 code);
+
int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
const struct resources *res, u8 id);

@@ -124,4 +242,8 @@ void msm_csid_unregister_entity(struct csid_device *csid);

void msm_csid_get_csid_id(struct media_entity *entity, u8 *id);

+
+extern const struct csid_hw_ops csid_ops_4_1;
+extern const struct csid_hw_ops csid_ops_4_7;
+
#endif /* QC_MSM_CAMSS_CSID_H */
--
2.27.0

2021-01-30 17:26:15

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v3 15/22] dt-bindings: media: camss: Add qcom, sdm660-camss binding

On Wed, 27 Jan 2021 15:49:23 +0100, Robert Foss wrote:
> Add bindings for qcom,sdm660-camss in order to support the camera
> subsystem on SDM630/660 and SDA variants.
>
> Signed-off-by: Robert Foss <[email protected]>
> ---
>
> Changes since v2
> - Rob: Add new line at end of file
> - Rob: Remove redundant descriptions
> - Rob: Add power domain description
> - Rob: Make clock-lanes a constant
> - Rob: Rework to conform to new port schema
> - Add max & minItems to data-lanes
> - Remove ports requirement - endpoint & reg
> - Added Angelo as binding maintainer
> - Removed Todor as binding maintainer
>
>
> .../bindings/media/qcom,sdm660-camss.yaml | 398 ++++++++++++++++++
> 1 file changed, 398 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
>

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/media/qcom,sdm660-camss.example.dts:21:18: fatal error: dt-bindings/clock/qcom,mmcc-sdm660.h: No such file or directory
21 | #include <dt-bindings/clock/qcom,mmcc-sdm660.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [scripts/Makefile.lib:344: Documentation/devicetree/bindings/media/qcom,sdm660-camss.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1370: dt_binding_check] Error 2

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

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.

2021-02-03 11:30:15

by Robert Foss

[permalink] [raw]
Subject: Re: [PATCH v3 15/22] dt-bindings: media: camss: Add qcom, sdm660-camss binding

On Sat, 30 Jan 2021 at 18:23, Rob Herring <[email protected]> wrote:
>
> On Wed, 27 Jan 2021 15:49:23 +0100, Robert Foss wrote:
> > Add bindings for qcom,sdm660-camss in order to support the camera
> > subsystem on SDM630/660 and SDA variants.
> >
> > Signed-off-by: Robert Foss <[email protected]>
> > ---
> >
> > Changes since v2
> > - Rob: Add new line at end of file
> > - Rob: Remove redundant descriptions
> > - Rob: Add power domain description
> > - Rob: Make clock-lanes a constant
> > - Rob: Rework to conform to new port schema
> > - Add max & minItems to data-lanes
> > - Remove ports requirement - endpoint & reg
> > - Added Angelo as binding maintainer
> > - Removed Todor as binding maintainer
> >
> >
> > .../bindings/media/qcom,sdm660-camss.yaml | 398 ++++++++++++++++++
> > 1 file changed, 398 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
> >
>
> My bot found errors running 'make dt_binding_check' on your patch:
>
> yamllint warnings/errors:
>
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/media/qcom,sdm660-camss.example.dts:21:18: fatal error: dt-bindings/clock/qcom,mmcc-sdm660.h: No such file or directory
> 21 | #include <dt-bindings/clock/qcom,mmcc-sdm660.h>
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> compilation terminated.
> make[1]: *** [scripts/Makefile.lib:344: Documentation/devicetree/bindings/media/qcom,sdm660-camss.example.dt.yaml] Error 1
> make[1]: *** Waiting for unfinished jobs....
> make: *** [Makefile:1370: dt_binding_check] Error 2

This is expected and mentioned in the cover letter due to a dependency
on an as of yet unmerged mmcc-sdm660 series.

>
> See https://patchwork.ozlabs.org/patch/1432255
>
> 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.
>

2021-02-05 00:53:28

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v3 15/22] dt-bindings: media: camss: Add qcom, sdm660-camss binding

On Wed, 27 Jan 2021 15:49:23 +0100, Robert Foss wrote:
> Add bindings for qcom,sdm660-camss in order to support the camera
> subsystem on SDM630/660 and SDA variants.
>
> Signed-off-by: Robert Foss <[email protected]>
> ---
>
> Changes since v2
> - Rob: Add new line at end of file
> - Rob: Remove redundant descriptions
> - Rob: Add power domain description
> - Rob: Make clock-lanes a constant
> - Rob: Rework to conform to new port schema
> - Add max & minItems to data-lanes
> - Remove ports requirement - endpoint & reg
> - Added Angelo as binding maintainer
> - Removed Todor as binding maintainer
>
>
> .../bindings/media/qcom,sdm660-camss.yaml | 398 ++++++++++++++++++
> 1 file changed, 398 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
>

Reviewed-by: Rob Herring <[email protected]>