* [PATCH v9 4/6] arm64: dts: qcom: sm8450: Add opp table support to PCIe
From: Krishna chaitanya chundru @ 2024-04-07 4:37 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Bjorn Helgaas, johan+linaro, bmasney,
djakov
Cc: linux-arm-msm, devicetree, linux-kernel, linux-pci, vireshk,
quic_vbadigan, quic_skananth, quic_nitegupt, quic_parass,
quic_krichai, krzysztof.kozlowski
In-Reply-To: <20240407-opp_support-v9-0-496184dc45d7@quicinc.com>
PCIe needs to choose the appropriate performance state of RPMH power
domain and interconnect bandwidth based up on the PCIe gen speed.
Add the OPP table support to specify RPMH performance states and
interconnect peak bandwidth.
Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
---
arch/arm64/boot/dts/qcom/sm8450.dtsi | 77 ++++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
index 615296e13c43..881e5339cfff 100644
--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
@@ -1855,7 +1855,35 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
pinctrl-names = "default";
pinctrl-0 = <&pcie0_default_state>;
+ operating-points-v2 = <&pcie0_opp_table>;
+
status = "disabled";
+
+ pcie0_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ /* GEN 1x1 */
+ opp-2500000 {
+ opp-hz = /bits/ 64 <2500000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <250000 1>;
+ };
+
+ /* GEN 2x1 */
+ opp-5000000 {
+ opp-hz = /bits/ 64 <5000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <500000 1>;
+ };
+
+ /* GEN 3x1 */
+ opp-8000000 {
+ opp-hz = /bits/ 64 <8000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ opp-peak-kBps = <984500 1>;
+ };
+ };
+
};
pcie0_phy: phy@1c06000 {
@@ -1982,7 +2010,56 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
pinctrl-names = "default";
pinctrl-0 = <&pcie1_default_state>;
+ operating-points-v2 = <&pcie1_opp_table>;
+
status = "disabled";
+
+ pcie1_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ /* GEN 1x1 */
+ opp-2500000 {
+ opp-hz = /bits/ 64 <2500000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <250000 1>;
+ };
+
+ /* GEN 1x2 GEN 2x1 */
+ opp-5000000 {
+ opp-hz = /bits/ 64 <5000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <500000 1>;
+ };
+
+ /* GEN 2x2 */
+ opp-10000000 {
+ opp-hz = /bits/ 64 <10000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ opp-peak-kBps = <1000000 1>;
+ };
+
+ /* GEN 3x1 */
+ opp-8000000 {
+ opp-hz = /bits/ 64 <8000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ opp-peak-kBps = <984500 1>;
+ };
+
+ /* GEN 3x2 GEN 4x1 */
+ opp-16000000 {
+ opp-hz = /bits/ 64 <16000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ opp-peak-kBps = <1969000 1>;
+ };
+
+ /* GEN 4x2 */
+ opp-32000000 {
+ opp-hz = /bits/ 64 <32000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ opp-peak-kBps = <3938000 1>;
+ };
+ };
+
};
pcie1_phy: phy@1c0e000 {
--
2.42.0
^ permalink raw reply related
* [PATCH v9 5/6] PCI: Bring the PCIe speed to MBps logic to new pcie_link_speed_to_mbps()
From: Krishna chaitanya chundru @ 2024-04-07 4:37 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Bjorn Helgaas, johan+linaro, bmasney,
djakov
Cc: linux-arm-msm, devicetree, linux-kernel, linux-pci, vireshk,
quic_vbadigan, quic_skananth, quic_nitegupt, quic_parass,
quic_krichai, krzysztof.kozlowski
In-Reply-To: <20240407-opp_support-v9-0-496184dc45d7@quicinc.com>
Bring the switch case in pcie_link_speed_mbps() to new function to
the header file so that it can be used in other places like
in controller driver.
Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
drivers/pci/pci.c | 19 +------------------
drivers/pci/pci.h | 22 ++++++++++++++++++++++
2 files changed, 23 insertions(+), 18 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e5f243dd4288..40487b86a75e 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -5922,24 +5922,7 @@ int pcie_link_speed_mbps(struct pci_dev *pdev)
if (err)
return err;
- switch (to_pcie_link_speed(lnksta)) {
- case PCIE_SPEED_2_5GT:
- return 2500;
- case PCIE_SPEED_5_0GT:
- return 5000;
- case PCIE_SPEED_8_0GT:
- return 8000;
- case PCIE_SPEED_16_0GT:
- return 16000;
- case PCIE_SPEED_32_0GT:
- return 32000;
- case PCIE_SPEED_64_0GT:
- return 64000;
- default:
- break;
- }
-
- return -EINVAL;
+ return pcie_link_speed_to_mbps(to_pcie_link_speed(lnksta));
}
EXPORT_SYMBOL(pcie_link_speed_mbps);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 17fed1846847..4de10087523e 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -290,6 +290,28 @@ void pci_bus_put(struct pci_bus *bus);
(speed) == PCIE_SPEED_2_5GT ? 2500*8/10 : \
0)
+static inline int pcie_link_speed_to_mbps(enum pci_bus_speed speed)
+{
+ switch (speed) {
+ case PCIE_SPEED_2_5GT:
+ return 2500;
+ case PCIE_SPEED_5_0GT:
+ return 5000;
+ case PCIE_SPEED_8_0GT:
+ return 8000;
+ case PCIE_SPEED_16_0GT:
+ return 16000;
+ case PCIE_SPEED_32_0GT:
+ return 32000;
+ case PCIE_SPEED_64_0GT:
+ return 64000;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
const char *pci_speed_string(enum pci_bus_speed speed);
enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev);
enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev);
--
2.42.0
^ permalink raw reply related
* [PATCH v9 6/6] PCI: qcom: Add OPP support to scale performance state of power domain
From: Krishna chaitanya chundru @ 2024-04-07 4:37 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Bjorn Helgaas, johan+linaro, bmasney,
djakov
Cc: linux-arm-msm, devicetree, linux-kernel, linux-pci, vireshk,
quic_vbadigan, quic_skananth, quic_nitegupt, quic_parass,
quic_krichai, krzysztof.kozlowski
In-Reply-To: <20240407-opp_support-v9-0-496184dc45d7@quicinc.com>
QCOM Resource Power Manager-hardened (RPMh) is a hardware block which
maintains hardware state of a regulator by performing max aggregation of
the requests made by all of the clients.
PCIe controller can operate on different RPMh performance state of power
domain based on the speed of the link. And this performance state varies
from target to target, like some controllers support GEN3 in NOM (Nominal)
voltage corner, while some other supports GEN3 in low SVS (static voltage
scaling).
The SoC can be more power efficient if we scale the performance state
based on the aggregate PCIe link bandwidth.
Add Operating Performance Points (OPP) support to vote for RPMh state based
on the aggregate link bandwidth.
OPP can handle ICC bw voting also, so move ICC bw voting through OPP
framework if OPP entries are present.
Different link configurations may share the same aggregate bandwidth,
e.g., a 2.5 GT/s x2 link and a 5.0 GT/s x1 link have the same bandwidth
and share the same OPP entry.
As we are moving ICC voting as part of OPP, don't initialize ICC if OPP
is supported.
Before PCIe link is initialized vote for highest OPP in the OPP table,
so that we are voting for maximum voltage corner for the link to come up
in maximum supported speed.
Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
---
drivers/pci/controller/dwc/pcie-qcom.c | 72 +++++++++++++++++++++++++++-------
1 file changed, 58 insertions(+), 14 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index b4893214b2d3..4ad5ef3bf8fc 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -22,6 +22,7 @@
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/pci.h>
+#include <linux/pm_opp.h>
#include <linux/pm_runtime.h>
#include <linux/platform_device.h>
#include <linux/phy/pcie.h>
@@ -1442,15 +1443,13 @@ static int qcom_pcie_icc_init(struct qcom_pcie *pcie)
return 0;
}
-static void qcom_pcie_icc_update(struct qcom_pcie *pcie)
+static void qcom_pcie_icc_opp_update(struct qcom_pcie *pcie)
{
struct dw_pcie *pci = pcie->pci;
- u32 offset, status;
+ u32 offset, status, freq;
+ struct dev_pm_opp *opp;
int speed, width;
- int ret;
-
- if (!pcie->icc_mem)
- return;
+ int ret, mbps;
offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
status = readw(pci->dbi_base + offset + PCI_EXP_LNKSTA);
@@ -1462,10 +1461,26 @@ static void qcom_pcie_icc_update(struct qcom_pcie *pcie)
speed = FIELD_GET(PCI_EXP_LNKSTA_CLS, status);
width = FIELD_GET(PCI_EXP_LNKSTA_NLW, status);
- ret = icc_set_bw(pcie->icc_mem, 0, width * QCOM_PCIE_LINK_SPEED_TO_BW(speed));
- if (ret) {
- dev_err(pci->dev, "failed to set interconnect bandwidth for PCIe-MEM: %d\n",
- ret);
+ if (pcie->icc_mem) {
+ ret = icc_set_bw(pcie->icc_mem, 0, width * QCOM_PCIE_LINK_SPEED_TO_BW(speed));
+ if (ret) {
+ dev_err(pci->dev, "failed to set interconnect bandwidth for PCIe-MEM: %d\n",
+ ret);
+ }
+ } else {
+ mbps = pcie_link_speed_to_mbps(pcie_link_speed[speed]);
+ if (mbps < 0)
+ return;
+
+ freq = mbps * 1000;
+ opp = dev_pm_opp_find_freq_exact(pci->dev, freq * width, true);
+ if (!IS_ERR(opp)) {
+ ret = dev_pm_opp_set_opp(pci->dev, opp);
+ if (ret)
+ dev_err(pci->dev, "Failed to set opp: freq %ld ret %d\n",
+ dev_pm_opp_get_freq(opp), ret);
+ dev_pm_opp_put(opp);
+ }
}
}
@@ -1509,8 +1524,10 @@ static void qcom_pcie_init_debugfs(struct qcom_pcie *pcie)
static int qcom_pcie_probe(struct platform_device *pdev)
{
const struct qcom_pcie_cfg *pcie_cfg;
+ unsigned long max_freq = INT_MAX;
struct device *dev = &pdev->dev;
struct qcom_pcie *pcie;
+ struct dev_pm_opp *opp;
struct dw_pcie_rp *pp;
struct resource *res;
struct dw_pcie *pci;
@@ -1577,9 +1594,33 @@ static int qcom_pcie_probe(struct platform_device *pdev)
goto err_pm_runtime_put;
}
- ret = qcom_pcie_icc_init(pcie);
- if (ret)
+ /* OPP table is optional */
+ ret = devm_pm_opp_of_add_table(dev);
+ if (ret && ret != -ENODEV) {
+ dev_err_probe(dev, ret, "Failed to add OPP table\n");
goto err_pm_runtime_put;
+ }
+
+ /*
+ * Use highest OPP here if the OPP table is present. At the end of
+ * the probe(), OPP will be updated using qcom_pcie_icc_opp_update().
+ */
+ if (!ret) {
+ opp = dev_pm_opp_find_freq_floor(dev, &max_freq);
+ if (!IS_ERR(opp)) {
+ ret = dev_pm_opp_set_opp(dev, opp);
+ if (ret)
+ dev_err_probe(pci->dev, ret,
+ "Failed to set OPP: freq %ld\n",
+ dev_pm_opp_get_freq(opp));
+ dev_pm_opp_put(opp);
+ }
+ } else {
+ /* Skip ICC init if OPP is supported as it is handled by OPP */
+ ret = qcom_pcie_icc_init(pcie);
+ if (ret)
+ goto err_pm_runtime_put;
+ }
ret = pcie->cfg->ops->get_resources(pcie);
if (ret)
@@ -1599,7 +1640,7 @@ static int qcom_pcie_probe(struct platform_device *pdev)
goto err_phy_exit;
}
- qcom_pcie_icc_update(pcie);
+ qcom_pcie_icc_opp_update(pcie);
if (pcie->mhi)
qcom_pcie_init_debugfs(pcie);
@@ -1658,6 +1699,9 @@ static int qcom_pcie_suspend_noirq(struct device *dev)
if (ret)
dev_err(dev, "failed to disable icc path of CPU-PCIe: %d\n", ret);
+ if (!pcie->icc_mem)
+ dev_pm_opp_set_opp(pcie->pci->dev, NULL);
+
return ret;
}
@@ -1680,7 +1724,7 @@ static int qcom_pcie_resume_noirq(struct device *dev)
pcie->suspended = false;
}
- qcom_pcie_icc_update(pcie);
+ qcom_pcie_icc_opp_update(pcie);
return 0;
}
--
2.42.0
^ permalink raw reply related
* [PATCH v1 0/1] Add rtc PCF2131 support
From: Joy Zou @ 2024-04-07 5:19 UTC (permalink / raw)
To: ping.bai, robh+dt, krzysztof.kozlowski+dt, conor+dt, shawnguo,
s.hauer
Cc: kernel, festevam, linux-imx, devicetree, imx, linux-arm-kernel,
linux-kernel
The patchset supports RTC PCF2131 on board dts.
For the details, please check the patch commit log.
Joy Zou (1):
arm64: dts: imx93-11x11-evk: add rtc PCF2131 support
.../boot/dts/freescale/imx93-11x11-evk.dts | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
--
2.37.1
^ permalink raw reply
* [PATCH v1 1/1] arm64: dts: imx93-11x11-evk: add rtc PCF2131 support
From: Joy Zou @ 2024-04-07 5:19 UTC (permalink / raw)
To: ping.bai, robh+dt, krzysztof.kozlowski+dt, conor+dt, shawnguo,
s.hauer
Cc: kernel, festevam, linux-imx, devicetree, imx, linux-arm-kernel,
linux-kernel
In-Reply-To: <20240407051913.1989364-1-joy.zou@nxp.com>
Support rtc PCF2131 on imx93-11x11-evk.
Signed-off-by: Joy Zou <joy.zou@nxp.com>
---
.../boot/dts/freescale/imx93-11x11-evk.dts | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
index 07e85a30a25f..065fa3390791 100644
--- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
@@ -281,6 +281,24 @@ ldo5: LDO5 {
};
};
+&lpi2c3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_lpi2c3>;
+ pinctrl-1 = <&pinctrl_lpi2c3>;
+ status = "okay";
+
+ pcf2131: rtc@53 {
+ compatible = "nxp,pcf2131";
+ reg = <0x53>;
+ interrupt-parent = <&pcal6524>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ status = "okay";
+ };
+};
+
&iomuxc {
pinctrl_eqos: eqosgrp {
fsl,pins = <
@@ -343,6 +361,13 @@ MX93_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e
>;
};
+ pinctrl_lpi2c3: lpi2c3grp {
+ fsl,pins = <
+ MX93_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e
+ MX93_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e
+ >;
+ };
+
pinctrl_pcal6524: pcal6524grp {
fsl,pins = <
MX93_PAD_CCM_CLKO2__GPIO3_IO27 0x31e
--
2.37.1
^ permalink raw reply related
* [PATCH v4 1/2] dt-bindings: arm: qcom: Document the Samsung Galaxy Z Fold5
From: Alexandru Marc Serdeliuc via B4 Relay @ 2024-04-07 5:38 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-kernel, Alexandru Marc Serdeliuc
In-Reply-To: <20240407-samsung-galaxy-zfold5-q5q-v4-0-8b67b1813653@yahoo.com>
From: Alexandru Marc Serdeliuc <serdeliuk@yahoo.com>
This documents Samsung Galaxy Z Fold5 (samsung,q5q)
which is a foldable phone by Samsung based on the sm8550 SoC.
Signed-off-by: Alexandru Marc Serdeliuc <serdeliuk@yahoo.com>
---
Documentation/devicetree/bindings/arm/qcom.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index 66beaac60e1d..dea2a23b8fc2 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -1003,6 +1003,7 @@ properties:
- qcom,sm8550-hdk
- qcom,sm8550-mtp
- qcom,sm8550-qrd
+ - samsung,q5q
- const: qcom,sm8550
- items:
--
2.34.1
^ permalink raw reply related
* [PATCH v4 0/2] Samsung Galaxy Z Fold5 initial support
From: Alexandru Marc Serdeliuc via B4 Relay @ 2024-04-07 5:38 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-kernel, Alexandru Marc Serdeliuc
- removed extraneous new line
- removed pcie_1_phy_aux_clk
- removed extranous pcie1
This documents and add intial dts support for Samsung Galaxy Z Fold5 (samsung,q5q)
which is a foldable phone by Samsung based on the sm8550 SoC.
Currently working features:
- Framebuffer
- UFS
- i2c
- Buttons
Signed-off-by: Alexandru Marc Serdeliuc <serdeliuk@yahoo.com>
---
Alexandru Marc Serdeliuc (2):
dt-bindings: arm: qcom: Document the Samsung Galaxy Z Fold5
arm64: dts: qcom: sm8550: Add support for Samsung Galaxy Z Fold5
Documentation/devicetree/bindings/arm/qcom.yaml | 1 +
arch/arm64/boot/dts/qcom/Makefile | 1 +
arch/arm64/boot/dts/qcom/sm8550-samsung-q5q.dts | 593 ++++++++++++++++++++++++
3 files changed, 595 insertions(+)
---
base-commit: 39cd87c4eb2b893354f3b850f916353f2658ae6f
change-id: 20240407-samsung-galaxy-zfold5-q5q-ab1fdb3df966
Best regards,
--
Alexandru Marc Serdeliuc <serdeliuk@yahoo.com>
^ permalink raw reply
* [PATCH v4 2/2] arm64: dts: qcom: sm8550: Add support for Samsung Galaxy Z Fold5
From: Alexandru Marc Serdeliuc via B4 Relay @ 2024-04-07 5:38 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-kernel, Alexandru Marc Serdeliuc
In-Reply-To: <20240407-samsung-galaxy-zfold5-q5q-v4-0-8b67b1813653@yahoo.com>
From: Alexandru Marc Serdeliuc <serdeliuk@yahoo.com>
Add support for Samsung Galaxy Z Fold5 (q5q) foldable phone based on sm8550
Currently working features:
- Framebuffer
- UFS
- i2c
- Buttons
Signed-off-by: Alexandru Marc Serdeliuc <serdeliuk@yahoo.com>
---
arch/arm64/boot/dts/qcom/Makefile | 1 +
arch/arm64/boot/dts/qcom/sm8550-samsung-q5q.dts | 593 ++++++++++++++++++++++++
2 files changed, 594 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 7d40ec5e7d21..a7503fd35b6c 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -241,6 +241,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8450-sony-xperia-nagara-pdx224.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8550-hdk.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8550-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8550-qrd.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sm8550-samsung-q5q.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8650-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8650-qrd.dtb
dtb-$(CONFIG_ARCH_QCOM) += x1e80100-crd.dtb
diff --git a/arch/arm64/boot/dts/qcom/sm8550-samsung-q5q.dts b/arch/arm64/boot/dts/qcom/sm8550-samsung-q5q.dts
new file mode 100644
index 000000000000..4654ae1364ba
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8550-samsung-q5q.dts
@@ -0,0 +1,593 @@
+// SPDX-License-cdsp_memIdentifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Alexandru Marc Serdeliuc <serdeliuk@yahoo.com>
+ * Copyright (c) 2024, David Wronek <david@mainlining.org>
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sm8550.dtsi"
+#include "pm8550.dtsi"
+#include "pm8550vs.dtsi"
+#include "pmk8550.dtsi"
+
+/delete-node/ &adspslpi_mem;
+/delete-node/ &cdsp_mem;
+/delete-node/ &mpss_dsm_mem;
+/delete-node/ &mpss_mem;
+/delete-node/ &rmtfs_mem;
+
+/ {
+ model = "Samsung Galaxy Z Fold5";
+ compatible = "samsung,q5q", "qcom,sm8550";
+ chassis-type = "handset";
+
+ aliases {
+ serial0 = &uart7;
+ };
+
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ framebuffer: framebuffer@b8000000 {
+ compatible = "simple-framebuffer";
+ reg = <0x0 0xb8000000 0x0 0x2b00000>;
+ width = <2176>;
+ height = <1812>;
+ stride = <(2176 * 4)>;
+ format = "a8r8g8b8";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&volume_up_n>;
+ pinctrl-names = "default";
+
+ key-volume-up {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ wakeup-source;
+ };
+ };
+
+ vph_pwr: vph-pwr-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vph_pwr";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ reserved-memory {
+ adspslpi_mem: adspslpi@9ea00000 {
+ reg = <0x0 0x9ea00000 0x0 0x59b4000>;
+ no-map;
+ };
+
+ cdsp_mem: cdsp-region@9c900000 {
+ reg = <0 0x9c900000 0 0x2000000>;
+ no-map;
+ };
+
+ mpss_dsm_mem: mpss-dsm@d4d00000 {
+ reg = <0x0 0xd4d00000 0x0 0x3300000>;
+ no-map;
+ };
+
+ mpss_mem: mpss@8b400000 {
+ reg = <0x0 0x8b400000 0x0 0xfc00000>;
+ no-map;
+ };
+
+ rmtfs_mem: rmtfs-region@d4a80000 {
+ reg = <0x0 0xd4a80000 0x0 0x280000>;
+ no-map;
+ };
+
+ /*
+ * The bootloader will only keep display hardware enabled
+ * if this memory region is named exactly 'splash_region'
+ */
+ splash_region@b8000000 {
+ reg = <0x0 0xb8000000 0x0 0x2b00000>;
+ no-map;
+ };
+ };
+};
+
+&apps_rsc {
+ regulators-0 {
+ compatible = "qcom,pm8550-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ vreg_bob1: bob1 {
+ regulator-name = "vreg_bob1";
+ regulator-min-microvolt = <3296000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_bob2: bob2 {
+ regulator-name = "vreg_bob2";
+ regulator-min-microvolt = <2720000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1b_1p8: ldo1 {
+ regulator-name = "vreg_l1b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2b_3p0: ldo2 {
+ regulator-name = "vreg_l2b_3p0";
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5b_3p1: ldo5 {
+ regulator-name = "vreg_l5b_3p1";
+ regulator-min-microvolt = <3104000>;
+ regulator-max-microvolt = <3104000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6b_1p8: ldo6 {
+ regulator-name = "vreg_l6b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7b_1p8: ldo7 {
+ regulator-name = "vreg_l7b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8b_1p8: ldo8 {
+ regulator-name = "vreg_l8b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9b_2p9: ldo9 {
+ regulator-name = "vreg_l9b_2p9";
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11b_1p2: ldo11 {
+ regulator-name = "vreg_l11b_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12b_1p8: ldo12 {
+ regulator-name = "vreg_l12b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13b_3p0: ldo13 {
+ regulator-name = "vreg_l13b_3p0";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l14b_3p2: ldo14 {
+ regulator-name = "vreg_l14b_3p2";
+ regulator-min-microvolt = <3200000>;
+ regulator-max-microvolt = <3200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l15b_1p8: ldo15 {
+ regulator-name = "vreg_l15b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ regulator-always-on;
+ };
+
+ vreg_l16b_2p8: ldo16 {
+ regulator-name = "vreg_l16b_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l17b_2p5: ldo17 {
+ regulator-name = "vreg_l17b_2p5";
+ regulator-min-microvolt = <2504000>;
+ regulator-max-microvolt = <2504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vreg_l3c_0p91: ldo3 {
+ regulator-name = "vreg_l3c_0p9";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-2 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "d";
+
+ vreg_l1d_0p88: ldo1 {
+ regulator-name = "vreg_l1d_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-3 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "e";
+
+ vreg_s4e_0p9: smps4 {
+ regulator-name = "vreg_s4e_0p9";
+ regulator-min-microvolt = <904000>;
+ regulator-max-microvolt = <984000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s5e_1p1: smps5 {
+ regulator-name = "vreg_s5e_1p1";
+ regulator-min-microvolt = <1080000>;
+ regulator-max-microvolt = <1120000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1e_0p88: ldo1 {
+ regulator-name = "vreg_l1e_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2e_0p9: ldo2 {
+ regulator-name = "vreg_l2e_0p9";
+ regulator-min-microvolt = <904000>;
+ regulator-max-microvolt = <970000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3e_1p2: ldo3 {
+ regulator-name = "vreg_l3e_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-4 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+ qcom,pmic-id = "f";
+
+ vreg_s4f_0p5: smps4 {
+ regulator-name = "vreg_s4f_0p5";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <700000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1f_0p9: ldo1 {
+ regulator-name = "vreg_l1f_0p9";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2f_0p88: ldo2 {
+ regulator-name = "vreg_l2f_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3f_0p91: ldo3 {
+ regulator-name = "vreg_l3f_0p91";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-5 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+ qcom,pmic-id = "g";
+
+ vreg_s1g_1p2: smps1 {
+ regulator-name = "vreg_s1g_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s2g_0p8: smps2 {
+ regulator-name = "vreg_s2g_0p8";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s3g_0p7: smps3 {
+ regulator-name = "vreg_s3g_0p7";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1004000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s4g_1p3: smps4 {
+ regulator-name = "vreg_s4g_1p3";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1352000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s5g_0p8: smps5 {
+ regulator-name = "vreg_s5g_0p8";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1004000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s6g_1p8: smps6 {
+ regulator-name = "vreg_s6g_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1g_1p2: ldo1 {
+ regulator-name = "vreg_l1g_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2g_1p2: ldo2 {
+ regulator-name = "vreg_l2g_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3g_1p2: ldo3 {
+ regulator-name = "vreg_l3g_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-6 {
+ compatible = "qcom,pm8010-rpmh-regulators";
+ qcom,pmic-id = "m";
+
+ vreg_l1m_1p056: ldo1 {
+ regulator-name = "vreg_l1m_1p056";
+ regulator-min-microvolt = <1056000>;
+ regulator-max-microvolt = <1056000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2m_1p056: ldo2 {
+ regulator-name = "vreg_l2m_1p056";
+ regulator-min-microvolt = <1056000>;
+ regulator-max-microvolt = <1056000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3m_2p8: ldo3 {
+ regulator-name = "vreg_l3m_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4m_2p8: ldo4 {
+ regulator-name = "vreg_l4m_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5m_1p8: ldo5 {
+ regulator-name = "vreg_l5m_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6m_1p8: ldo6 {
+ regulator-name = "vreg_l6m_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7m_2p9: ldo7 {
+ regulator-name = "vreg_l7m_2p9";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2904000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-7 {
+ compatible = "qcom,pm8010-rpmh-regulators";
+ qcom,pmic-id = "n";
+
+ vreg_l1n_1p1: ldo1 {
+ regulator-name = "vreg_l1n_1p1";
+ regulator-min-microvolt = <1104000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2n_1p1: ldo2 {
+ regulator-name = "vreg_l2n_1p1";
+ regulator-min-microvolt = <1104000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3n_2p8: ldo3 {
+ regulator-name = "vreg_l3n_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4n_2p8: ldo4 {
+ regulator-name = "vreg_l4n_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5n_1p8: ldo5 {
+ regulator-name = "vreg_l5n_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6n_3p3: ldo6 {
+ regulator-name = "vreg_l6n_3p3";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7n_2p96: ldo7 {
+ regulator-name = "vreg_l7n_2p96";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+};
+
+&dispcc {
+ status = "disabled";
+};
+
+&i2c_master_hub_0 {
+ status = "okay";
+};
+
+&pcie0 {
+ wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+ perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
+ pinctrl-0 = <&pcie0_default_state>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&pcie0_phy {
+ vdda-phy-supply = <&vreg_l1e_0p88>;
+ vdda-pll-supply = <&vreg_l3e_1p2>;
+ status = "okay";
+};
+
+&pm8550_gpios {
+ volume_up_n: volume-up-n-state {
+ pins = "gpio6";
+ function = "normal";
+ power-source = <1>;
+ bias-pull-up;
+ input-enable;
+ };
+};
+
+&pon_pwrkey {
+ status = "okay";
+};
+
+&pon_resin {
+ status = "okay";
+ linux,code = <KEY_VOLUMEDOWN>;
+};
+
+&qupv3_id_0 {
+ status = "okay";
+};
+
+&remoteproc_adsp {
+ firmware-name = "qcom/sm8550/adsp.mdt",
+ "qcom/sm8550/adsp_dtb.mdt";
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/sm8550/cdsp.mdt",
+ "qcom/sm8550/cdsp_dtb.mdt";
+ status = "okay";
+};
+
+&remoteproc_mpss {
+ firmware-name = "qcom/sm8550/modem.mdt",
+ "qcom/sm8550/modem_dtb.mdt";
+ status = "okay";
+};
+
+&sleep_clk {
+ clock-frequency = <32000>;
+};
+
+&tlmm {
+ gpio-reserved-ranges = <36 4>, <50 2>;
+};
+
+&ufs_mem_hc {
+ reset-gpios = <&tlmm 210 GPIO_ACTIVE_LOW>;
+ vcc-supply = <&vreg_l17b_2p5>;
+ vcc-max-microamp = <1300000>;
+ vccq-supply = <&vreg_l1g_1p2>;
+ vccq-max-microamp = <1200000>;
+ vdd-hba-supply = <&vreg_l3g_1p2>;
+ status = "okay";
+};
+
+&ufs_mem_phy {
+ vdda-phy-supply = <&vreg_l1d_0p88>;
+ vdda-pll-supply = <&vreg_l3e_1p2>;
+ status = "okay";
+};
+
+&xo_board {
+ clock-frequency = <76800000>;
+};
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v5 2/4] drm/bridge: add lvds controller support for sam9x7
From: Hari.PrasathGE @ 2024-04-07 6:28 UTC (permalink / raw)
To: Dharma.B, andrzej.hajda, neil.armstrong, rfoss, Laurent.pinchart,
jonas, jernej.skrabec, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, robh+dt, krzysztof.kozlowski+dt, conor+dt, linux,
Nicolas.Ferre, alexandre.belloni, claudiu.beznea, Manikandan.M,
arnd, geert+renesas, Jason, mpe, gerg, rdunlap, vbabka, dri-devel,
devicetree, linux-kernel, linux-arm-kernel, akpm, deller
In-Reply-To: <20240405043536.274220-3-dharma.b@microchip.com>
On 4/5/24 10:05 AM, Dharma Balasubiramani wrote:
> Add a new LVDS controller driver for sam9x7 which does the following:
> - Prepares and enables the LVDS Peripheral clock
> - Defines its connector type as DRM_MODE_CONNECTOR_LVDS and adds itself
> to the global bridge list.
> - Identifies its output endpoint as panel and adds it to the encoder
> display pipeline
> - Enables the LVDS serializer
Acked-by: Hari Prasath Gujulan Elango <hari.prasathge@microchip.com>
>
> Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
> Signed-off-by: Dharma Balasubiramani <dharma.b@microchip.com>
> ---
> Changelog
> v4 -> v5
> - Drop the unused variable 'format'.
> - Use DRM wrapper for dev_err() to maintain uniformity.
> - return -ENODEV instead of -EINVAL to maintain consistency with other DRM
> bridge drivers.
> v3 -> v4
> - No changes.
> v2 ->v3
> - Correct Typo error "serializer".
> - Consolidate get() and prepare() functions and use devm_clk_get_prepared().
> - Remove unused variable 'ret' in probe().
> - Use devm_pm_runtime_enable() and drop the mchp_lvds_remove().
> v1 -> v2
> - Drop 'res' variable and combine two lines into one.
> - Handle deferred probe properly, use dev_err_probe().
> - Don't print anything on deferred probe. Dropped print.
> - Remove the MODULE_ALIAS and add MODULE_DEVICE_TABLE().
> - symbol 'mchp_lvds_driver' was not declared. It should be static.
> ---
> drivers/gpu/drm/bridge/Kconfig | 7 +
> drivers/gpu/drm/bridge/Makefile | 1 +
> drivers/gpu/drm/bridge/microchip-lvds.c | 228 ++++++++++++++++++++++++
> 3 files changed, 236 insertions(+)
> create mode 100644 drivers/gpu/drm/bridge/microchip-lvds.c
>
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index efd996f6c138..889098e2d65f 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -190,6 +190,13 @@ config DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW
> to DP++. This is used with the i.MX6 imx-ldb
> driver. You are likely to say N here.
>
> +config DRM_MICROCHIP_LVDS_SERIALIZER
> + tristate "Microchip LVDS serializer support"
> + depends on OF
> + depends on DRM_ATMEL_HLCDC
> + help
> + Support for Microchip's LVDS serializer.
> +
> config DRM_NWL_MIPI_DSI
> tristate "Northwest Logic MIPI DSI Host controller"
> depends on DRM
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index 017b5832733b..7df87b582dca 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -13,6 +13,7 @@ obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o
> obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) += lontium-lt9611uxc.o
> obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o
> obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o
> +obj-$(CONFIG_DRM_MICROCHIP_LVDS_SERIALIZER) += microchip-lvds.o
> obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
> obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
> obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
> diff --git a/drivers/gpu/drm/bridge/microchip-lvds.c b/drivers/gpu/drm/bridge/microchip-lvds.c
> new file mode 100644
> index 000000000000..149704f498a6
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/microchip-lvds.c
> @@ -0,0 +1,228 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries
> + *
> + * Author: Manikandan Muralidharan <manikandan.m@microchip.com>
> + * Author: Dharma Balasubiramani <dharma.b@microchip.com>
> + *
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/component.h>
> +#include <linux/delay.h>
> +#include <linux/jiffies.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of_graph.h>
> +#include <linux/pinctrl/devinfo.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_bridge.h>
> +#include <drm/drm_of.h>
> +#include <drm/drm_panel.h>
> +#include <drm/drm_print.h>
> +#include <drm/drm_probe_helper.h>
> +#include <drm/drm_simple_kms_helper.h>
> +
> +#define LVDS_POLL_TIMEOUT_MS 1000
> +
> +/* LVDSC register offsets */
> +#define LVDSC_CR 0x00
> +#define LVDSC_CFGR 0x04
> +#define LVDSC_SR 0x0C
> +#define LVDSC_WPMR 0xE4
> +
> +/* Bitfields in LVDSC_CR (Control Register) */
> +#define LVDSC_CR_SER_EN BIT(0)
> +
> +/* Bitfields in LVDSC_CFGR (Configuration Register) */
> +#define LVDSC_CFGR_PIXSIZE_24BITS 0
> +#define LVDSC_CFGR_DEN_POL_HIGH 0
> +#define LVDSC_CFGR_DC_UNBALANCED 0
> +#define LVDSC_CFGR_MAPPING_JEIDA BIT(6)
> +
> +/*Bitfields in LVDSC_SR */
> +#define LVDSC_SR_CS BIT(0)
> +
> +/* Bitfields in LVDSC_WPMR (Write Protection Mode Register) */
> +#define LVDSC_WPMR_WPKEY_MASK GENMASK(31, 8)
> +#define LVDSC_WPMR_WPKEY_PSSWD 0x4C5644
> +
> +struct mchp_lvds {
> + struct device *dev;
> + void __iomem *regs;
> + struct clk *pclk;
> + struct drm_panel *panel;
> + struct drm_bridge bridge;
> + struct drm_bridge *panel_bridge;
> +};
> +
> +static inline struct mchp_lvds *bridge_to_lvds(struct drm_bridge *bridge)
> +{
> + return container_of(bridge, struct mchp_lvds, bridge);
> +}
> +
> +static inline u32 lvds_readl(struct mchp_lvds *lvds, u32 offset)
> +{
> + return readl_relaxed(lvds->regs + offset);
> +}
> +
> +static inline void lvds_writel(struct mchp_lvds *lvds, u32 offset, u32 val)
> +{
> + writel_relaxed(val, lvds->regs + offset);
> +}
> +
> +static void lvds_serialiser_on(struct mchp_lvds *lvds)
> +{
> + unsigned long timeout = jiffies + msecs_to_jiffies(LVDS_POLL_TIMEOUT_MS);
> +
> + /* The LVDSC registers can only be written if WPEN is cleared */
> + lvds_writel(lvds, LVDSC_WPMR, (LVDSC_WPMR_WPKEY_PSSWD &
> + LVDSC_WPMR_WPKEY_MASK));
> +
> + /* Wait for the status of configuration registers to be changed */
> + while (lvds_readl(lvds, LVDSC_SR) & LVDSC_SR_CS) {
> + if (time_after(jiffies, timeout)) {
> + DRM_DEV_ERROR(lvds->dev, "%s: timeout error\n",
> + __func__);
> + return;
> + }
> + usleep_range(1000, 2000);
> + }
> +
> + /* Configure the LVDSC */
> + lvds_writel(lvds, LVDSC_CFGR, (LVDSC_CFGR_MAPPING_JEIDA |
> + LVDSC_CFGR_DC_UNBALANCED |
> + LVDSC_CFGR_DEN_POL_HIGH |
> + LVDSC_CFGR_PIXSIZE_24BITS));
> +
> + /* Enable the LVDS serializer */
> + lvds_writel(lvds, LVDSC_CR, LVDSC_CR_SER_EN);
> +}
> +
> +static int mchp_lvds_attach(struct drm_bridge *bridge,
> + enum drm_bridge_attach_flags flags)
> +{
> + struct mchp_lvds *lvds = bridge_to_lvds(bridge);
> +
> + bridge->encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
> +
> + return drm_bridge_attach(bridge->encoder, lvds->panel_bridge,
> + bridge, flags);
> +}
> +
> +static void mchp_lvds_enable(struct drm_bridge *bridge)
> +{
> + struct mchp_lvds *lvds = bridge_to_lvds(bridge);
> + int ret;
> +
> + ret = clk_enable(lvds->pclk);
> + if (ret < 0) {
> + DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret);
> + return;
> + }
> +
> + ret = pm_runtime_get_sync(lvds->dev);
> + if (ret < 0) {
> + DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
> + clk_disable(lvds->pclk);
> + return;
> + }
> +
> + lvds_serialiser_on(lvds);
> +}
> +
> +static void mchp_lvds_disable(struct drm_bridge *bridge)
> +{
> + struct mchp_lvds *lvds = bridge_to_lvds(bridge);
> +
> + pm_runtime_put(lvds->dev);
> + clk_disable(lvds->pclk);
> +}
> +
> +static const struct drm_bridge_funcs mchp_lvds_bridge_funcs = {
> + .attach = mchp_lvds_attach,
> + .enable = mchp_lvds_enable,
> + .disable = mchp_lvds_disable,
> +};
> +
> +static int mchp_lvds_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct mchp_lvds *lvds;
> + struct device_node *port;
> +
> + if (!dev->of_node)
> + return -ENODEV;
> +
> + lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL);
> + if (!lvds)
> + return -ENOMEM;
> +
> + lvds->dev = dev;
> +
> + lvds->regs = devm_ioremap_resource(lvds->dev,
> + platform_get_resource(pdev, IORESOURCE_MEM, 0));
> + if (IS_ERR(lvds->regs))
> + return PTR_ERR(lvds->regs);
> +
> + lvds->pclk = devm_clk_get_prepared(lvds->dev, "pclk");
> + if (IS_ERR(lvds->pclk))
> + return dev_err_probe(lvds->dev, PTR_ERR(lvds->pclk),
> + "could not get pclk_lvds prepared\n");
> +
> + port = of_graph_get_remote_node(dev->of_node, 1, 0);
> + if (!port) {
> + DRM_DEV_ERROR(dev,
> + "can't find port point, please init lvds panel port!\n");
> + return -ENODEV;
> + }
> +
> + lvds->panel = of_drm_find_panel(port);
> + of_node_put(port);
> +
> + if (IS_ERR(lvds->panel))
> + return -EPROBE_DEFER;
> +
> + lvds->panel_bridge = devm_drm_panel_bridge_add(dev, lvds->panel);
> +
> + if (IS_ERR(lvds->panel_bridge))
> + return PTR_ERR(lvds->panel_bridge);
> +
> + lvds->bridge.of_node = dev->of_node;
> + lvds->bridge.type = DRM_MODE_CONNECTOR_LVDS;
> + lvds->bridge.funcs = &mchp_lvds_bridge_funcs;
> +
> + dev_set_drvdata(dev, lvds);
> + devm_pm_runtime_enable(dev);
> +
> + drm_bridge_add(&lvds->bridge);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id mchp_lvds_dt_ids[] = {
> + {
> + .compatible = "microchip,sam9x75-lvds",
> + },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, mchp_lvds_dt_ids);
> +
> +static struct platform_driver mchp_lvds_driver = {
> + .probe = mchp_lvds_probe,
> + .driver = {
> + .name = "microchip-lvds",
> + .of_match_table = mchp_lvds_dt_ids,
> + },
> +};
> +module_platform_driver(mchp_lvds_driver);
> +
> +MODULE_AUTHOR("Manikandan Muralidharan <manikandan.m@microchip.com>");
> +MODULE_AUTHOR("Dharma Balasubiramani <dharma.b@microchip.com>");
> +MODULE_DESCRIPTION("Low Voltage Differential Signaling Controller Driver");
> +MODULE_LICENSE("GPL");
^ permalink raw reply
* Re: [PATCH v2] dt-bindings: omap-mcpdm: Convert to DT schema
From: Mithil @ 2024-04-07 7:11 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, alsa-devel, devicetree, linux-kernel
In-Reply-To: <352672fc-b6e1-458e-b4f9-840a8ba07c7e@linaro.org>
On Fri, Apr 5, 2024 at 11:49 PM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 05/04/2024 19:21, Mithil wrote:
> > On Fri, Apr 5, 2024 at 10:38 PM Krzysztof Kozlowski
> > <krzysztof.kozlowski@linaro.org> wrote:
> >>
> >> On 05/04/2024 18:29, Mithil wrote:
> >>> On Fri, Apr 5, 2024 at 9:27 PM Krzysztof Kozlowski
> >>> <krzysztof.kozlowski@linaro.org> wrote:
> >>>>
> >>>> On 05/04/2024 16:48, Mithil wrote:
> >>>>> So sorry about the 2nd patch being sent as a new mail, here is a new
> >>>>> patch with the changes as suggested
> >>>>>
> >>>>>> Please use subject prefixes matching the subsystem
> >>>>> Changed the patch name to match the folder history.
> >>>>
> >>>> Nothing improved. What the history tells you?
> >>>>
> >>>
> >>> Referred to "ASoC: dt-bindings: rt1015: Convert to dtschema"
> >>> Not really sure what else I should change.
> >>
> >> But the subject you wrote here is "dt-bindings: omap-mcpdm: Convert to
> >> DT schema"?
> >>
> >> Where is the ASoC?
> >>
> > I did change it, will send the patch again.
> >
> >>
> >> reg is not correct. Please point me to files doing that way, so I can
> >> fix them.
> >>
> >> You need items with description.
> >>
> > Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml
> > I referred here for the description, but will add items for the 2 regs
>
> I don't see at all the code you are using. It's entirely different!
> Where in this file is that type of "reg" property?
>
Changed it to use items and description. Was not aware about this
format apologies.
> >
> >>> Interrupts and hwmods use maxItems now.
> >>
> >> hwmods lost description, why?
> > Seems self explanatory.
>
> Really? Not to me. I have no clue what this is. Also, you need
> description for (almost) every non-standard, vendor property.
>
Re-added it as it was previously.
> >
> >>> Changed nodename to be generic in example as well.
> >>
> >> "mcpdm" does not feel generic. What is mcpdm? Google finds nothing.
> >> Maybe just "pdm"?
> >>
> > Multichannel PDM Controller. Kept it like that since the node is also
>
> You said you "changed nodename". So from what did you change to what?
>
> > called as mcpdm in the devicetree. Calling it pdm might cause
>
> Poor DTS is not the example...
>
> > confusion.
>
> So far I am confused. Often name of SoC block is specific, not generic.
> Anyway, that's not important part, so if you claim mcpdm is generic name
> of a class of devices, I am fine.
>
Changed to pdm.
Here's the patch,
From 9fb94e551da1ff06d489f60d52335001a9de9976 Mon Sep 17 00:00:00 2001
From: Mithil Bavishi <bavishimithil@gmail.com>
Date: Mon, 1 Apr 2024 21:10:15 +0530
Subject: [PATCH] ASoC: dt-bindings: omap-mcpdm: Convert to DT schema
Convert the OMAP4+ McPDM bindings to DT schema.
Signed-off-by: Mithil Bavishi <bavishimithil@gmail.com>
---
.../devicetree/bindings/sound/omap-mcpdm.txt | 30 ----------
.../bindings/sound/ti,omap4-mcpdm.yaml | 58 +++++++++++++++++++
2 files changed, 58 insertions(+), 30 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/sound/omap-mcpdm.txt
create mode 100644 Documentation/devicetree/bindings/sound/ti,omap4-mcpdm.yaml
diff --git a/Documentation/devicetree/bindings/sound/omap-mcpdm.txt
b/Documentation/devicetree/bindings/sound/omap-mcpdm.txt
deleted file mode 100644
index ff98a0cb5..000000000
--- a/Documentation/devicetree/bindings/sound/omap-mcpdm.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-* Texas Instruments OMAP4+ McPDM
-
-Required properties:
-- compatible: "ti,omap4-mcpdm"
-- reg: Register location and size as an array:
- <MPU access base address, size>,
- <L3 interconnect address, size>;
-- interrupts: Interrupt number for McPDM
-- ti,hwmods: Name of the hwmod associated to the McPDM
-- clocks: phandle for the pdmclk provider, likely <&twl6040>
-- clock-names: Must be "pdmclk"
-
-Example:
-
-mcpdm: mcpdm@40132000 {
- compatible = "ti,omap4-mcpdm";
- reg = <0x40132000 0x7f>, /* MPU private access */
- <0x49032000 0x7f>; /* L3 Interconnect */
- interrupts = <0 112 0x4>;
- interrupt-parent = <&gic>;
- ti,hwmods = "mcpdm";
-};
-
-In board DTS file the pdmclk needs to be added:
-
-&mcpdm {
- clocks = <&twl6040>;
- clock-names = "pdmclk";
- status = "okay";
-};
diff --git a/Documentation/devicetree/bindings/sound/ti,omap4-mcpdm.yaml
b/Documentation/devicetree/bindings/sound/ti,omap4-mcpdm.yaml
new file mode 100644
index 000000000..73fcfaf6e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ti,omap4-mcpdm.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/ti,omap4-mcpdm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: OMAP McPDM
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+description:
+ OMAP ALSA SoC DAI driver using McPDM port used by TWL6040
+
+properties:
+ compatible:
+ const: ti,omap4-mcpdm
+
+ reg:
+ items:
+ - description: MPU access base address
+ - description: L3 interconnect address
+
+ interrupts:
+ maxItems: 1
+
+ ti,hwmods:
+ description: Name of the hwmod associated to the McPDM, likely "mcpdm"
+
+ clocks:
+ description: phandle for the pdmclk provider, likely <&twl6040>
+
+ clock-names:
+ description: Must be "pdmclk"
+
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - ti,hwmods
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ pdm@0 {
+ compatible = "ti,omap4-mcpdm";
+ reg = <0x40132000 0x7f>, /* MPU private access */
+ <0x49032000 0x7f>; /* L3 Interconnect */
+ interrupts = <0 112 0x4>;
+ interrupt-parent = <&gic>;
+ ti,hwmods = "mcpdm";
+ clocks = <&twl6040>;
+ clock-names = "pdmclk";
+ };
--
2.34.1
Best regards,
Mithil
^ permalink raw reply related
* Re: [PATCH v2 0/2] Enable JPEG encoding on rk3588
From: Nicolas Dufresne @ 2024-04-07 8:08 UTC (permalink / raw)
To: Link Mauve
Cc: linux-kernel, Ezequiel Garcia, Philipp Zabel,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Heiko Stuebner, Joerg Roedel, Will Deacon,
Robin Murphy, Sebastian Reichel, Cristian Ciocaltea, Dragan Simic,
Shreeya Patel, Chris Morgan, Andy Yan, Nicolas Frattaroli,
linux-media, linux-rockchip, devicetree, linux-arm-kernel, iommu
In-Reply-To: <ZhAI6tQZTD7BTosI@desktop>
Le vendredi 05 avril 2024 à 16:21 +0200, Link Mauve a écrit :
> On Thu, Apr 04, 2024 at 01:41:15PM -0400, Nicolas Dufresne wrote:
> > Hi,
>
> Hi,
>
> >
> > Le mercredi 27 mars 2024 à 14:41 +0100, Emmanuel Gil Peyrot a écrit :
> > > Only the JPEG encoder is available for now, although there are patches
> > > for the undocumented VP8 encoder floating around[0].
> >
> > [0] seems like a broken link. The VP8 encoder RFC is for RK3399 (and Hantro H1
> > posted by ST more recently). The TRM says "VEPU121(JPEG encoder only)", which
> > suggest that the H.264 and VP8 encoders usually found on the VEPU121 are
> > removed. As Rockchip have remove the synthesize register while modifying the H1
> > IP, it is difficult to verify. Confusingly the H.264 specific registers are
> > documented in the TRM around VEPU121.
>
> Ah, the link became, and was indeed ST’s series:
> https://patchwork.kernel.org/project/linux-rockchip/list/?series=789885&archive=both
>
> But the TRM part 1 says the VEPU121 supports H.264 encoding (page 367),
> and it’s likely they didn’t remove just VP8 support since the codec
> features are pretty close to H.264’s.
>
> >
> > >
> > > This has been tested on a rock-5b, resulting in four /dev/video*
> > > encoders. The userspace program I’ve been using to test them is
> > > Onix[1], using the jpeg-encoder example, it will pick one of these four
> > > at random (but displays the one it picked):
> > > % ffmpeg -i <input image> -pix_fmt yuvj420p temp.yuv
> > > % jpeg-encoder temp.yuv <width> <height> NV12 <quality> output.jpeg
> >
> > I don't like that we exposing each identical cores a separate video nodes. I
> > think we should aim for 1 device, and then multi-plex and schedule de cores from
> > inside the Linux kernel.
>
> I agree, but this should be handled in the driver not in the device
> tree, and it can be done later.
As the behaviour we want is that these cores becomes a group and get schedule
together, its certainly a good time to slow down and evaluate if that part needs
to be improve in the DT too.
Hantro G1/H1 and VEPU/VDPU121 combos originally shared the same sram region. Its
not clear if any of these cores have this limitation and if this should be
expressed in the DT / driver.
>
> >
> > Not doing this now means we'll never have an optimal hardware usage
> > distribution. Just consider two userspace software wanting to do jpeg encoding.
> > If they both take a guess, they may endup using a single core. Where with proper
> > scheduling in V4L2, the kernel will be able to properly distribute the load. I
> > insist on this, since if we merge you changes it becomes an ABI and we can't
> > change it anymore.
>
> Will it really become ABI just like that? Userspace should always
> discover the video nodes and their capabilities and not hardcode e.g. a
> specific /dev/videoN file for a specific codec. I would argue that this
> series would let userspace do JPEG encoding right away, even if in a
> less optimal way than if the driver would round-robin them through a
> single video node, but that can always be added in a future version.
Might be on the gray side, but there is good chances software written for your
specific board can stop working after te grouping is done.
>
> >
> > I understand that this impose a rework of the mem2mem framework so that we can
> > run multiple jobs, but this will be needed anyway on RK3588, since the rkvdec2,
> > which we don't have a driver yet is also multi-core, but you need to use 2 cores
> > when the resolution is close to 8K.
>
> I think the mediatek JPEG driver already supports that, would it be ok
> to do it the same way?
I don't know for JPEG, the MTK vcoder do support cascading cores. This is
different from concurrent cores. In MTK architecture, for some of the codec,
there is LAT (entropy decoder) and CORE (the reconstruction block) that are
split.
Nicolas
^ permalink raw reply
* Re: [PATCH v3 09/25] media: i2c: imx258: Add support for running on 2 CSI data lanes
From: Kieran Bingham @ 2024-04-07 8:51 UTC (permalink / raw)
To: Luis Garcia, Pavel Machek
Cc: linux-media, dave.stevenson, jacopo.mondi, mchehab, robh,
krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
linux-kernel, phone-devel
In-Reply-To: <803b0bd3-e615-41c1-888e-69b6ecca0b8a@luigi311.com>
Quoting Luis Garcia (2024-04-06 06:25:41)
> On 4/3/24 12:45, Pavel Machek wrote:
> > Hi!
> >
> >> +/*
> >> + * 4208x3120 @ 30 fps needs 1267Mbps/lane, 4 lanes.
> >> + * To avoid further computation of clock settings, adopt the same per
> >> + * lane data rate when using 2 lanes, thus allowing a maximum of 15fps.
> >> + */
> >> +static const struct imx258_reg mipi_1267mbps_19_2mhz_2l[] = {
> >> + { 0x0136, 0x13 },
> >> + { 0x0137, 0x33 },
> >> + { 0x0301, 0x0A },
> >> + { 0x0303, 0x02 },
> >> + { 0x0305, 0x03 },
> >> + { 0x0306, 0x00 },
> >> + { 0x0307, 0xC6 },
> >> + { 0x0309, 0x0A },
> >> + { 0x030B, 0x01 },
> >> + { 0x030D, 0x02 },
> >> + { 0x030E, 0x00 },
> >> + { 0x030F, 0xD8 },
> >> + { 0x0310, 0x00 },
> >> +
> >> + { 0x0114, 0x01 },
> >> + { 0x0820, 0x09 },
> >> + { 0x0821, 0xa6 },
> >> + { 0x0822, 0x66 },
> >> + { 0x0823, 0x66 },
> >> +};
> >> +
> >> +static const struct imx258_reg mipi_1267mbps_19_2mhz_4l[] = {
> >> { 0x0136, 0x13 },
> >> { 0x0137, 0x33 },
> >> { 0x0301, 0x05 },
> >
> > I wish we did not have to copy all the magic values like this.
> >
> > Best regards,
> > Pavel
> >
>
> no kidding, magic values everywhere.... it makes it annoying
> for me to move things around because they all start to look
> similar. Down the line we added in more defined names so its
> not as bad but still its bad lol.
This series converts the defines to names, which is great. It would have
been nicer if the series converted first, but I know the history here
means you have done the register naming on top of existing patches - so
I don't think there's a requirement to change the ordering now.
But I see new drivers coming in with register tables. I hope we can
start to apply more pressure to driver submitters to use higher quality
named register sets in the future, now that we have a greater precendent
of sensor drivers 'doing the right thing'.
Sets of tables like we have are basically a binary blob stored as ascii
and make maintainance far more difficult IMO.
Maybe I should hit send on my comments on the latest GalaxyCore driver
coming in that I hesitated on ...
--
Kieran
^ permalink raw reply
* Re: [PATCH v2 1/6] dt-bindings: firmware: arm,scmi: set additionalProperties to true
From: Krzysztof Kozlowski @ 2024-04-07 8:55 UTC (permalink / raw)
To: Peng Fan, Peng Fan (OSS), Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Sudeep Holla, Cristian Marussi
Cc: devicetree@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <DU0PR04MB9417932A6208128FBBB22C4188012@DU0PR04MB9417.eurprd04.prod.outlook.com>
On 07/04/2024 02:37, Peng Fan wrote:
>> Subject: Re: [PATCH v2 1/6] dt-bindings: firmware: arm,scmi: set
>> additionalProperties to true
>>
>> On 05/04/2024 14:39, Peng Fan (OSS) wrote:
>>> From: Peng Fan <peng.fan@nxp.com>
>>>
>>> When adding vendor extension protocols, there is dt-schema warning:
>>> "
>>> imx,scmi.example.dtb: scmi: 'protocol@81', 'protocol@84' do not match
>>> any of the regexes: 'pinctrl-[0-9]+'
>>> "
>>>
>>> Set additionalProperties to true to address the issue.
>>
>> I do not see anything addressed here, except making the binding accepting
>> anything anywhere...
>
> I not wanna add vendor protocols in arm,scmi.yaml, so will introduce
> a new yaml imx.scmi.yaml which add i.MX SCMI protocol extension.
>
> With additionalProperties set to false, I not know how, please suggest.
First of all, you cannot affect negatively existing devices (their
bindings) and your patch does exactly that. This should make you thing
what is the correct approach...
Rob gave you the comment about missing compatible - you still did not
address that.
You need common schema referenced in arm,scmi and your device specific
schema, also using it.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v2 2/6] dt-bindings: firmware: add i.MX SCMI Extension protocol
From: Krzysztof Kozlowski @ 2024-04-07 8:57 UTC (permalink / raw)
To: Peng Fan, Peng Fan (OSS), Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Sudeep Holla, Cristian Marussi
Cc: devicetree@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <DU0PR04MB941719A18C3F749E7D180FD888012@DU0PR04MB9417.eurprd04.prod.outlook.com>
On 07/04/2024 02:51, Peng Fan wrote:
>> Subject: Re: [PATCH v2 2/6] dt-bindings: firmware: add i.MX SCMI Extension
>> protocol
>>
>> On 05/04/2024 14:39, Peng Fan (OSS) wrote:
>>> From: Peng Fan <peng.fan@nxp.com>
>>>
>>> Add i.MX SCMI Extension protocols bindings for:
>>> - Battery Backed Secure Module(BBSM)
>>
>> Which is what?
>
> I should say BBM(BBSM + BBNSM), BBM has RTC and ON/OFF
> key features, but BBM is managed by SCMI firmware and exported
> to agent by BBM protocol. So add bindings for i.MX BBM protocol.
>
> Is this ok?
No, I still don't know what is BBSM, BBNSM and BBM.
>
>>
>>> - MISC settings such as General Purpose Registers settings.
>>>
>>> Signed-off-by: Peng Fan <peng.fan@nxp.com>
>>> ---
>>> .../devicetree/bindings/firmware/imx,scmi.yaml | 80
>> ++++++++++++++++++++++
>>> 1 file changed, 80 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/firmware/imx,scmi.yaml
>>> b/Documentation/devicetree/bindings/firmware/imx,scmi.yaml
>>> new file mode 100644
>>> index 000000000000..7ee19a661d83
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/firmware/imx,scmi.yaml
>>> @@ -0,0 +1,80 @@
>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) # Copyright 2024
>>> +NXP %YAML 1.2
>>> +---
>>> +$id:
>>> +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevi
>>>
>> +cetree.org%2Fschemas%2Ffirmware%2Fimx%2Cscmi.yaml%23&data=05%7
>> C02%7Cp
>>>
>> +eng.fan%40nxp.com%7C5d16781d3eca425a342508dc562910b7%7C686ea
>> 1d3bc2b4c
>>>
>> +6fa92cd99c5c301635%7C0%7C0%7C638479981570959816%7CUnknown%
>> 7CTWFpbGZsb
>>>
>> +3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn
>> 0%3D
>>>
>> +%7C0%7C%7C%7C&sdata=mWNwPvu2eyF18MroVOBHb%2Fjeo%2BIHfV5V
>> h%2F9ebdx65MM
>>> +%3D&reserved=0
>>> +$schema:
>>> +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevi
>>> +cetree.org%2Fmeta-
>> schemas%2Fcore.yaml%23&data=05%7C02%7Cpeng.fan%40nx
>>>
>> +p.com%7C5d16781d3eca425a342508dc562910b7%7C686ea1d3bc2b4c6fa
>> 92cd99c5c
>>>
>> +301635%7C0%7C0%7C638479981570971949%7CUnknown%7CTWFpbGZs
>> b3d8eyJWIjoiM
>>>
>> +C4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7
>> C%7C%7
>>>
>> +C&sdata=v4XnGG00D4I8j5MJvDUVYMRTm7yRrvz0V3fUyc5KAAA%3D&reser
>> ved=0
>>> +
>>> +title: i.MX System Control and Management Interface(SCMI) Vendor
>>> +Protocols Extension
>>> +
>>> +maintainers:
>>> + - Peng Fan <peng.fan@nxp.com>
>>> +
>>> +allOf:
>>> + - $ref: arm,scmi.yaml#
>>
>> Sorry, but arm,scmi is a final schema. Is your plan to define some common
>> part?
>
> No. I just wanna add vendor extension per SCMI spec.
>
> 0x80-0xFF:
> Reserved for vendor or platform-specific extensions to this interface
>
> Each vendor may have different usage saying id 0x81, so I add
> i.MX dt-schema file.
>
>>
>>> +
>>> +properties:
>>> + protocol@81:
>>> + $ref: 'arm,scmi.yaml#/$defs/protocol-node'
>>> + unevaluatedProperties: false
>>> + description:
>>> + The BBM Protocol is for managing Battery Backed Secure Module
>> (BBSM) RTC
>>> + and the ON/OFF Key
>>> +
>>> + properties:
>>> + reg:
>>> + const: 0x81
>>> +
>>> + required:
>>> + - reg
>>> +
>>> + protocol@84:
>>> + $ref: 'arm,scmi.yaml#/$defs/protocol-node'
>>> + unevaluatedProperties: false
>>> + description:
>>> + The MISC Protocol is for managing SoC Misc settings, such as
>>> + GPR settings
>>
>> Genera register is not a setting... this is a pleonasm. Please be more specific
>> what is the GPR, MISC protocol etc.
>
> The MISC Protocol is for managing SoC Misc settings, such as SAI MCLK/MQS in
> Always On domain BLK CTRL, SAI_CLK_SEL in WAKEUP BLK CTRL, gpio
> expanders which is under control of SCMI firmware.
So like a bag for everything which you do not want to call something
specific?
No, be specific...
>
>>> +
>>> + properties:
>>> + reg:
>>> + const: 0x84
>>> +
>>> + wakeup-sources:
>>> + description:
>>> + Each entry consists of 2 integers, represents the source
>>> + and electric signal edge
>>
>> Can you answer questions from reviewers?
>
> Sorry. Is this ok?
> minItems: 1
> maxItems: 32
No. Does it answers Rob's question? I see zero correlation to his question.
Do not ignore emails from reviewers but respond to them.
>
>>
>>> + items:
>>> + items:
>>> + - description: the wakeup source
>>> + - description: the wakeup electric signal edge
>>> + $ref: /schemas/types.yaml#/definitions/uint32-matrix
>>> +
>>> + required:
>>> + - reg
>>> +
>>> +additionalProperties: false
>>> +
>>> +examples:
>>> + - |
>>> + firmware {
>>> + scmi {
>>> + compatible = "arm,scmi";
>>
>>> + mboxes = <&mu2 5 0>, <&mu2 3 0>, <&mu2 3 1>;
>>> + shmem = <&scmi_buf0>, <&scmi_buf1>;
>>> +
>>> + #address-cells = <1>;
>>> + #size-cells = <0>;
>>> +
>>> + protocol@81 {
>>> + reg = <0x81>;
>>> + };
>>> +
>>> + protocol@84 {
>>> + reg = <0x84>;
>>> + wakeup-sources = <0x8000 1
>>> + 0x8001 1
>>> + 0x8002 1
>>> + 0x8003 1
>>> + 0x8004 1>;
>>
>> Nothing improved... If you are going to ignore reviews, then you will only get
>> NAKed.
>
> Sorry, you mean the examples, or the whole dt-schema?
*Read comments and respond to them*. Regardless where they are.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v9 3/6] dt-bindings: pci: qcom: Add opp table
From: Krzysztof Kozlowski @ 2024-04-07 9:00 UTC (permalink / raw)
To: Krishna chaitanya chundru, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Bjorn Helgaas, johan+linaro, bmasney,
djakov
Cc: linux-arm-msm, devicetree, linux-kernel, linux-pci, vireshk,
quic_vbadigan, quic_skananth, quic_nitegupt, quic_parass
In-Reply-To: <20240407-opp_support-v9-3-496184dc45d7@quicinc.com>
On 07/04/2024 06:37, Krishna chaitanya chundru wrote:
> PCIe needs to choose the appropriate performance state of RPMH power
> domain based upon the PCIe gen speed.
>
> Adding the Operating Performance Points table allows to adjust power
> domain performance state and icc peak bw, depending on the PCIe gen
> speed and width.
>
> Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
> ---
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v4 1/2] dt-bindings: arm: qcom: Document the Samsung Galaxy Z Fold5
From: Krzysztof Kozlowski @ 2024-04-07 9:01 UTC (permalink / raw)
To: serdeliuk, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <20240407-samsung-galaxy-zfold5-q5q-v4-1-8b67b1813653@yahoo.com>
On 07/04/2024 07:38, Alexandru Marc Serdeliuc via B4 Relay wrote:
> From: Alexandru Marc Serdeliuc <serdeliuk@yahoo.com>
>
> This documents Samsung Galaxy Z Fold5 (samsung,q5q)
> which is a foldable phone by Samsung based on the sm8550 SoC.
>
> Signed-off-by: Alexandru Marc Serdeliuc <serdeliuk@yahoo.com>
> ---
This is a friendly reminder during the review process.
It looks like you received a tag and forgot to add it.
If you do not know the process, here is a short explanation:
Please add Acked-by/Reviewed-by/Tested-by tags when posting new
versions, under or above your Signed-off-by tag. Tag is "received", when
provided in a message replied to you on the mailing list. Tools like b4
can help here. However, there's no need to repost patches *only* to add
the tags. The upstream maintainer will do that for tags received on the
version they apply.
https://elixir.bootlin.com/linux/v6.5-rc3/source/Documentation/process/submitting-patches.rst#L577
If a tag was not added on purpose, please state why and what changed.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v4 2/2] arm64: dts: qcom: sm8550: Add support for Samsung Galaxy Z Fold5
From: Krzysztof Kozlowski @ 2024-04-07 9:03 UTC (permalink / raw)
To: serdeliuk, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <20240407-samsung-galaxy-zfold5-q5q-v4-2-8b67b1813653@yahoo.com>
On 07/04/2024 07:38, Alexandru Marc Serdeliuc via B4 Relay wrote:
> From: Alexandru Marc Serdeliuc <serdeliuk@yahoo.com>
>
> Add support for Samsung Galaxy Z Fold5 (q5q) foldable phone based on sm8550
>
> Currently working features:
> - Framebuffer
> - UFS
> - i2c
> - Buttons
>
> Signed-off-by: Alexandru Marc Serdeliuc <serdeliuk@yahoo.com>
> ---
> arch/arm64/boot/dts/qcom/Makefile | 1 +
Where is the changelog? This is v4 and nothing (neither here nor in
cover letter) explained what was happening with this patchset.
Tags were ignored, so maybe comments as well?
Please provide *full* and detailed changelog.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v1 1/1] arm64: dts: imx93-11x11-evk: add rtc PCF2131 support
From: Krzysztof Kozlowski @ 2024-04-07 9:04 UTC (permalink / raw)
To: Joy Zou, ping.bai, robh+dt, krzysztof.kozlowski+dt, conor+dt,
shawnguo, s.hauer
Cc: kernel, festevam, linux-imx, devicetree, imx, linux-arm-kernel,
linux-kernel
In-Reply-To: <20240407051913.1989364-2-joy.zou@nxp.com>
On 07/04/2024 07:19, Joy Zou wrote:
> Support rtc PCF2131 on imx93-11x11-evk.
>
> Signed-off-by: Joy Zou <joy.zou@nxp.com>
> ---
> .../boot/dts/freescale/imx93-11x11-evk.dts | 25 +++++++++++++++++++
> 1 file changed, 25 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
> index 07e85a30a25f..065fa3390791 100644
> --- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
> @@ -281,6 +281,24 @@ ldo5: LDO5 {
> };
> };
>
> +&lpi2c3 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + clock-frequency = <400000>;
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&pinctrl_lpi2c3>;
> + pinctrl-1 = <&pinctrl_lpi2c3>;
> + status = "okay";
> +
> + pcf2131: rtc@53 {
> + compatible = "nxp,pcf2131";
> + reg = <0x53>;
> + interrupt-parent = <&pcal6524>;
> + interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
> + status = "okay";
Really, just drop...
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v4 4/5] dt-bindings: fsl-imx-sdma: Add I2C peripheral types ID
From: Krzysztof Kozlowski @ 2024-04-07 9:04 UTC (permalink / raw)
To: Frank Li, Vinod Koul, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joy Zou
Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree, imx
In-Reply-To: <20240329-sdma_upstream-v4-4-daeb3067dea7@nxp.com>
On 29/03/2024 15:34, Frank Li wrote:
> Add peripheral types ID 26 for I2C because sdma firmware (sdma-6q: v3.6,
> sdma-7d: v4.6) support I2C DMA transfer.
>
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
This is a friendly reminder during the review process.
It looks like you received a tag and forgot to add it.
If you do not know the process, here is a short explanation:
Please add Acked-by/Reviewed-by/Tested-by tags when posting new
versions, under or above your Signed-off-by tag. Tag is "received", when
provided in a message replied to you on the mailing list. Tools like b4
can help here. However, there's no need to repost patches *only* to add
the tags. The upstream maintainer will do that for tags received on the
version they apply.
https://elixir.bootlin.com/linux/v6.5-rc3/source/Documentation/process/submitting-patches.rst#L577
If a tag was not added on purpose, please state why and what changed.
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v3 1/2] dt-bindings: arm: qcom: Add Motorola Moto G (2013)
From: Stanislav Jakubek @ 2024-04-07 9:05 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-arm-kernel, phone-devel,
linux-kernel
Document the Motorola Moto G (2013), which is a smartphone based
on the Qualcomm MSM8226 SoC.
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Stanislav Jakubek <stano.jakubek@gmail.com>
---
Changes in V3:
- no changes
Changes in V2:
- collect Krzysztof's A-b
Documentation/devicetree/bindings/arm/qcom.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index 66beaac60e1d..d2910982ae86 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -137,6 +137,7 @@ properties:
- microsoft,dempsey
- microsoft,makepeace
- microsoft,moneypenny
+ - motorola,falcon
- samsung,s3ve3g
- const: qcom,msm8226
--
2.34.1
^ permalink raw reply related
* [PATCH v3 2/2] ARM: dts: qcom: Add support for Motorola Moto G (2013)
From: Stanislav Jakubek @ 2024-04-07 9:05 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-arm-kernel, phone-devel,
linux-kernel
In-Reply-To: <32c507337ab80c550fb1df08f7014d1e31eb4c32.1712480582.git.stano.jakubek@gmail.com>
Add a device tree for the Motorola Moto G (2013) smartphone based
on the Qualcomm MSM8226 SoC.
Initially supported features:
- Buttons (Volume Down/Up, Power)
- eMMC
- Hall Effect Sensor
- SimpleFB display
- TMP108 temperature sensor
- Vibrator
Note: the dhob and shob reserved-memory regions are seemingly a part of some
Motorola specific (firmware?) mechanism, see [1].
[1] https://github.com/LineageOS/android_kernel_motorola_msm8226/blob/cm-14.1/Documentation/devicetree/bindings/misc/hob_ram.txt
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Signed-off-by: Stanislav Jakubek <stano.jakubek@gmail.com>
---
Changes in V3:
- collect Konrad's R-b
Changes in V2:
- split hob-ram reserved-memory region into dhob and shob
- add a note and a link to downstream documentation with more
information about these regions
arch/arm/boot/dts/qcom/Makefile | 1 +
.../boot/dts/qcom/msm8226-motorola-falcon.dts | 359 ++++++++++++++++++
2 files changed, 360 insertions(+)
create mode 100644 arch/arm/boot/dts/qcom/msm8226-motorola-falcon.dts
diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index 6478a39b3be5..3eacbf5c0785 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
dtb-$(CONFIG_ARCH_QCOM) += \
+ msm8226-motorola-falcon.dtb \
qcom-apq8016-sbc.dtb \
qcom-apq8026-asus-sparrow.dtb \
qcom-apq8026-huawei-sturgeon.dtb \
diff --git a/arch/arm/boot/dts/qcom/msm8226-motorola-falcon.dts b/arch/arm/boot/dts/qcom/msm8226-motorola-falcon.dts
new file mode 100644
index 000000000000..029e1b1659c9
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msm8226-motorola-falcon.dts
@@ -0,0 +1,359 @@
+// SPDX-License-Identifier: BSD-3-Clause
+
+/dts-v1/;
+
+#include "qcom-msm8226.dtsi"
+#include "pm8226.dtsi"
+
+/delete-node/ &smem_region;
+
+/ {
+ model = "Motorola Moto G (2013)";
+ compatible = "motorola,falcon", "qcom,msm8226";
+ chassis-type = "handset";
+
+ aliases {
+ mmc0 = &sdhc_1;
+ };
+
+ chosen {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@3200000 {
+ compatible = "simple-framebuffer";
+ reg = <0x03200000 0x800000>;
+ width = <720>;
+ height = <1280>;
+ stride = <(720 * 3)>;
+ format = "r8g8b8";
+ vsp-supply = <®_lcd_pos>;
+ vsn-supply = <®_lcd_neg>;
+ vddio-supply = <&vddio_disp_vreg>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ event-hall-sensor {
+ label = "Hall Effect Sensor";
+ gpios = <&tlmm 51 GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_LID>;
+ linux,can-disable;
+ };
+
+ key-volume-up {
+ label = "Volume Up";
+ gpios = <&tlmm 106 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ debounce-interval = <15>;
+ };
+ };
+
+ vddio_disp_vreg: regulator-vddio-disp {
+ compatible = "regulator-fixed";
+ regulator-name = "vddio_disp";
+ gpio = <&tlmm 34 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&pm8226_l8>;
+ startup-delay-us = <300>;
+ enable-active-high;
+ regulator-boot-on;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@3200000 {
+ reg = <0x03200000 0x800000>;
+ no-map;
+ };
+
+ dhob@f500000 {
+ reg = <0x0f500000 0x40000>;
+ no-map;
+ };
+
+ shob@f540000 {
+ reg = <0x0f540000 0x2000>;
+ no-map;
+ };
+
+ smem_region: smem@fa00000 {
+ reg = <0x0fa00000 0x100000>;
+ no-map;
+ };
+
+ /* Actually <0x0fa00000 0x500000>, but first 100000 is smem */
+ reserved@fb00000 {
+ reg = <0x0fb00000 0x400000>;
+ no-map;
+ };
+ };
+};
+
+&blsp1_i2c3 {
+ status = "okay";
+
+ regulator@3e {
+ compatible = "ti,tps65132";
+ reg = <0x3e>;
+ pinctrl-0 = <®_lcd_default>;
+ pinctrl-names = "default";
+
+ reg_lcd_pos: outp {
+ regulator-name = "outp";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+ regulator-active-discharge = <1>;
+ regulator-boot-on;
+ enable-gpios = <&tlmm 31 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_lcd_neg: outn {
+ regulator-name = "outn";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+ regulator-active-discharge = <1>;
+ regulator-boot-on;
+ enable-gpios = <&tlmm 33 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ temperature-sensor@48 {
+ compatible = "ti,tmp108";
+ reg = <0x48>;
+ interrupts-extended = <&tlmm 13 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-0 = <&temp_alert_default>;
+ pinctrl-names = "default";
+ #thermal-sensor-cells = <0>;
+ };
+};
+
+&pm8226_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
+&pm8226_vib {
+ status = "okay";
+};
+
+&rpm_requests {
+ regulators {
+ compatible = "qcom,rpm-pm8226-regulators";
+
+ pm8226_s3: s3 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ pm8226_s4: s4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2200000>;
+ };
+
+ pm8226_s5: s5 {
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+ };
+
+ pm8226_l1: l1 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pm8226_l2: l2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8226_l3: l3 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1337500>;
+ };
+
+ pm8226_l4: l4 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8226_l5: l5 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8226_l6: l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-allow-set-load;
+ };
+
+ pm8226_l7: l7 {
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <1850000>;
+ };
+
+ pm8226_l8: l8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8226_l9: l9 {
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pm8226_l10: l10 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8226_l12: l12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm8226_l14: l14 {
+ regulator-min-microvolt = <2750000>;
+ regulator-max-microvolt = <2750000>;
+ };
+
+ pm8226_l15: l15 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ pm8226_l16: l16 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3350000>;
+ };
+
+ pm8226_l17: l17 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_l18: l18 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_l19: l19 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ pm8226_l20: l20 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3075000>;
+ };
+
+ pm8226_l21: l21 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-allow-set-load;
+ };
+
+ pm8226_l22: l22 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_l23: l23 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ pm8226_l24: l24 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1350000>;
+ };
+
+ pm8226_l25: l25 {
+ regulator-min-microvolt = <1775000>;
+ regulator-max-microvolt = <2125000>;
+ };
+
+ pm8226_l26: l26 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ pm8226_l27: l27 {
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ pm8226_l28: l28 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ };
+
+ pm8226_lvs1: lvs1 {
+ regulator-always-on;
+ };
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm8226_l17>;
+ vqmmc-supply = <&pm8226_l6>;
+
+ bus-width = <8>;
+ non-removable;
+
+ status = "okay";
+};
+
+&smbb {
+ qcom,fast-charge-safe-current = <2000000>;
+ qcom,fast-charge-current-limit = <1900000>;
+ qcom,fast-charge-safe-voltage = <4400000>;
+ qcom,minimum-input-voltage = <4300000>;
+
+ status = "okay";
+};
+
+&tlmm {
+ reg_lcd_default: reg-lcd-default-state {
+ pins = "gpio31", "gpio33";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+
+ reg_vddio_disp_default: reg-vddio-disp-default-state {
+ pins = "gpio34";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+
+ temp_alert_default: temp-alert-default-state {
+ pins = "gpio13";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-disable;
+ };
+};
+
+&usb {
+ extcon = <&smbb>;
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usb_hs_phy {
+ extcon = <&smbb>;
+ v1p8-supply = <&pm8226_l10>;
+ v3p3-supply = <&pm8226_l20>;
+};
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v3 2/2] media: i2c: Add GC05A2 image sensor driver
From: Kieran Bingham @ 2024-04-07 9:08 UTC (permalink / raw)
To: Zhi Mao, krzysztof.kozlowski+dt, mchehab, robh+dt, sakari.ailus
Cc: laurent.pinchart, shengnan.wang, yaya.chang,
Project_Global_Chrome_Upstream_Group, yunkec, conor+dt,
matthias.bgg, angelogioacchino.delregno, jacopo.mondi, zhi.mao,
10572168, hverkuil-cisco, heiko, jernej.skrabec, macromorgan,
linus.walleij, hdegoede, tomi.valkeinen, gerald.loacker,
andy.shevchenko, bingbu.cao, dan.scally, linux-media, devicetree,
linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <20240403033825.9072-3-zhi.mao@mediatek.com>
Hello,
Thanks for helping extending the kernels sensor driver support.
My comments below can likely be taken with a pinch of salt, as they are
mostly around the tabled register values ... but we have many drivers
which are binary blobs of sensor register values and I think it would be
far more beneficial to clean these up where possible...
So the first question is ... Can we ?
Quoting Zhi Mao (2024-04-03 04:38:25)
> Add a V4L2 sub-device driver for Galaxycore GC05A2 image sensor.
>
> Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> ---
> drivers/media/i2c/Kconfig | 10 +
> drivers/media/i2c/Makefile | 1 +
> drivers/media/i2c/gc05a2.c | 1383 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 1394 insertions(+)
> create mode 100644 drivers/media/i2c/gc05a2.c
>
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 56f276b920ab..97993bf160f9 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -70,6 +70,16 @@ config VIDEO_GC0308
> To compile this driver as a module, choose M here: the
> module will be called gc0308.
>
> +config VIDEO_GC05A2
> + tristate "GalaxyCore gc05a2 sensor support"
> + select V4L2_CCI_I2C
> + help
> + This is a Video4Linux2 sensor driver for the GalaxyCore gc05a2
> + camera.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called gc05a2.
> +
> config VIDEO_GC2145
> select V4L2_CCI_I2C
> tristate "GalaxyCore GC2145 sensor support"
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index dfbe6448b549..8ed6faf0f854 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
> obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
> obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
> obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
> +obj-$(CONFIG_VIDEO_GC05A2) += gc05a2.o
> obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
> obj-$(CONFIG_VIDEO_HI556) += hi556.o
> obj-$(CONFIG_VIDEO_HI846) += hi846.o
> diff --git a/drivers/media/i2c/gc05a2.c b/drivers/media/i2c/gc05a2.c
> new file mode 100644
> index 000000000000..461d33055a3b
> --- /dev/null
> +++ b/drivers/media/i2c/gc05a2.c
> @@ -0,0 +1,1383 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for GalaxyCore gc05a2 image sensor
> + *
> + * Copyright 2024 MediaTek
> + *
> + * Zhi Mao <zhi.mao@mediatek.com>
> + */
> +#include <linux/array_size.h>
> +#include <linux/bits.h>
> +#include <linux/clk.h>
> +#include <linux/container_of.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/math64.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/property.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/types.h>
> +#include <linux/units.h>
> +
> +#include <media/v4l2-cci.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-event.h>
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-subdev.h>
> +
> +#define GC05A2_REG_TEST_PATTERN_EN CCI_REG8(0x008c)
> +#define GC05A2_REG_TEST_PATTERN_IDX CCI_REG8(0x008d)
> +#define GC05A2_TEST_PATTERN_EN 0x01
> +
> +#define GC05A2_STREAMING_REG CCI_REG8(0x0100)
> +
> +#define GC05A2_FLIP_REG CCI_REG8(0x0101)
> +#define GC05A2_FLIP_H_MASK BIT(0)
> +#define GC05A2_FLIP_V_MASK BIT(1)
> +
> +#define GC05A2_EXP_REG CCI_REG16(0x0202)
> +#define GC05A2_EXP_MARGIN 16
> +#define GC05A2_EXP_MIN 4
> +#define GC05A2_EXP_STEP 1
> +
> +#define GC05A2_AGAIN_REG CCI_REG16(0x0204)
> +#define GC05A2_AGAIN_MIN 1024
> +#define GC05A2_AGAIN_MAX (1024 * 16)
> +#define GC05A2_AGAIN_STEP 1
> +
> +#define GC05A2_FRAME_LENGTH_REG CCI_REG16(0x0340)
> +#define GC05A2_VTS_MAX 0xffff
> +
> +#define GC05A2_REG_CHIP_ID CCI_REG16(0x03f0)
> +#define GC05A2_CHIP_ID 0x05a2
> +
> +#define GC05A2_NATIVE_WIDTH 2592
> +#define GC05A2_NATIVE_HEIGHT 1944
> +
> +#define GC05A2_DEFAULT_CLK_FREQ (24 * HZ_PER_MHZ)
> +#define GC05A2_MBUS_CODE MEDIA_BUS_FMT_SGRBG10_1X10
> +#define GC05A2_DATA_LANES 2
> +#define GC05A2_RGB_DEPTH 10
> +#define GC05A2_SLEEP_US (2 * USEC_PER_MSEC)
> +
> +static const char *const gc05a2_test_pattern_menu[] = {
> + "No Pattern", "Fade_to_gray_Color Bar", "Color Bar",
> + "PN9", "Horizental_gradient", "Checkboard Pattern",
> + "Slant", "Resolution", "Solid Black",
> + "Solid White",
> +};
> +
> +static const s64 gc05a2_link_freq_menu_items[] = {
> + (448 * HZ_PER_MHZ),
> + (224 * HZ_PER_MHZ),
> +};
> +
> +static const char *const gc05a2_supply_name[] = {
> + "avdd",
> + "dvdd",
> + "dovdd",
> +};
> +
> +struct gc05a2 {
> + struct device *dev;
> + struct v4l2_subdev sd;
> + struct media_pad pad;
> +
> + struct clk *xclk;
> + struct regulator_bulk_data supplies[ARRAY_SIZE(gc05a2_supply_name)];
> + struct gpio_desc *reset_gpio;
> +
> + struct v4l2_ctrl_handler ctrls;
> + struct v4l2_ctrl *pixel_rate;
> + struct v4l2_ctrl *link_freq;
> + struct v4l2_ctrl *exposure;
> + struct v4l2_ctrl *vblank;
> + struct v4l2_ctrl *hblank;
> + struct v4l2_ctrl *hflip;
> + struct v4l2_ctrl *vflip;
> +
> + struct regmap *regmap;
> + unsigned long link_freq_bitmap;
> +
> + /* True if the device has been identified */
> + bool identified;
> + const struct gc05a2_mode *cur_mode;
> +};
> +
> +struct gc05a2_reg_list {
> + u32 num_of_regs;
> + const struct cci_reg_sequence *regs;
> +};
> +
> +static const struct cci_reg_sequence mode_2592x1944[] = {
> + /* system */
> + { CCI_REG8(0x0135), 0x01 },
> +
> + /* pre_setting */
> + { CCI_REG8(0x0084), 0x21 },
> + { CCI_REG8(0x0d05), 0xcc },
> + { CCI_REG8(0x0218), 0x00 },
> + { CCI_REG8(0x005e), 0x48 },
> + { CCI_REG8(0x0d06), 0x01 },
> + { CCI_REG8(0x0007), 0x16 },
> + { CCI_REG8(0x0101), 0x00 },
> +
> + /* analog */
> + { CCI_REG8(0x0342), 0x07 },
> + { CCI_REG8(0x0343), 0x28 },
> + { CCI_REG8(0x0220), 0x07 },
> + { CCI_REG8(0x0221), 0xd0 },
> + { CCI_REG8(0x0202), 0x07 },
> + { CCI_REG8(0x0203), 0x32 },
> + { CCI_REG8(0x0340), 0x07 },
> + { CCI_REG8(0x0341), 0xf0 },
> + { CCI_REG8(0x0219), 0x00 },
> + { CCI_REG8(0x0346), 0x00 },
> + { CCI_REG8(0x0347), 0x04 },
> + { CCI_REG8(0x0d14), 0x00 },
> + { CCI_REG8(0x0d13), 0x05 },
> + { CCI_REG8(0x0d16), 0x05 },
> + { CCI_REG8(0x0d15), 0x1d },
> + { CCI_REG8(0x00c0), 0x0a },
> + { CCI_REG8(0x00c1), 0x30 },
> + { CCI_REG8(0x034a), 0x07 },
> + { CCI_REG8(0x034b), 0xa8 },
> + { CCI_REG8(0x0e0a), 0x00 },
> + { CCI_REG8(0x0e0b), 0x00 },
> + { CCI_REG8(0x0e0e), 0x03 },
> + { CCI_REG8(0x0e0f), 0x00 },
> + { CCI_REG8(0x0e06), 0x0a },
> + { CCI_REG8(0x0e23), 0x15 },
> + { CCI_REG8(0x0e24), 0x15 },
> + { CCI_REG8(0x0e2a), 0x10 },
> + { CCI_REG8(0x0e2b), 0x10 },
> + { CCI_REG8(0x0e17), 0x49 },
> + { CCI_REG8(0x0e1b), 0x1c },
> + { CCI_REG8(0x0e3a), 0x36 },
> + { CCI_REG8(0x0d11), 0x84 },
> + { CCI_REG8(0x0e52), 0x14 },
> + { CCI_REG8(0x000b), 0x10 },
> + { CCI_REG8(0x0008), 0x08 },
> + { CCI_REG8(0x0223), 0x17 },
> + { CCI_REG8(0x0d27), 0x39 },
> + { CCI_REG8(0x0d22), 0x00 },
> + { CCI_REG8(0x03f6), 0x0d },
> + { CCI_REG8(0x0d04), 0x07 },
> + { CCI_REG8(0x03f3), 0x72 },
> + { CCI_REG8(0x03f4), 0xb8 },
> + { CCI_REG8(0x03f5), 0xbc },
> + { CCI_REG8(0x0d02), 0x73 },
> +
> + /* auto load start */
> + { CCI_REG8(0x00cb), 0x00 },
> +
> + /* OUT 2592*1944 */
> + { CCI_REG8(0x0350), 0x01 },
> + { CCI_REG8(0x0353), 0x00 },
> + { CCI_REG8(0x0354), 0x08 },
> + { CCI_REG8(0x034c), 0x0a },
> + { CCI_REG8(0x034d), 0x20 },
Should/Could this be
{ CCI_REG16(0x034c), 2592 }, /* Width */
> + { CCI_REG8(0x021f), 0x14 },
> +
> + /* MIPI */
> + { CCI_REG8(0x0107), 0x05 },
> + { CCI_REG8(0x0117), 0x01 },
> + { CCI_REG8(0x0d81), 0x00 },
> + { CCI_REG8(0x0d84), 0x0c },
> + { CCI_REG8(0x0d85), 0xa8 },
> + { CCI_REG8(0x0d86), 0x06 },
> + { CCI_REG8(0x0d87), 0x55 },
> + { CCI_REG8(0x0db3), 0x06 },
> + { CCI_REG8(0x0db4), 0x08 },
> + { CCI_REG8(0x0db5), 0x1e },
> + { CCI_REG8(0x0db6), 0x02 },
> + { CCI_REG8(0x0db8), 0x12 },
> + { CCI_REG8(0x0db9), 0x0a },
> + { CCI_REG8(0x0d93), 0x06 },
> + { CCI_REG8(0x0d94), 0x09 },
> + { CCI_REG8(0x0d95), 0x0d },
> + { CCI_REG8(0x0d99), 0x0b },
> + { CCI_REG8(0x0084), 0x01 },
> +
> + /* OUT */
> + { CCI_REG8(0x0110), 0x01 },
> +};
> +
> +static const struct cci_reg_sequence mode_1280x720[] = {
> + /* system */
> + { CCI_REG8(0x0135), 0x05 },
In 2592x1944 this is 0x01. Do you have a datasheet? Can you explain why
they are different? Can you add register definitions that have names to
make this more maintainable or extendable in the future?
There's discussion in the recent series improving the IMX258 which makes
me wonder if we should try harder to have sensor drivers with clearer
definitions.
> +
> + /*pre_setting*/
/* pre_setting */ ?
> + { CCI_REG8(0x0084), 0x21 },
> + { CCI_REG8(0x0d05), 0xcc },
> + { CCI_REG8(0x0218), 0x80 },
> + { CCI_REG8(0x005e), 0x49 },
> + { CCI_REG8(0x0d06), 0x81 },
> + { CCI_REG8(0x0007), 0x16 },
> + { CCI_REG8(0x0101), 0x00 },
In 2592x1944, only register 0x0218 differs. Why? What is that? Can it be
broken out to a function that applies the correct configuration at
startuup based on a parameter instead of duplicating this table set?
> +
> + /* analog */
> + { CCI_REG8(0x0342), 0x07 },
> + { CCI_REG8(0x0343), 0x10 },
> + { CCI_REG8(0x0220), 0x07 },
> + { CCI_REG8(0x0221), 0xd0 },
> + { CCI_REG8(0x0202), 0x03 },
> + { CCI_REG8(0x0203), 0x32 },
> + { CCI_REG8(0x0340), 0x04 },
> + { CCI_REG8(0x0341), 0x08 },
> + { CCI_REG8(0x0219), 0x00 },
> + { CCI_REG8(0x0346), 0x01 },
> + { CCI_REG8(0x0347), 0x00 },
> + { CCI_REG8(0x0d14), 0x00 },
> + { CCI_REG8(0x0d13), 0x05 },
> + { CCI_REG8(0x0d16), 0x05 },
> + { CCI_REG8(0x0d15), 0x1d },
> + { CCI_REG8(0x00c0), 0x0a },
> + { CCI_REG8(0x00c1), 0x30 },
> + { CCI_REG8(0x034a), 0x05 },
> + { CCI_REG8(0x034b), 0xb0 },
> + { CCI_REG8(0x0e0a), 0x00 },
> + { CCI_REG8(0x0e0b), 0x00 },
> + { CCI_REG8(0x0e0e), 0x03 },
> + { CCI_REG8(0x0e0f), 0x00 },
> + { CCI_REG8(0x0e06), 0x0a },
> + { CCI_REG8(0x0e23), 0x15 },
> + { CCI_REG8(0x0e24), 0x15 },
> + { CCI_REG8(0x0e2a), 0x10 },
> + { CCI_REG8(0x0e2b), 0x10 },
> + { CCI_REG8(0x0e17), 0x49 },
> + { CCI_REG8(0x0e1b), 0x1c },
> + { CCI_REG8(0x0e3a), 0x36 },
> + { CCI_REG8(0x0d11), 0x84 },
> + { CCI_REG8(0x0e52), 0x14 },
> + { CCI_REG8(0x000b), 0x0e },
> + { CCI_REG8(0x0008), 0x03 },
> + { CCI_REG8(0x0223), 0x16 },
> + { CCI_REG8(0x0d27), 0x39 },
> + { CCI_REG8(0x0d22), 0x00 },
> + { CCI_REG8(0x03f6), 0x0d },
> + { CCI_REG8(0x0d04), 0x07 },
> + { CCI_REG8(0x03f3), 0x72 },
> + { CCI_REG8(0x03f4), 0xb8 },
> + { CCI_REG8(0x03f5), 0xbc },
> + { CCI_REG8(0x0d02), 0x73 },
> +
Are any of those able to be broken out to named register to be more
clear in their intent?
> + /* auto load start */
> + { CCI_REG8(0x00cb), 0xfc },
> +
Why is this auto load start so different to the other modes 'auto load
start'? What do the bits refer to ?
> + /* OUT 1280x720 */
> + { CCI_REG8(0x0350), 0x01 },
> + { CCI_REG8(0x0353), 0x00 },
> + { CCI_REG8(0x0354), 0x0c },
> + { CCI_REG8(0x034c), 0x05 },
> + { CCI_REG8(0x034d), 0x00 },
Should/Could this be
{ CCI_REG16(0x034c), 1280 },
Are there any other register settings that would make more sense to be
in decimal units that match their actual context?
> + { CCI_REG8(0x021f), 0x14 },
I don't see a setting for 720/0x2d0. Do these registers only set the
width?
> +
> + /* MIPI */
> + { CCI_REG8(0x0107), 0x05 },
> + { CCI_REG8(0x0117), 0x01 },
> + { CCI_REG8(0x0d81), 0x00 },
> + { CCI_REG8(0x0d84), 0x06 },
> + { CCI_REG8(0x0d85), 0x40 },
> + { CCI_REG8(0x0d86), 0x03 },
> + { CCI_REG8(0x0d87), 0x21 },
> + { CCI_REG8(0x0db3), 0x03 },
> + { CCI_REG8(0x0db4), 0x04 },
> + { CCI_REG8(0x0db5), 0x0d },
> + { CCI_REG8(0x0db6), 0x01 },
> + { CCI_REG8(0x0db8), 0x04 },
> + { CCI_REG8(0x0db9), 0x06 },
> + { CCI_REG8(0x0d93), 0x03 },
> + { CCI_REG8(0x0d94), 0x04 },
> + { CCI_REG8(0x0d95), 0x05 },
> + { CCI_REG8(0x0d99), 0x06 },
> + { CCI_REG8(0x0084), 0x01 },
> +
> + /* OUT */
Out where? What is out?
> + { CCI_REG8(0x0110), 0x01 },
> +};
> +
> +static const struct cci_reg_sequence mode_table_common[] = {
> + { GC05A2_STREAMING_REG, 0x00 },
> + /* system */
> + { CCI_REG8(0x0315), 0xd4 },
> + { CCI_REG8(0x0d06), 0x01 },
> + { CCI_REG8(0x0a70), 0x80 },
> + { CCI_REG8(0x031a), 0x00 },
> + { CCI_REG8(0x0314), 0x00 },
> + { CCI_REG8(0x0130), 0x08 },
> + { CCI_REG8(0x0132), 0x01 },
> + { CCI_REG8(0x0136), 0x38 },
> + { CCI_REG8(0x0137), 0x03 },
> + { CCI_REG8(0x0134), 0x5b },
> + { CCI_REG8(0x031c), 0xe0 },
> + { CCI_REG8(0x0d82), 0x14 },
> + { CCI_REG8(0x0dd1), 0x56 },
> +
> + /* gate_mode */
> + { CCI_REG8(0x0af4), 0x01 },
> + { CCI_REG8(0x0002), 0x10 },
> + { CCI_REG8(0x00c3), 0x34 },
> +
> + /* auto load start */
The previous 'auto load start' referenced 0x00cb ?
> + { CCI_REG8(0x00c4), 0x00 },
> + { CCI_REG8(0x00c5), 0x01 },
> + { CCI_REG8(0x0af6), 0x00 },
> + { CCI_REG8(0x0ba0), 0x17 },
> + { CCI_REG8(0x0ba1), 0x00 },
> + { CCI_REG8(0x0ba2), 0x00 },
> + { CCI_REG8(0x0ba3), 0x00 },
> + { CCI_REG8(0x0ba4), 0x03 },
> + { CCI_REG8(0x0ba5), 0x00 },
> + { CCI_REG8(0x0ba6), 0x00 },
> + { CCI_REG8(0x0ba7), 0x00 },
> + { CCI_REG8(0x0ba8), 0x40 },
> + { CCI_REG8(0x0ba9), 0x00 },
> + { CCI_REG8(0x0baa), 0x00 },
> + { CCI_REG8(0x0bab), 0x00 },
> + { CCI_REG8(0x0bac), 0x40 },
> + { CCI_REG8(0x0bad), 0x00 },
> + { CCI_REG8(0x0bae), 0x00 },
> + { CCI_REG8(0x0baf), 0x00 },
> + { CCI_REG8(0x0bb0), 0x02 },
> + { CCI_REG8(0x0bb1), 0x00 },
> + { CCI_REG8(0x0bb2), 0x00 },
> + { CCI_REG8(0x0bb3), 0x00 },
> + { CCI_REG8(0x0bb8), 0x02 },
> + { CCI_REG8(0x0bb9), 0x00 },
> + { CCI_REG8(0x0bba), 0x00 },
> + { CCI_REG8(0x0bbb), 0x00 },
> + { CCI_REG8(0x0a70), 0x80 },
> + { CCI_REG8(0x0a71), 0x00 },
> + { CCI_REG8(0x0a72), 0x00 },
> + { CCI_REG8(0x0a66), 0x00 },
> + { CCI_REG8(0x0a67), 0x80 },
> + { CCI_REG8(0x0a4d), 0x4e },
> + { CCI_REG8(0x0a50), 0x00 },
> + { CCI_REG8(0x0a4f), 0x0c },
> + { CCI_REG8(0x0a66), 0x00 },
> + { CCI_REG8(0x00ca), 0x00 },
> + { CCI_REG8(0x00cc), 0x00 },
> + { CCI_REG8(0x00cd), 0x00 },
> + { CCI_REG8(0x0aa1), 0x00 },
> + { CCI_REG8(0x0aa2), 0xe0 },
> + { CCI_REG8(0x0aa3), 0x00 },
> + { CCI_REG8(0x0aa4), 0x40 },
> + { CCI_REG8(0x0a90), 0x03 },
> + { CCI_REG8(0x0a91), 0x0e },
> + { CCI_REG8(0x0a94), 0x80 },
> +
> + /* standby */
> + { CCI_REG8(0x0af6), 0x20 },
> + { CCI_REG8(0x0b00), 0x91 },
> + { CCI_REG8(0x0b01), 0x17 },
> + { CCI_REG8(0x0b02), 0x01 },
> + { CCI_REG8(0x0b03), 0x00 },
> + { CCI_REG8(0x0b04), 0x01 },
> + { CCI_REG8(0x0b05), 0x17 },
> + { CCI_REG8(0x0b06), 0x01 },
> + { CCI_REG8(0x0b07), 0x00 },
> + { CCI_REG8(0x0ae9), 0x01 },
> + { CCI_REG8(0x0aea), 0x02 },
> + { CCI_REG8(0x0ae8), 0x53 },
> + { CCI_REG8(0x0ae8), 0x43 },
> +
> + /* gain_partition */
> + { CCI_REG8(0x0af6), 0x30 },
> + { CCI_REG8(0x0b00), 0x08 },
> + { CCI_REG8(0x0b01), 0x0f },
> + { CCI_REG8(0x0b02), 0x00 },
> + { CCI_REG8(0x0b04), 0x1c },
> + { CCI_REG8(0x0b05), 0x24 },
> + { CCI_REG8(0x0b06), 0x00 },
> + { CCI_REG8(0x0b08), 0x30 },
> + { CCI_REG8(0x0b09), 0x40 },
> + { CCI_REG8(0x0b0a), 0x00 },
> + { CCI_REG8(0x0b0c), 0x0e },
> + { CCI_REG8(0x0b0d), 0x2a },
> + { CCI_REG8(0x0b0e), 0x00 },
> + { CCI_REG8(0x0b10), 0x0e },
> + { CCI_REG8(0x0b11), 0x2b },
> + { CCI_REG8(0x0b12), 0x00 },
> + { CCI_REG8(0x0b14), 0x0e },
> + { CCI_REG8(0x0b15), 0x23 },
> + { CCI_REG8(0x0b16), 0x00 },
> + { CCI_REG8(0x0b18), 0x0e },
> + { CCI_REG8(0x0b19), 0x24 },
> + { CCI_REG8(0x0b1a), 0x00 },
> + { CCI_REG8(0x0b1c), 0x0c },
> + { CCI_REG8(0x0b1d), 0x0c },
> + { CCI_REG8(0x0b1e), 0x00 },
> + { CCI_REG8(0x0b20), 0x03 },
> + { CCI_REG8(0x0b21), 0x03 },
> + { CCI_REG8(0x0b22), 0x00 },
> + { CCI_REG8(0x0b24), 0x0e },
> + { CCI_REG8(0x0b25), 0x0e },
> + { CCI_REG8(0x0b26), 0x00 },
> + { CCI_REG8(0x0b28), 0x03 },
> + { CCI_REG8(0x0b29), 0x03 },
> + { CCI_REG8(0x0b2a), 0x00 },
> + { CCI_REG8(0x0b2c), 0x12 },
> + { CCI_REG8(0x0b2d), 0x12 },
> + { CCI_REG8(0x0b2e), 0x00 },
> + { CCI_REG8(0x0b30), 0x08 },
> + { CCI_REG8(0x0b31), 0x08 },
> + { CCI_REG8(0x0b32), 0x00 },
> + { CCI_REG8(0x0b34), 0x14 },
> + { CCI_REG8(0x0b35), 0x14 },
> + { CCI_REG8(0x0b36), 0x00 },
> + { CCI_REG8(0x0b38), 0x10 },
> + { CCI_REG8(0x0b39), 0x10 },
> + { CCI_REG8(0x0b3a), 0x00 },
> + { CCI_REG8(0x0b3c), 0x16 },
> + { CCI_REG8(0x0b3d), 0x16 },
> + { CCI_REG8(0x0b3e), 0x00 },
> + { CCI_REG8(0x0b40), 0x10 },
> + { CCI_REG8(0x0b41), 0x10 },
> + { CCI_REG8(0x0b42), 0x00 },
> + { CCI_REG8(0x0b44), 0x19 },
> + { CCI_REG8(0x0b45), 0x19 },
> + { CCI_REG8(0x0b46), 0x00 },
> + { CCI_REG8(0x0b48), 0x16 },
> + { CCI_REG8(0x0b49), 0x16 },
> + { CCI_REG8(0x0b4a), 0x00 },
> + { CCI_REG8(0x0b4c), 0x19 },
> + { CCI_REG8(0x0b4d), 0x19 },
> + { CCI_REG8(0x0b4e), 0x00 },
> + { CCI_REG8(0x0b50), 0x16 },
> + { CCI_REG8(0x0b51), 0x16 },
> + { CCI_REG8(0x0b52), 0x00 },
> + { CCI_REG8(0x0b80), 0x01 },
> + { CCI_REG8(0x0b81), 0x00 },
> + { CCI_REG8(0x0b82), 0x00 },
> + { CCI_REG8(0x0b84), 0x00 },
> + { CCI_REG8(0x0b85), 0x00 },
> + { CCI_REG8(0x0b86), 0x00 },
> + { CCI_REG8(0x0b88), 0x01 },
> + { CCI_REG8(0x0b89), 0x6a },
> + { CCI_REG8(0x0b8a), 0x00 },
> + { CCI_REG8(0x0b8c), 0x00 },
> + { CCI_REG8(0x0b8d), 0x01 },
> + { CCI_REG8(0x0b8e), 0x00 },
> + { CCI_REG8(0x0b90), 0x01 },
> + { CCI_REG8(0x0b91), 0xf6 },
> + { CCI_REG8(0x0b92), 0x00 },
> + { CCI_REG8(0x0b94), 0x00 },
> + { CCI_REG8(0x0b95), 0x02 },
> + { CCI_REG8(0x0b96), 0x00 },
> + { CCI_REG8(0x0b98), 0x02 },
> + { CCI_REG8(0x0b99), 0xc4 },
> + { CCI_REG8(0x0b9a), 0x00 },
> + { CCI_REG8(0x0b9c), 0x00 },
> + { CCI_REG8(0x0b9d), 0x03 },
> + { CCI_REG8(0x0b9e), 0x00 },
> + { CCI_REG8(0x0ba0), 0x03 },
> + { CCI_REG8(0x0ba1), 0xd8 },
> + { CCI_REG8(0x0ba2), 0x00 },
> + { CCI_REG8(0x0ba4), 0x00 },
> + { CCI_REG8(0x0ba5), 0x04 },
> + { CCI_REG8(0x0ba6), 0x00 },
> + { CCI_REG8(0x0ba8), 0x05 },
> + { CCI_REG8(0x0ba9), 0x4d },
> + { CCI_REG8(0x0baa), 0x00 },
> + { CCI_REG8(0x0bac), 0x00 },
> + { CCI_REG8(0x0bad), 0x05 },
> + { CCI_REG8(0x0bae), 0x00 },
> + { CCI_REG8(0x0bb0), 0x07 },
> + { CCI_REG8(0x0bb1), 0x3e },
> + { CCI_REG8(0x0bb2), 0x00 },
> + { CCI_REG8(0x0bb4), 0x00 },
> + { CCI_REG8(0x0bb5), 0x06 },
> + { CCI_REG8(0x0bb6), 0x00 },
> + { CCI_REG8(0x0bb8), 0x0a },
> + { CCI_REG8(0x0bb9), 0x1a },
> + { CCI_REG8(0x0bba), 0x00 },
> + { CCI_REG8(0x0bbc), 0x09 },
> + { CCI_REG8(0x0bbd), 0x36 },
> + { CCI_REG8(0x0bbe), 0x00 },
> + { CCI_REG8(0x0bc0), 0x0e },
> + { CCI_REG8(0x0bc1), 0x66 },
> + { CCI_REG8(0x0bc2), 0x00 },
> + { CCI_REG8(0x0bc4), 0x10 },
> + { CCI_REG8(0x0bc5), 0x06 },
> + { CCI_REG8(0x0bc6), 0x00 },
> + { CCI_REG8(0x02c1), 0xe0 },
> + { CCI_REG8(0x0207), 0x04 },
> + { CCI_REG8(0x02c2), 0x10 },
> + { CCI_REG8(0x02c3), 0x74 },
> + { CCI_REG8(0x02c5), 0x09 },
> + { CCI_REG8(0x02c1), 0xe0 },
> + { CCI_REG8(0x0207), 0x04 },
> + { CCI_REG8(0x02c2), 0x10 },
> + { CCI_REG8(0x02c5), 0x09 },
> + { CCI_REG8(0x02c1), 0xe0 },
> + { CCI_REG8(0x0207), 0x04 },
> + { CCI_REG8(0x02c2), 0x10 },
> + { CCI_REG8(0x02c5), 0x09 },
> +
> + /* auto load CH_GAIN */
> + { CCI_REG8(0x0aa1), 0x15 },
> + { CCI_REG8(0x0aa2), 0x50 },
> + { CCI_REG8(0x0aa3), 0x00 },
> + { CCI_REG8(0x0aa4), 0x09 },
> + { CCI_REG8(0x0a90), 0x25 },
> + { CCI_REG8(0x0a91), 0x0e },
> + { CCI_REG8(0x0a94), 0x80 },
> +
> + /* ISP */
> + { CCI_REG8(0x0050), 0x00 },
> + { CCI_REG8(0x0089), 0x83 },
> + { CCI_REG8(0x005a), 0x40 },
> + { CCI_REG8(0x00c3), 0x35 },
> + { CCI_REG8(0x00c4), 0x80 },
> + { CCI_REG8(0x0080), 0x10 },
> + { CCI_REG8(0x0040), 0x12 },
> + { CCI_REG8(0x0053), 0x0a },
> + { CCI_REG8(0x0054), 0x44 },
> + { CCI_REG8(0x0055), 0x32 },
> + { CCI_REG8(0x0058), 0x89 },
> + { CCI_REG8(0x004a), 0x03 },
> + { CCI_REG8(0x0048), 0xf0 },
> + { CCI_REG8(0x0049), 0x0f },
> + { CCI_REG8(0x0041), 0x20 },
> + { CCI_REG8(0x0043), 0x0a },
> + { CCI_REG8(0x009d), 0x08 },
> + { CCI_REG8(0x0236), 0x40 },
> +
> + /* gain */
Is the gain configurable? Is this analogue gain? digital gain? or colour
balanace gains ?
> + { CCI_REG8(0x0204), 0x04 },
> + { CCI_REG8(0x0205), 0x00 },
> + { CCI_REG8(0x02b3), 0x00 },
> + { CCI_REG8(0x02b4), 0x00 },
> + { CCI_REG8(0x009e), 0x01 },
> + { CCI_REG8(0x009f), 0x94 },
> +
> + /* auto load REG */
> + { CCI_REG8(0x0aa1), 0x10 },
> + { CCI_REG8(0x0aa2), 0xf8 },
> + { CCI_REG8(0x0aa3), 0x00 },
> + { CCI_REG8(0x0aa4), 0x1f },
> + { CCI_REG8(0x0a90), 0x11 },
> + { CCI_REG8(0x0a91), 0x0e },
> + { CCI_REG8(0x0a94), 0x80 },
> + { CCI_REG8(0x03fe), 0x00 },
> + { CCI_REG8(0x0a90), 0x00 },
> + { CCI_REG8(0x0a70), 0x00 },
> + { CCI_REG8(0x0a67), 0x00 },
> + { CCI_REG8(0x0af4), 0x29 },
> +
> + /* DPHY */
> + { CCI_REG8(0x0d80), 0x07 },
> + { CCI_REG8(0x0dd3), 0x18 },
> +
> + /* CISCTL_Reset */
> + { CCI_REG8(0x031c), 0x80 },
> + { CCI_REG8(0x03fe), 0x30 },
> + { CCI_REG8(0x0d17), 0x06 },
> + { CCI_REG8(0x03fe), 0x00 },
> + { CCI_REG8(0x0d17), 0x00 },
> + { CCI_REG8(0x031c), 0x93 },
> + { CCI_REG8(0x03fe), 0x00 },
> + { CCI_REG8(0x031c), 0x80 },
> + { CCI_REG8(0x03fe), 0x30 },
> + { CCI_REG8(0x0d17), 0x06 },
> + { CCI_REG8(0x03fe), 0x00 },
> + { CCI_REG8(0x0d17), 0x00 },
> + { CCI_REG8(0x031c), 0x93 },
> +};
> +
> +struct gc05a2_mode {
> + u32 width;
> + u32 height;
> + const struct gc05a2_reg_list reg_list;
> +
> + u32 hts; /* Horizontal timining size */
> + u32 vts_def; /* Default vertical timining size */
> + u32 vts_min; /* Min vertical timining size */
> +};
> +
> +/* Declare modes in order, from biggest to smallest height. */
> +static const struct gc05a2_mode gc05a2_modes[] = {
> + {
> + /* 2592*1944@30fps */
> + .width = GC05A2_NATIVE_WIDTH,
> + .height = GC05A2_NATIVE_HEIGHT,
> + .reg_list = {
> + .num_of_regs = ARRAY_SIZE(mode_2592x1944),
> + .regs = mode_2592x1944,
> + },
> + .hts = 3664,
> + .vts_def = 2032,
> + .vts_min = 2032,
> + },
> + {
> + /* 1280*720@60fps */
> + .width = 1280,
> + .height = 720,
> + .reg_list = {
> + .num_of_regs = ARRAY_SIZE(mode_1280x720),
> + .regs = mode_1280x720,
> + },
> + .hts = 3616,
> + .vts_def = 1032,
> + .vts_min = 1032,
> + },
> +};
> +
> +static inline struct gc05a2 *to_gc05a2(struct v4l2_subdev *sd)
> +{
> + return container_of(sd, struct gc05a2, sd);
> +}
> +
> +static int gc05a2_power_on(struct device *dev)
> +{
> + struct v4l2_subdev *sd = dev_get_drvdata(dev);
> + struct gc05a2 *gc05a2 = to_gc05a2(sd);
> + int ret;
> +
> + ret = regulator_bulk_enable(ARRAY_SIZE(gc05a2_supply_name),
> + gc05a2->supplies);
> + if (ret < 0) {
> + dev_err(gc05a2->dev, "failed to enable regulators: %d\n", ret);
> + return ret;
> + }
> +
> + ret = clk_prepare_enable(gc05a2->xclk);
> + if (ret < 0) {
> + regulator_bulk_disable(ARRAY_SIZE(gc05a2_supply_name),
> + gc05a2->supplies);
> + dev_err(gc05a2->dev, "clk prepare enable failed\n");
> + return ret;
> + }
> +
> + fsleep(GC05A2_SLEEP_US);
> +
> + gpiod_set_value_cansleep(gc05a2->reset_gpio, 0);
> + fsleep(GC05A2_SLEEP_US);
> +
> + return 0;
> +}
> +
> +static int gc05a2_power_off(struct device *dev)
> +{
> + struct v4l2_subdev *sd = dev_get_drvdata(dev);
> + struct gc05a2 *gc05a2 = to_gc05a2(sd);
> +
> + clk_disable_unprepare(gc05a2->xclk);
> + gpiod_set_value_cansleep(gc05a2->reset_gpio, 1);
> + regulator_bulk_disable(ARRAY_SIZE(gc05a2_supply_name),
> + gc05a2->supplies);
> +
> + return 0;
> +}
> +
> +static int gc05a2_enum_mbus_code(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *sd_state,
> + struct v4l2_subdev_mbus_code_enum *code)
> +{
> + if (code->index > 0)
> + return -EINVAL;
> +
> + code->code = GC05A2_MBUS_CODE;
> +
> + return 0;
> +}
> +
> +static int gc05a2_enum_frame_size(struct v4l2_subdev *subdev,
> + struct v4l2_subdev_state *sd_state,
> + struct v4l2_subdev_frame_size_enum *fse)
> +{
> + if (fse->code != GC05A2_MBUS_CODE)
> + return -EINVAL;
> +
> + if (fse->index >= ARRAY_SIZE(gc05a2_modes))
> + return -EINVAL;
> +
> + fse->min_width = gc05a2_modes[fse->index].width;
> + fse->max_width = gc05a2_modes[fse->index].width;
> + fse->min_height = gc05a2_modes[fse->index].height;
> + fse->max_height = gc05a2_modes[fse->index].height;
> +
> + return 0;
> +}
> +
> +static int gc05a2_update_cur_mode_controls(struct gc05a2 *gc05a2,
> + const struct gc05a2_mode *mode)
> +{
> + s64 exposure_max, h_blank;
> + int ret;
> +
> + ret = __v4l2_ctrl_modify_range(gc05a2->vblank,
> + mode->vts_min - mode->height,
> + GC05A2_VTS_MAX - mode->height, 1,
> + mode->vts_def - mode->height);
> + if (ret) {
> + dev_err(gc05a2->dev, "VB ctrl range update failed\n");
> + return ret;
> + }
> +
> + h_blank = mode->hts - mode->width;
> + ret = __v4l2_ctrl_modify_range(gc05a2->hblank, h_blank, h_blank, 1,
> + h_blank);
> + if (ret) {
> + dev_err(gc05a2->dev, "HB ctrl range update failed\n");
> + return ret;
> + }
> +
> + exposure_max = mode->vts_def - GC05A2_EXP_MARGIN;
> + ret = __v4l2_ctrl_modify_range(gc05a2->exposure, GC05A2_EXP_MIN,
> + exposure_max, GC05A2_EXP_STEP,
> + exposure_max);
> + if (ret) {
> + dev_err(gc05a2->dev, "exposure ctrl range update failed\n");
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static void gc05a2_update_pad_format(struct gc05a2 *gc08a3,
> + const struct gc05a2_mode *mode,
> + struct v4l2_mbus_framefmt *fmt)
> +{
> + fmt->width = mode->width;
> + fmt->height = mode->height;
> + fmt->code = GC05A2_MBUS_CODE;
> + fmt->field = V4L2_FIELD_NONE;
> + fmt->colorspace = V4L2_COLORSPACE_RAW;
> + fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
> + fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
> + fmt->xfer_func = V4L2_XFER_FUNC_NONE;
> +}
> +
> +static int gc05a2_set_format(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state,
> + struct v4l2_subdev_format *fmt)
> +{
> + struct gc05a2 *gc05a2 = to_gc05a2(sd);
> + struct v4l2_mbus_framefmt *mbus_fmt;
> + struct v4l2_rect *crop;
> + const struct gc05a2_mode *mode;
> +
> + mode = v4l2_find_nearest_size(gc05a2_modes, ARRAY_SIZE(gc05a2_modes),
> + width, height, fmt->format.width,
> + fmt->format.height);
> +
> + /* update crop info to subdev state */
> + crop = v4l2_subdev_state_get_crop(state, 0);
> + crop->width = mode->width;
> + crop->height = mode->height;
> +
> + /* update fmt info to subdev state */
> + gc05a2_update_pad_format(gc05a2, mode, &fmt->format);
> + mbus_fmt = v4l2_subdev_state_get_format(state, 0);
> + *mbus_fmt = fmt->format;
> +
> + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
> + return 0;
> + gc05a2->cur_mode = mode;
> + gc05a2_update_cur_mode_controls(gc05a2, mode);
> +
> + return 0;
> +}
> +
> +static int gc05a2_get_selection(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state,
> + struct v4l2_subdev_selection *sel)
> +{
> + switch (sel->target) {
> + case V4L2_SEL_TGT_CROP_DEFAULT:
> + case V4L2_SEL_TGT_CROP:
> + sel->r = *v4l2_subdev_state_get_crop(state, 0);
> + break;
> + case V4L2_SEL_TGT_CROP_BOUNDS:
> + sel->r.top = 0;
> + sel->r.left = 0;
> + sel->r.width = GC05A2_NATIVE_WIDTH;
> + sel->r.height = GC05A2_NATIVE_HEIGHT;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static int gc05a2_init_state(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state)
> +{
> + struct v4l2_subdev_format fmt = {
> + .which = V4L2_SUBDEV_FORMAT_TRY,
> + .pad = 0,
> + .format = {
> + .code = GC05A2_MBUS_CODE,
> + .width = gc05a2_modes[0].width,
> + .height = gc05a2_modes[0].height,
> + },
> + };
> +
> + gc05a2_set_format(sd, state, &fmt);
> +
> + return 0;
> +}
> +
> +static int gc05a2_set_ctrl_hflip(struct gc05a2 *gc05a2, u32 ctrl_val)
> +{
> + int ret;
> + u64 val;
> +
> + ret = cci_read(gc05a2->regmap, GC05A2_FLIP_REG, &val, NULL);
> + if (ret) {
> + dev_err(gc05a2->dev, "read hflip register failed: %d\n", ret);
> + return ret;
> + }
> +
> + return cci_update_bits(gc05a2->regmap, GC05A2_FLIP_REG,
> + GC05A2_FLIP_H_MASK,
> + ctrl_val ? GC05A2_FLIP_H_MASK : 0, NULL);
> +}
> +
> +static int gc05a2_set_ctrl_vflip(struct gc05a2 *gc05a2, u32 ctrl_val)
> +{
> + int ret;
> + u64 val;
> +
> + ret = cci_read(gc05a2->regmap, GC05A2_FLIP_REG, &val, NULL);
> + if (ret) {
> + dev_err(gc05a2->dev, "read vflip register failed: %d\n", ret);
> + return ret;
> + }
> +
> + return cci_update_bits(gc05a2->regmap, GC05A2_FLIP_REG,
> + GC05A2_FLIP_V_MASK,
> + ctrl_val ? GC05A2_FLIP_V_MASK : 0, NULL);
> +}
> +
> +static int gc05a2_test_pattern(struct gc05a2 *gc05a2, u32 pattern_menu)
> +{
> + u32 pattern;
> + int ret;
> +
> + if (pattern_menu) {
> + switch (pattern_menu) {
> + case 1:
> + case 2:
> + case 3:
> + case 4:
> + case 5:
> + case 6:
> + case 7:
> + pattern = pattern_menu << 4;
> + break;
> +
> + case 8:
> + pattern = 0;
> + break;
> +
> + case 9:
> + pattern = 4;
> + break;
> +
> + default:
> + pattern = 0x00;
> + break;
> + }
This is fairly terse. Can we add comments, or definitions for the types
or such so that the above is easier to interpret?
> +
> + ret = cci_write(gc05a2->regmap, GC05A2_REG_TEST_PATTERN_IDX,
> + pattern, NULL);
> + if (ret)
> + return ret;
> +
> + return cci_write(gc05a2->regmap, GC05A2_REG_TEST_PATTERN_EN,
> + GC05A2_TEST_PATTERN_EN, NULL);
> + } else {
> + return cci_write(gc05a2->regmap, GC05A2_REG_TEST_PATTERN_EN,
> + 0x00, NULL);
> + }
> +}
> +
> +static int gc05a2_set_ctrl(struct v4l2_ctrl *ctrl)
> +{
> + struct gc05a2 *gc05a2 =
> + container_of(ctrl->handler, struct gc05a2, ctrls);
> + int ret = 0;
> + s64 exposure_max;
> + struct v4l2_subdev_state *state;
> + const struct v4l2_mbus_framefmt *format;
> +
> + state = v4l2_subdev_get_locked_active_state(&gc05a2->sd);
> + format = v4l2_subdev_state_get_format(state, 0);
> +
> + if (ctrl->id == V4L2_CID_VBLANK) {
> + /* Update max exposure while meeting expected vblanking */
> + exposure_max = format->height + ctrl->val - GC05A2_EXP_MARGIN;
> + __v4l2_ctrl_modify_range(gc05a2->exposure,
> + gc05a2->exposure->minimum,
> + exposure_max, gc05a2->exposure->step,
> + exposure_max);
> + }
> +
> + /*
> + * Applying V4L2 control value only happens
> + * when power is on for streaming.
> + */
> + if (!pm_runtime_get_if_active(gc05a2->dev))
> + return 0;
> +
> + switch (ctrl->id) {
> + case V4L2_CID_EXPOSURE:
> + ret = cci_write(gc05a2->regmap, GC05A2_EXP_REG,
> + ctrl->val, NULL);
> + break;
> +
> + case V4L2_CID_ANALOGUE_GAIN:
> + ret = cci_write(gc05a2->regmap, GC05A2_AGAIN_REG,
> + ctrl->val, NULL);
> + break;
> +
> + case V4L2_CID_VBLANK:
> + ret = cci_write(gc05a2->regmap, GC05A2_FRAME_LENGTH_REG,
> + gc05a2->cur_mode->height + ctrl->val, NULL);
> + break;
> +
> + case V4L2_CID_HFLIP:
> + ret = gc05a2_set_ctrl_hflip(gc05a2, ctrl->val);
> + break;
> +
> + case V4L2_CID_VFLIP:
> + ret = gc05a2_set_ctrl_vflip(gc05a2, ctrl->val);
> + break;
> +
> + case V4L2_CID_TEST_PATTERN:
> + ret = gc05a2_test_pattern(gc05a2, ctrl->val);
> + break;
> +
> + default:
> + break;
> + }
> +
> + pm_runtime_put(gc05a2->dev);
> +
> + return ret;
> +}
> +
> +static const struct v4l2_ctrl_ops gc05a2_ctrl_ops = {
> + .s_ctrl = gc05a2_set_ctrl,
> +};
> +
> +static int gc05a2_identify_module(struct gc05a2 *gc05a2)
> +{
> + u64 val;
> + int ret;
> +
> + if (gc05a2->identified)
> + return 0;
> +
> + ret = cci_read(gc05a2->regmap, GC05A2_REG_CHIP_ID, &val, NULL);
> + if (ret)
> + return ret;
> +
> + if (val != GC05A2_CHIP_ID) {
> + dev_err(gc05a2->dev, "chip id mismatch: 0x%x!=0x%llx",
> + GC05A2_CHIP_ID, val);
> + return -ENXIO;
> + }
> +
> + gc05a2->identified = true;
> +
> + return 0;
> +}
> +
> +static int gc05a2_start_streaming(struct gc05a2 *gc05a2)
> +{
> + const struct gc05a2_mode *mode;
> + const struct gc05a2_reg_list *reg_list;
> + int ret;
> +
> + ret = pm_runtime_resume_and_get(gc05a2->dev);
> + if (ret < 0)
> + return ret;
> +
> + ret = gc05a2_identify_module(gc05a2);
> + if (ret)
> + goto err_rpm_put;
> +
> + ret = cci_multi_reg_write(gc05a2->regmap,
> + mode_table_common,
> + ARRAY_SIZE(mode_table_common), NULL);
> + if (ret)
> + goto err_rpm_put;
> +
> + mode = gc05a2->cur_mode;
> + reg_list = &mode->reg_list;
> +
> + ret = cci_multi_reg_write(gc05a2->regmap,
> + reg_list->regs, reg_list->num_of_regs, NULL);
> + if (ret < 0)
> + goto err_rpm_put;
> +
> + ret = __v4l2_ctrl_handler_setup(&gc05a2->ctrls);
> + if (ret < 0) {
> + dev_err(gc05a2->dev, "could not sync v4l2 controls\n");
> + goto err_rpm_put;
> + }
> +
> + ret = cci_write(gc05a2->regmap, GC05A2_STREAMING_REG, 1, NULL);
> + if (ret < 0) {
> + dev_err(gc05a2->dev, "write STREAMING_REG failed: %d\n", ret);
> + goto err_rpm_put;
> + }
> +
> + return 0;
> +
> +err_rpm_put:
> + pm_runtime_put(gc05a2->dev);
> + return ret;
> +}
> +
> +static int gc05a2_stop_streaming(struct gc05a2 *gc05a2)
> +{
> + int ret;
> +
> + ret = cci_write(gc05a2->regmap, GC05A2_STREAMING_REG, 0, NULL);
> + if (ret < 0)
> + dev_err(gc05a2->dev, "could not sent stop streaming %d\n", ret);
> +
> + pm_runtime_put(gc05a2->dev);
> + return ret;
> +}
> +
> +static int gc05a2_s_stream(struct v4l2_subdev *subdev, int enable)
> +{
> + struct gc05a2 *gc05a2 = to_gc05a2(subdev);
> + struct v4l2_subdev_state *state;
> + int ret;
> +
> + state = v4l2_subdev_lock_and_get_active_state(subdev);
> +
> + if (enable)
> + ret = gc05a2_start_streaming(gc05a2);
> + else
> + ret = gc05a2_stop_streaming(gc05a2);
> +
> + v4l2_subdev_unlock_state(state);
> +
> + return ret;
> +}
> +
> +static const struct v4l2_subdev_video_ops gc05a2_video_ops = {
> + .s_stream = gc05a2_s_stream,
> +};
> +
> +static const struct v4l2_subdev_pad_ops gc05a2_subdev_pad_ops = {
> + .enum_mbus_code = gc05a2_enum_mbus_code,
> + .enum_frame_size = gc05a2_enum_frame_size,
> + .get_fmt = v4l2_subdev_get_fmt,
> + .set_fmt = gc05a2_set_format,
> + .get_selection = gc05a2_get_selection,
> +};
> +
> +static const struct v4l2_subdev_core_ops gc05a2_core_ops = {
> + .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
> + .unsubscribe_event = v4l2_event_subdev_unsubscribe,
> +};
> +
> +static const struct v4l2_subdev_ops gc05a2_subdev_ops = {
> + .core = &gc05a2_core_ops,
> + .video = &gc05a2_video_ops,
> + .pad = &gc05a2_subdev_pad_ops,
> +};
> +
> +static const struct v4l2_subdev_internal_ops gc05a2_internal_ops = {
> + .init_state = gc05a2_init_state,
> +};
> +
> +static int gc05a2_get_regulators(struct device *dev, struct gc05a2 *gc05a2)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < ARRAY_SIZE(gc05a2_supply_name); i++)
> + gc05a2->supplies[i].supply = gc05a2_supply_name[i];
> +
> + return devm_regulator_bulk_get(dev, ARRAY_SIZE(gc05a2_supply_name),
> + gc05a2->supplies);
> +}
> +
> +static int gc05a2_parse_fwnode(struct gc05a2 *gc05a2)
> +{
> + struct fwnode_handle *endpoint;
> + struct v4l2_fwnode_endpoint bus_cfg = {
> + .bus_type = V4L2_MBUS_CSI2_DPHY,
> + };
> + int ret;
> + struct device *dev = gc05a2->dev;
> +
> + endpoint =
> + fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0,
> + FWNODE_GRAPH_ENDPOINT_NEXT);
> + if (!endpoint) {
> + dev_err(dev, "endpoint node not found\n");
> + return -EINVAL;
> + }
> +
> + ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
> + if (ret) {
> + dev_err(dev, "parsing endpoint node failed\n");
> + goto done;
> + }
> +
> + ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
> + bus_cfg.nr_of_link_frequencies,
> + gc05a2_link_freq_menu_items,
> + ARRAY_SIZE(gc05a2_link_freq_menu_items),
> + &gc05a2->link_freq_bitmap);
> + if (ret)
> + goto done;
> +
> +done:
> + v4l2_fwnode_endpoint_free(&bus_cfg);
> + fwnode_handle_put(endpoint);
> + return ret;
> +}
> +
> +static u64 gc05a2_to_pixel_rate(u32 f_index)
> +{
> + u64 pixel_rate =
> + gc05a2_link_freq_menu_items[f_index] * 2 * GC05A2_DATA_LANES;
> +
> + return div_u64(pixel_rate, GC05A2_RGB_DEPTH);
> +}
> +
> +static int gc05a2_init_controls(struct gc05a2 *gc05a2)
> +{
> + struct i2c_client *client = v4l2_get_subdevdata(&gc05a2->sd);
> + const struct gc05a2_mode *mode = &gc05a2_modes[0];
> + const struct v4l2_ctrl_ops *ops = &gc05a2_ctrl_ops;
> + struct v4l2_fwnode_device_properties props;
> + struct v4l2_ctrl_handler *ctrl_hdlr;
> + s64 exposure_max, h_blank;
> + int ret;
> +
> + ctrl_hdlr = &gc05a2->ctrls;
> + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 9);
> + if (ret)
> + return ret;
> +
> + gc05a2->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
> + V4L2_CID_HFLIP, 0, 1, 1, 0);
> + gc05a2->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
> + V4L2_CID_VFLIP, 0, 1, 1, 0);
> + v4l2_ctrl_cluster(2, &gc05a2->hflip);
> +
> + gc05a2->link_freq =
> + v4l2_ctrl_new_int_menu(ctrl_hdlr,
> + &gc05a2_ctrl_ops,
> + V4L2_CID_LINK_FREQ,
> + ARRAY_SIZE(gc05a2_link_freq_menu_items) - 1,
> + 0,
> + gc05a2_link_freq_menu_items);
> + if (gc05a2->link_freq)
> + gc05a2->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> + gc05a2->pixel_rate =
> + v4l2_ctrl_new_std(ctrl_hdlr,
> + &gc05a2_ctrl_ops,
> + V4L2_CID_PIXEL_RATE, 0,
> + gc05a2_to_pixel_rate(0),
> + 1,
> + gc05a2_to_pixel_rate(0));
> +
> + gc05a2->vblank =
> + v4l2_ctrl_new_std(ctrl_hdlr,
> + &gc05a2_ctrl_ops, V4L2_CID_VBLANK,
> + mode->vts_min - mode->height,
> + GC05A2_VTS_MAX - mode->height, 1,
> + mode->vts_def - mode->height);
> +
> + h_blank = mode->hts - mode->width;
> + gc05a2->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
> + V4L2_CID_HBLANK, h_blank, h_blank, 1,
> + h_blank);
> + if (gc05a2->hblank)
> + gc05a2->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> + v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
> + V4L2_CID_ANALOGUE_GAIN, GC05A2_AGAIN_MIN,
> + GC05A2_AGAIN_MAX, GC05A2_AGAIN_STEP,
> + GC05A2_AGAIN_MIN);
> +
> + exposure_max = mode->vts_def - GC05A2_EXP_MARGIN;
> + gc05a2->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
> + V4L2_CID_EXPOSURE, GC05A2_EXP_MIN,
> + exposure_max, GC05A2_EXP_STEP,
> + exposure_max);
> +
> + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &gc05a2_ctrl_ops,
> + V4L2_CID_TEST_PATTERN,
> + ARRAY_SIZE(gc05a2_test_pattern_menu) - 1,
> + 0, 0, gc05a2_test_pattern_menu);
> +
> + /* register properties to fwnode (e.g. rotation, orientation) */
> + ret = v4l2_fwnode_device_parse(&client->dev, &props);
> + if (ret)
> + goto error_ctrls;
> +
> + ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, ops, &props);
> + if (ret)
> + goto error_ctrls;
> +
> + if (ctrl_hdlr->error) {
> + ret = ctrl_hdlr->error;
> + goto error_ctrls;
> + }
> +
> + gc05a2->sd.ctrl_handler = ctrl_hdlr;
> +
> + return 0;
> +
> +error_ctrls:
> + v4l2_ctrl_handler_free(ctrl_hdlr);
> +
> + return ret;
> +}
> +
> +static int gc05a2_probe(struct i2c_client *client)
> +{
> + struct device *dev = &client->dev;
> + struct gc05a2 *gc05a2;
> + int ret;
> +
> + gc05a2 = devm_kzalloc(dev, sizeof(*gc05a2), GFP_KERNEL);
> + if (!gc05a2)
> + return -ENOMEM;
> +
> + gc05a2->dev = dev;
> +
> + ret = gc05a2_parse_fwnode(gc05a2);
> + if (ret)
> + return ret;
> +
> + gc05a2->regmap = devm_cci_regmap_init_i2c(client, 16);
> + if (IS_ERR(gc05a2->regmap))
> + return dev_err_probe(dev, PTR_ERR(gc05a2->regmap),
> + "failed to init CCI\n");
> +
> + gc05a2->xclk = devm_clk_get(dev, NULL);
> + if (IS_ERR(gc05a2->xclk))
> + return dev_err_probe(dev, PTR_ERR(gc05a2->xclk),
> + "failed to get xclk\n");
> +
> + ret = clk_set_rate(gc05a2->xclk, GC05A2_DEFAULT_CLK_FREQ);
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "failed to set xclk frequency\n");
> +
> + ret = gc05a2_get_regulators(dev, gc05a2);
> + if (ret < 0)
> + return dev_err_probe(dev, ret,
> + "failed to get regulators\n");
> +
> + gc05a2->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
> + if (IS_ERR(gc05a2->reset_gpio))
> + return dev_err_probe(dev, PTR_ERR(gc05a2->reset_gpio),
> + "failed to get gpio\n");
> +
> + v4l2_i2c_subdev_init(&gc05a2->sd, client, &gc05a2_subdev_ops);
> + gc05a2->sd.internal_ops = &gc05a2_internal_ops;
> + gc05a2->cur_mode = &gc05a2_modes[0];
> +
> + ret = gc05a2_init_controls(gc05a2);
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "failed to init controls\n");
> +
> + gc05a2->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
> + V4L2_SUBDEV_FL_HAS_EVENTS;
> + gc05a2->pad.flags = MEDIA_PAD_FL_SOURCE;
> + gc05a2->sd.dev = &client->dev;
> + gc05a2->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> +
> + ret = media_entity_pads_init(&gc05a2->sd.entity, 1, &gc05a2->pad);
> + if (ret < 0) {
> + dev_err(dev, "could not register media entity\n");
> + goto err_v4l2_ctrl_handler_free;
> + }
> +
> + gc05a2->sd.state_lock = gc05a2->ctrls.lock;
> + ret = v4l2_subdev_init_finalize(&gc05a2->sd);
> + if (ret < 0) {
> + dev_err(dev, "v4l2 subdev init error: %d\n", ret);
> + goto err_media_entity_cleanup;
> + }
> +
> + pm_runtime_set_active(gc05a2->dev);
> + pm_runtime_enable(gc05a2->dev);
> + pm_runtime_set_autosuspend_delay(gc05a2->dev, 1000);
> + pm_runtime_use_autosuspend(gc05a2->dev);
> + pm_runtime_idle(gc05a2->dev);
> +
> + ret = v4l2_async_register_subdev_sensor(&gc05a2->sd);
> + if (ret < 0) {
> + dev_err(dev, "could not register v4l2 device\n");
> + goto err_rpm;
> + }
> +
> + return 0;
> +
> +err_rpm:
> + pm_runtime_disable(gc05a2->dev);
> + v4l2_subdev_cleanup(&gc05a2->sd);
> +
> +err_media_entity_cleanup:
> + media_entity_cleanup(&gc05a2->sd.entity);
> +
> +err_v4l2_ctrl_handler_free:
> + v4l2_ctrl_handler_free(&gc05a2->ctrls);
> +
> + return ret;
> +}
> +
> +static void gc05a2_remove(struct i2c_client *client)
> +{
> + struct v4l2_subdev *sd = i2c_get_clientdata(client);
> + struct gc05a2 *gc05a2 = to_gc05a2(sd);
> +
> + v4l2_async_unregister_subdev(&gc05a2->sd);
> + v4l2_subdev_cleanup(sd);
> + media_entity_cleanup(&gc05a2->sd.entity);
> + v4l2_ctrl_handler_free(&gc05a2->ctrls);
> +
> + pm_runtime_disable(&client->dev);
> + if (!pm_runtime_status_suspended(&client->dev))
> + gc05a2_power_off(gc05a2->dev);
> + pm_runtime_set_suspended(&client->dev);
> +}
> +
> +static const struct of_device_id gc05a2_of_match[] = {
> + { .compatible = "galaxycore,gc05a2" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, gc05a2_of_match);
> +
> +static DEFINE_RUNTIME_DEV_PM_OPS(gc05a2_pm_ops,
> + gc05a2_power_off,
> + gc05a2_power_on,
> + NULL);
> +
> +static struct i2c_driver gc05a2_i2c_driver = {
> + .driver = {
> + .of_match_table = gc05a2_of_match,
> + .pm = pm_ptr(&gc05a2_pm_ops),
> + .name = "gc05a2",
> + },
> + .probe = gc05a2_probe,
> + .remove = gc05a2_remove,
> +};
> +module_i2c_driver(gc05a2_i2c_driver);
> +
> +MODULE_DESCRIPTION("GalaxyCore gc05a2 Camera driver");
> +MODULE_AUTHOR("Zhi Mao <zhi.mao@mediatek.com>");
> +MODULE_LICENSE("GPL");
> --
> 2.25.1
>
^ permalink raw reply
* RE: [EXT] Re: [PATCH v1 1/1] arm64: dts: imx93-11x11-evk: add rtc PCF2131 support
From: Joy Zou @ 2024-04-07 9:09 UTC (permalink / raw)
To: Krzysztof Kozlowski, Jacky Bai, robh+dt@kernel.org,
krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org,
shawnguo@kernel.org, s.hauer@pengutronix.de
Cc: kernel@pengutronix.de, festevam@gmail.com, dl-linux-imx,
devicetree@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <f019690a-2397-4bf8-9472-ec38f4b94c1d@linaro.org>
> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Sent: 2024年4月7日 17:04
> To: Joy Zou <joy.zou@nxp.com>; Jacky Bai <ping.bai@nxp.com>;
> robh+dt@kernel.org; krzysztof.kozlowski+dt@linaro.org;
> conor+dt@kernel.org; shawnguo@kernel.org; s.hauer@pengutronix.de
> Cc: kernel@pengutronix.de; festevam@gmail.com; dl-linux-imx
> <linux-imx@nxp.com>; devicetree@vger.kernel.org; imx@lists.linux.dev;
> linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> Subject: [EXT] Re: [PATCH v1 1/1] arm64: dts: imx93-11x11-evk: add rtc
> PCF2131 support
> > +&lpi2c3 {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + clock-frequency = <400000>;
> > + pinctrl-names = "default", "sleep";
> > + pinctrl-0 = <&pinctrl_lpi2c3>;
> > + pinctrl-1 = <&pinctrl_lpi2c3>;
> > + status = "okay";
> > +
> > + pcf2131: rtc@53 {
> > + compatible = "nxp,pcf2131";
> > + reg = <0x53>;
> > + interrupt-parent = <&pcal6524>;
> > + interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
> > + status = "okay";
>
> Really, just drop...
Ok, will drop the status in next version.
Thanks for your comment!
BR
Joy Zou
>
>
> Best regards,
> Krzysztof
^ permalink raw reply
* Re: [PATCH v2] dt-bindings: PCI: altera: Convert to YAML
From: Krzysztof Kozlowski @ 2024-04-07 9:11 UTC (permalink / raw)
To: matthew.gerlach, bhelgaas, lpieralisi, kw, robh,
krzysztof.kozlowski+dt, conor+dt, linux-pci, devicetree,
linux-kernel
In-Reply-To: <20240405145322.3805828-1-matthew.gerlach@linux.intel.com>
On 05/04/2024 16:53, matthew.gerlach@linux.intel.com wrote:
> From: Matthew Gerlach <matthew.gerlach@linux.intel.com>
>
> Convert the device tree bindings for the Altera Root Port PCIe controller
> from text to YAML.
>
> Signed-off-by: Matthew Gerlach <matthew.gerlach@linux.intel.com>
> ---
> v2:
> - Move allOf: to bottom of file, just like example-schema is showing
No, just open it and you will see it is placed differently...
> - add constraint for reg and reg-names
Not complete...
> - remove unneeded device_type
> - drop #address-cells and #size-cells
> - change minItems to maxItems for interrupts:
> - change msi-parent to just "msi-parent: true"
> - cleaned up required:
> - make subject consistent with other commits coverting to YAML
> - s/overt/onvert/g
> ---
> .../devicetree/bindings/pci/altera-pcie.txt | 50 ---------
> .../bindings/pci/altr,pcie-root-port.yaml | 106 ++++++++++++++++++
> 2 files changed, 106 insertions(+), 50 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/pci/altera-pcie.txt
> create mode 100644 Documentation/devicetree/bindings/pci/altr,pcie-root-port.yaml
>
> diff --git a/Documentation/devicetree/bindings/pci/altera-pcie.txt b/Documentation/devicetree/bindings/pci/altera-pcie.txt
> deleted file mode 100644
> index 816b244a221e..000000000000
> --- a/Documentation/devicetree/bindings/pci/altera-pcie.txt
> +++ /dev/null
> @@ -1,50 +0,0 @@
> -* Altera PCIe controller
> -
> -Required properties:
> -- compatible : should contain "altr,pcie-root-port-1.0" or "altr,pcie-root-port-2.0"
> -- reg: a list of physical base address and length for TXS and CRA.
> - For "altr,pcie-root-port-2.0", additional HIP base address and length.
> -- reg-names: must include the following entries:
> - "Txs": TX slave port region
> - "Cra": Control register access region
> - "Hip": Hard IP region (if "altr,pcie-root-port-2.0")
> -- interrupts: specifies the interrupt source of the parent interrupt
> - controller. The format of the interrupt specifier depends
> - on the parent interrupt controller.
> -- device_type: must be "pci"
> -- #address-cells: set to <3>
> -- #size-cells: set to <2>
> -- #interrupt-cells: set to <1>
> -- ranges: describes the translation of addresses for root ports and
> - standard PCI regions.
> -- interrupt-map-mask and interrupt-map: standard PCI properties to define the
> - mapping of the PCIe interface to interrupt numbers.
> -
> -Optional properties:
> -- msi-parent: Link to the hardware entity that serves as the MSI controller
> - for this PCIe controller.
> -- bus-range: PCI bus numbers covered
> -
> -Example
> - pcie_0: pcie@c00000000 {
> - compatible = "altr,pcie-root-port-1.0";
> - reg = <0xc0000000 0x20000000>,
> - <0xff220000 0x00004000>;
> - reg-names = "Txs", "Cra";
> - interrupt-parent = <&hps_0_arm_gic_0>;
> - interrupts = <0 40 4>;
> - interrupt-controller;
> - #interrupt-cells = <1>;
> - bus-range = <0x0 0xFF>;
> - device_type = "pci";
> - msi-parent = <&msi_to_gic_gen_0>;
> - #address-cells = <3>;
> - #size-cells = <2>;
> - interrupt-map-mask = <0 0 0 7>;
> - interrupt-map = <0 0 0 1 &pcie_0 1>,
> - <0 0 0 2 &pcie_0 2>,
> - <0 0 0 3 &pcie_0 3>,
> - <0 0 0 4 &pcie_0 4>;
> - ranges = <0x82000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x10000000
> - 0x82000000 0x00000000 0x10000000 0xd0000000 0x00000000 0x10000000>;
> - };
> diff --git a/Documentation/devicetree/bindings/pci/altr,pcie-root-port.yaml b/Documentation/devicetree/bindings/pci/altr,pcie-root-port.yaml
> new file mode 100644
> index 000000000000..999dcda05f55
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/altr,pcie-root-port.yaml
> @@ -0,0 +1,106 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright (C) 2024, Intel Corporation
This is derivative of previous work, which is easily visible by doing
the same mistakes in DTS as they were before.
You now added fresh copyrights ignoring all previous work, even though
you copied it. I don't agree.
If you want to ignore previous copyrights, then at least don't copy
existing code... although even that would not be sufficient.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/altr,pcie-root-port.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Altera PCIe Root Port
> +
> +maintainers:
> + - Matthew Gerlach <matthew.gerlach@linux.intel.com>
> +
> +properties:
> + compatible:
> + items:
Drop items.
> + - enum:
> + - altr,pcie-root-port-1.0
> + - altr,pcie-root-port-2.0
> +
Missing reg with constraints.
> + interrupts:
> + maxItems: 1
> +
> + interrupt-map-mask:
> + items:
> + - const: 0
> + - const: 0
> + - const: 0
> + - const: 7
> +
> + interrupt-map:
> + maxItems: 4
> +
> + "#interrupt-cells":
> + const: 1
> +
> + msi-parent: true
> +
> +required:
> + - compatible
> + - reg
> + - reg-names
> + - device_type
> + - interrupts
> + - interrupt-map
> + - interrupt-map-mask
> +
> +unevaluatedProperties: false
> +
> +allOf:
> + - $ref: /schemas/pci/pci-bus.yaml#
That's deprecated, as explained in its description. You should use
pci-host-bridge.yaml.
> + - if:
> + properties:
> + compatible:
> + enum:
> + - altr,pcie-root-port-1.0
> + then:
> + properties:
> + reg:
> + items:
> + - description: TX slave port region
> + - description: Control register access region
> +
> + reg-names:
> + items:
> + - const: Txs
> + - const: Cra
> +
> + else:
> + properties:
> + reg:
> + items:
> + - description: Hard IP region
> + - description: TX slave port region
> + - description: Control register access region
> +
> + reg-names:
> + items:
> + - const: Hip
> + - const: Txs
> + - const: Cra
> +
unevaluated goes here, just like example-schema.
> +examples:
> + - |
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> + #include <dt-bindings/interrupt-controller/irq.h>
> + pcie_0: pcie@c00000000 {
> + compatible = "altr,pcie-root-port-1.0";
> + reg = <0xc0000000 0x20000000>,
> + <0xff220000 0x00004000>;
> + reg-names = "Txs", "Cra";
> + interrupt-parent = <&hps_0_arm_gic_0>;
> + interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
> + #interrupt-cells = <1>;
> + bus-range = <0x0 0xff>;
> + device_type = "pci";
> + msi-parent = <&msi_to_gic_gen_0>;
> + #address-cells = <3>;
> + #size-cells = <2>;
> + interrupt-map-mask = <0 0 0 7>;
> + interrupt-map = <0 0 0 1 &pcie_intc 1>,
> + <0 0 0 2 &pcie_intc 2>,
> + <0 0 0 3 &pcie_intc 3>,
> + <0 0 0 4 &pcie_intc 4>;
> + ranges = <0x82000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x10000000
> + 0x82000000 0x00000000 0x10000000 0xd0000000 0x00000000 0x10000000>;
That's two entries.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [EXT] Re: [PATCH v1 1/1] arm64: dts: imx93-11x11-evk: add rtc PCF2131 support
From: Krzysztof Kozlowski @ 2024-04-07 9:12 UTC (permalink / raw)
To: Joy Zou, Jacky Bai, robh+dt@kernel.org,
krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org,
shawnguo@kernel.org, s.hauer@pengutronix.de
Cc: kernel@pengutronix.de, festevam@gmail.com, dl-linux-imx,
devicetree@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <AS4PR04MB9386C629F898A8417AE57506E1012@AS4PR04MB9386.eurprd04.prod.outlook.com>
On 07/04/2024 11:09, Joy Zou wrote:
>
>> -----Original Message-----
>> From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
>> Sent: 2024年4月7日 17:04
>> To: Joy Zou <joy.zou@nxp.com>; Jacky Bai <ping.bai@nxp.com>;
>> robh+dt@kernel.org; krzysztof.kozlowski+dt@linaro.org;
>> conor+dt@kernel.org; shawnguo@kernel.org; s.hauer@pengutronix.de
>> Cc: kernel@pengutronix.de; festevam@gmail.com; dl-linux-imx
>> <linux-imx@nxp.com>; devicetree@vger.kernel.org; imx@lists.linux.dev;
>> linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org
>> Subject: [EXT] Re: [PATCH v1 1/1] arm64: dts: imx93-11x11-evk: add rtc
>> PCF2131 support
>>> +&lpi2c3 {
>>> + #address-cells = <1>;
>>> + #size-cells = <0>;
>>> + clock-frequency = <400000>;
>>> + pinctrl-names = "default", "sleep";
>>> + pinctrl-0 = <&pinctrl_lpi2c3>;
>>> + pinctrl-1 = <&pinctrl_lpi2c3>;
>>> + status = "okay";
>>> +
>>> + pcf2131: rtc@53 {
>>> + compatible = "nxp,pcf2131";
>>> + reg = <0x53>;
>>> + interrupt-parent = <&pcal6524>;
>>> + interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
>>> + status = "okay";
>>
>> Really, just drop...
> Ok, will drop the status in next version.
> Thanks for your comment!
Please read DTS coding style.
Best regards,
Krzysztof
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox