* [PATCH v4 4/6] arm64: dts: qcom: shikra: Add pin configuration for mclks
From: Nihal Kumar Gupta @ 2026-06-15 8:33 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma,
Nihal Kumar Gupta
In-Reply-To: <20260615-shikra-camss-review-v4-0-bcb51081735b@oss.qualcomm.com>
Add pinctrl configuration for the four available camera master clocks.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Signed-off-by: Nihal Kumar Gupta <nihal.gupta@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/shikra.dtsi | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi
index 57732804a6c6a114a407a4a541a1cc7af7635ea2..16b547131e8b14541abc68ff7cda126ba777ad80 100644
--- a/arch/arm64/boot/dts/qcom/shikra.dtsi
+++ b/arch/arm64/boot/dts/qcom/shikra.dtsi
@@ -380,6 +380,34 @@ cci_i2c1_sleep: cci-i2c1-sleep-state {
bias-pull-down;
};
+ cam_mclk0_default: cam-mclk0-default-state {
+ pins = "gpio34";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk1_default: cam-mclk1-default-state {
+ pins = "gpio35";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk2_default: cam-mclk2-default-state {
+ pins = "gpio96";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk3_default: cam-mclk3-default-state {
+ pins = "gpio98";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
qup_uart0_default: qup-uart0-default-state {
pins = "gpio0", "gpio1";
function = "qup0_se0";
--
2.34.1
^ permalink raw reply related
* [PATCH v4 3/6] arm64: dts: qcom: shikra: Add CCI definitions
From: Nihal Kumar Gupta @ 2026-06-15 8:33 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma,
Nihal Kumar Gupta
In-Reply-To: <20260615-shikra-camss-review-v4-0-bcb51081735b@oss.qualcomm.com>
Qualcomm Shikra SoC has one Camera Control Interface (CCI)
containing two I2C hosts.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Signed-off-by: Nihal Kumar Gupta <nihal.gupta@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/shikra.dtsi | 70 ++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi
index f0e827996609dab2c09834857a1bffd9560155a6..57732804a6c6a114a407a4a541a1cc7af7635ea2 100644
--- a/arch/arm64/boot/dts/qcom/shikra.dtsi
+++ b/arch/arm64/boot/dts/qcom/shikra.dtsi
@@ -348,6 +348,38 @@ tlmm: pinctrl@500000 {
gpio-ranges = <&tlmm 0 0 165>;
wakeup-parent = <&mpm>;
+ cci_i2c0_default: cci-i2c0-default-state {
+ /* SDA, SCL */
+ pins = "gpio36", "gpio37";
+ function = "cci_i2c0";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ cci_i2c0_sleep: cci-i2c0-sleep-state {
+ /* SDA, SCL */
+ pins = "gpio36", "gpio37";
+ function = "cci_i2c0";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ cci_i2c1_default: cci-i2c1-default-state {
+ /* SDA, SCL */
+ pins = "gpio41", "gpio42";
+ function = "cci_i2c1";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ cci_i2c1_sleep: cci-i2c1-sleep-state {
+ /* SDA, SCL */
+ pins = "gpio41", "gpio42";
+ function = "cci_i2c1";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
qup_uart0_default: qup-uart0-default-state {
pins = "gpio0", "gpio1";
function = "qup0_se0";
@@ -702,6 +734,44 @@ port@1 {
reg = <1>;
};
};
+
+ };
+
+ cci: cci@5c1b000 {
+ compatible = "qcom,shikra-cci", "qcom,msm8996-cci";
+ reg = <0x0 0x05c1b000 0x0 0x1000>;
+
+ interrupts = <GIC_SPI 206 IRQ_TYPE_EDGE_RISING 0>;
+
+ clocks = <&gcc GCC_CAMSS_TOP_AHB_CLK>,
+ <&gcc GCC_CAMSS_CCI_0_CLK>;
+ clock-names = "ahb",
+ "cci";
+
+ power-domains = <&gcc GCC_CAMSS_TOP_GDSC>;
+
+ pinctrl-0 = <&cci_i2c0_default &cci_i2c1_default>;
+ pinctrl-1 = <&cci_i2c0_sleep &cci_i2c1_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ cci_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <400000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cci_i2c1: i2c-bus@1 {
+ reg = <1>;
+ clock-frequency = <400000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
};
qupv3_0: geniqup@4ac0000 {
--
2.34.1
^ permalink raw reply related
* [PATCH v4 2/6] arm64: dts: qcom: shikra: Add CAMSS node
From: Nihal Kumar Gupta @ 2026-06-15 8:33 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma,
Nihal Kumar Gupta
In-Reply-To: <20260615-shikra-camss-review-v4-0-bcb51081735b@oss.qualcomm.com>
Add the Camera Subsystem node. Shikra shares the same IP as QCM2290
with two CSIPHYs, two CSIDs and two VFEs, but does not include CDM
and OPE blocks, so only a single IOMMU context bank is needed.
Co-developed-by: Vikram Sharma <vikram.sharma@oss.qualcomm.com>
Signed-off-by: Vikram Sharma <vikram.sharma@oss.qualcomm.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Signed-off-by: Nihal Kumar Gupta <nihal.gupta@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/shikra.dtsi | 100 +++++++++++++++++++++++++++++++++++
1 file changed, 100 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi
index a4334d99c1f35ee851ca8266ec37d4a200a07ee5..f0e827996609dab2c09834857a1bffd9560155a6 100644
--- a/arch/arm64/boot/dts/qcom/shikra.dtsi
+++ b/arch/arm64/boot/dts/qcom/shikra.dtsi
@@ -604,6 +604,106 @@ opp-384000000 {
};
};
+ camss: camss@5c11000 {
+ compatible = "qcom,shikra-camss", "qcom,qcm2290-camss";
+
+ reg = <0x0 0x05c11000 0x0 0x1000>,
+ <0x0 0x05c6e000 0x0 0x1000>,
+ <0x0 0x05c75000 0x0 0x1000>,
+ <0x0 0x05c52000 0x0 0x1000>,
+ <0x0 0x05c53000 0x0 0x1000>,
+ <0x0 0x05c66000 0x0 0x400>,
+ <0x0 0x05c68000 0x0 0x400>,
+ <0x0 0x05c6f000 0x0 0x4000>,
+ <0x0 0x05c76000 0x0 0x4000>;
+ reg-names = "top",
+ "csid0",
+ "csid1",
+ "csiphy0",
+ "csiphy1",
+ "csitpg0",
+ "csitpg1",
+ "vfe0",
+ "vfe1";
+
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMSS_AXI_CLK>,
+ <&gcc GCC_CAMSS_NRT_AXI_CLK>,
+ <&gcc GCC_CAMSS_RT_AXI_CLK>,
+ <&gcc GCC_CAMSS_TFE_0_CSID_CLK>,
+ <&gcc GCC_CAMSS_TFE_1_CSID_CLK>,
+ <&gcc GCC_CAMSS_CPHY_0_CLK>,
+ <&gcc GCC_CAMSS_CSI0PHYTIMER_CLK>,
+ <&gcc GCC_CAMSS_CPHY_1_CLK>,
+ <&gcc GCC_CAMSS_CSI1PHYTIMER_CLK>,
+ <&gcc GCC_CAMSS_TOP_AHB_CLK>,
+ <&gcc GCC_CAMSS_TFE_0_CLK>,
+ <&gcc GCC_CAMSS_TFE_0_CPHY_RX_CLK>,
+ <&gcc GCC_CAMSS_TFE_1_CLK>,
+ <&gcc GCC_CAMSS_TFE_1_CPHY_RX_CLK>;
+ clock-names = "ahb",
+ "axi",
+ "camnoc_nrt_axi",
+ "camnoc_rt_axi",
+ "csi0",
+ "csi1",
+ "csiphy0",
+ "csiphy0_timer",
+ "csiphy1",
+ "csiphy1_timer",
+ "top_ahb",
+ "vfe0",
+ "vfe0_cphy_rx",
+ "vfe1",
+ "vfe1_cphy_rx";
+
+ interrupts = <GIC_SPI 210 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 212 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 72 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 73 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 309 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 310 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 211 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 213 IRQ_TYPE_EDGE_RISING 0>;
+ interrupt-names = "csid0",
+ "csid1",
+ "csiphy0",
+ "csiphy1",
+ "csitpg0",
+ "csitpg1",
+ "vfe0",
+ "vfe1";
+
+ interconnects = <&mem_noc MASTER_AMPSS_M0 RPM_ACTIVE_TAG
+ &config_noc SLAVE_CAMERA_CFG RPM_ACTIVE_TAG>,
+ <&mmrt_virt MASTER_CAMNOC_HF RPM_ALWAYS_TAG
+ &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>,
+ <&mmnrt_virt MASTER_CAMNOC_SF RPM_ALWAYS_TAG
+ &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>;
+ interconnect-names = "ahb",
+ "hf_mnoc",
+ "sf_mnoc";
+
+ iommus = <&apps_smmu 0x400 0x0>;
+
+ power-domains = <&gcc GCC_CAMSS_TOP_GDSC>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
qupv3_0: geniqup@4ac0000 {
compatible = "qcom,geni-se-qup";
reg = <0x0 0x04ac0000 0x0 0x2000>;
--
2.34.1
^ permalink raw reply related
* [PATCH v4 1/6] dt-bindings: media: qcom: Add Shikra CAMSS compatible
From: Nihal Kumar Gupta @ 2026-06-15 8:33 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma,
Nihal Kumar Gupta, Krzysztof Kozlowski
In-Reply-To: <20260615-shikra-camss-review-v4-0-bcb51081735b@oss.qualcomm.com>
Shikra contains the same Camera Subsystem IP as QCM2290. Document the
platform-specific compatible string, using qcom,qcm2290-camss as
fallback.
Unlike QCM2290, Shikra omits the CDM and OPE blocks, requiring only a
single IOMMU context bank instead of four.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Signed-off-by: Nihal Kumar Gupta <nihal.gupta@oss.qualcomm.com>
---
.../devicetree/bindings/media/qcom,qcm2290-camss.yaml | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/media/qcom,qcm2290-camss.yaml b/Documentation/devicetree/bindings/media/qcom,qcm2290-camss.yaml
index 391d0f6f67ef5fdfea31dd3683477561516b1556..490a7f3a8c5ff9c624f46150ee651793811823de 100644
--- a/Documentation/devicetree/bindings/media/qcom,qcm2290-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,qcm2290-camss.yaml
@@ -14,7 +14,11 @@ description:
properties:
compatible:
- const: qcom,qcm2290-camss
+ oneOf:
+ - items:
+ - const: qcom,shikra-camss
+ - const: qcom,qcm2290-camss
+ - const: qcom,qcm2290-camss
reg:
maxItems: 9
@@ -76,7 +80,14 @@ properties:
- const: sf_mnoc
iommus:
- maxItems: 4
+ oneOf:
+ - items:
+ - description: S1 HLOS VFE non-protected (VFE only)
+ - items:
+ - description: S1 HLOS VFE non-protected
+ - description: S1 HLOS CDM non-protected
+ - description: S1 HLOS OPE read non-protected
+ - description: S1 HLOS OPE write non-protected
power-domains:
items:
--
2.34.1
^ permalink raw reply related
* [PATCH v4 0/6] Add CAMSS and IMX577 sensor support for Shikra EVK
From: Nihal Kumar Gupta @ 2026-06-15 8:33 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma,
Nihal Kumar Gupta, Krzysztof Kozlowski
Shikra EVK is based on the Qualcomm Shikra SoC.
It lacks a camera sensor in its default configuration.
This series adds CAMSS driver support, CCI definitions and enables
the 22-pin IMX577 sensor via CSIPHY1 through device tree overlays.
We have tested IMX577 Sensor on CCI1 with following commands:
- media-ctl --reset
- media-ctl -d /dev/media0 -V '"imx577 1-001a":0[fmt:SRGGB10/4056x3040 field:none]'
- media-ctl -d /dev/media0 -V '"msm_csiphy1":0[fmt:SRGGB10/4056x3040]'
- media-ctl -d /dev/media0 -V '"msm_csid0":0[fmt:SRGGB10/4056x3040]'
- media-ctl -d /dev/media0 -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/4056x3040]'
- media-ctl -d /dev/media0 -l '"msm_csiphy1":1->"msm_csid0":0[1]'
- media-ctl -d /dev/media0 -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'
- yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 4056x3040 -F /dev/video0
Used following tools for the sanity check of these changes.
- make -j32 W=1
- checkpatch.pl
- make DT_CHECKER_FLAGS=-m W=1 DT_SCHEMA_FILES=i2c/qcom,i2c-cci.yaml dt_binding_check
- make DT_CHECKER_FLAGS=-m DT_SCHEMA_FILES=media/qcom,qcm2290-camss.yaml dt_binding_check W=1
- make CHECK_DTBS=y W=1 qcom/qrb2210-rb1-vision-mezzanine.dtb
- make CHECK_DTBS=1 W=1 qcom/shikra-cqm-cqs-evk-imx577-camera.dtb
- make CHECK_DTBS=1 W=1 qcom/shikra-iqs-evk-imx577-camera.dtb
- make CHECK_DTBS=y W=1 dtbs
The Shikra CAMSS binding patch does not depend on the rest of the series
and can go through the media tree on its own.
This patch series depends on patch series:
https://lore.kernel.org/all/20260527-shikra-dt-v4-0-b5ca1fa0b392@oss.qualcomm.com/
https://lore.kernel.org/all/20260608-shikra-gcc-rpmcc-clks-v5-0-94cefe092ee3@oss.qualcomm.com/
Signed-off-by: Nihal Kumar Gupta <nihal.gupta@oss.qualcomm.com>
---
Changes in v4:
- Fix data-lanes numbering to start from 1 in all endpoints (Vladimir)
Missed in last rev.
- Link to v3: https://lore.kernel.org/r/20260615-shikra-camss-review-v3-0-8183481f48d0@oss.qualcomm.com
Changes in v3:
- Drop dt-bindings: i2c: qcom-cci: Document Shikra compatible; already
picked by Andi Shyti into her i2c tree (now in linux-next as e3a8f8329397)
- Preserve blank line after compatible const in qcom,qcm2290-camss.yaml (Krzysztof)
- Add blank line between iommus and power-domains in CAMSS node (Vladimir)
- Move cam1_reset_default pinctrl state from board .dts files into the
mezzanine .dtso overlay files (Vladimir)
- Collect Reviewed-by tags
- Link to v2: https://lore.kernel.org/r/20260608-shikra-camss-review-v2-0-ca1936bf1219@oss.qualcomm.com
Changes in v2:
- Drop qcm2390_resources struct and CAMSS_2390 enum; use qcom,qcm2290-camss
as fallback compatible string since Shikra CAMSS is register-compatible
with QCM2290 (Loic, Bryan)
- Use oneOf in iommus to describe all valid SID combinations: VFE-only
(Shikra) and VFE+CDM+OPE read+OPE write (QCM2290/Agatti); add
per-entry descriptions naming each SID (Krzysztof, Bryan)
- Rename shikra-cqm-evk-imx577-camera overlay to
shikra-cqm-cqs-evk-imx577-camera, shared by both CQM and CQS EVK
boards which use the same PM4125 PMIC and camera supply rails (Bryan)
- Add reset-gpios pinctrl state for IMX577 sensor (gpio33, cam1-reset-default-state)
- Add comment in overlay DTS explaining absent regulators are powered
by the daughter board (Bryan)
- Collect Reviewed-by tags
- Add reset-gpios pinctrl state for IMX577 sensor.
- Link to v1: https://lore.kernel.org/r/20260526-shikra-camss-review-v1-0-645d2c8c75a7@qti.qualcomm.com
---
Nihal Kumar Gupta (6):
dt-bindings: media: qcom: Add Shikra CAMSS compatible
arm64: dts: qcom: shikra: Add CAMSS node
arm64: dts: qcom: shikra: Add CCI definitions
arm64: dts: qcom: shikra: Add pin configuration for mclks
arm64: dts: qcom: shikra-cqm-cqs-evk-imx577-camera: Add DT overlay
arm64: dts: qcom: shikra-iqs-evk-imx577-camera: Add DT overlay
.../bindings/media/qcom,qcm2290-camss.yaml | 15 +-
arch/arm64/boot/dts/qcom/Makefile | 8 +
.../dts/qcom/shikra-cqm-cqs-evk-imx577-camera.dtso | 79 ++++++++
.../dts/qcom/shikra-iqs-evk-imx577-camera.dtso | 79 ++++++++
arch/arm64/boot/dts/qcom/shikra.dtsi | 198 +++++++++++++++++++++
5 files changed, 377 insertions(+), 2 deletions(-)
---
base-commit: abe651837cb394f76d738a7a747322fca3bf17ba
change-id: 20260526-shikra-camss-review-cf6f66ac566b
prerequisite-change-id: 20260511-shikra-dt-d75d97454646:v4
prerequisite-patch-id: 3a689e8dda5fd2755b689d94d095806b3f2e6eed
prerequisite-patch-id: 2acc300a68ed8c5364fb5f2f7d28fc0d56ab07bf
prerequisite-patch-id: 2357cac636e019eaf14d6a493a1c72bca56fe405
prerequisite-patch-id: 2885f299e711582da312ca9d13983d296a3dd5dc
prerequisite-patch-id: 91af5f3c01e766a53ce8de69aa21847a2d6bbbf8
prerequisite-change-id: 20260429-shikra-gcc-rpmcc-clks-2094edfff3b0:v5
prerequisite-patch-id: 59bb0a7828e41f546f734f127d81da83c0adcda9
prerequisite-patch-id: 197da6bcb15cadc47869dba88c8020987b25c335
prerequisite-patch-id: 8ec9c1eb03f052ae232ed54117abed38672c23f6
prerequisite-patch-id: 350db4f4bcdfc0fad9ed57cd5b1723f85ad44f5d
Best regards,
--
Nihal Kumar Gupta <nihal.gupta@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH net-next v5 0/3] airoha: add the capability to configure GDM3/GDM4 as WAN/LAN on demand
From: Simon Horman @ 2026-06-15 8:32 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, linux-arm-kernel, linux-mediatek, netdev,
Madhur Agrawal, Alexander Lobakin
In-Reply-To: <20260611-airoha-ethtool-priv_flags-v5-0-c11de08486d1@kernel.org>
On Thu, Jun 11, 2026 at 11:55:50PM +0200, Lorenzo Bianconi wrote:
> Add the capability to configure GDM3/GDM4 as WAN/LAN on demand when QoS
> offload is created or destroyed.
> Make dev->qdma an RCU pointer so the TX path can safely dereference it
> without holding RTNL.
> Introduce airoha_qdma_start() and airoha_qdma_stop() helpers.
For the series:
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply
* RE: [External Mail] Re: [PATCH v2 3/7] net: wwan: t9xx: Add control DMA interface
From: Wu. JackBB (GSM) @ 2026-06-15 8:31 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Loic Poulain, Sergey Ryazanov, Johannes Berg, Andrew Lunn,
David S. Miller, Eric Dumazet, Paolo Abeni, Wen-Zhi Huang,
Shi-Wei Yeh, Minano Tseng, Matthias Brugger,
AngeloGioacchino Del Regno, Simon Horman, Jonathan Corbet,
Shuah Khan, linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org, linux-doc@vger.kernel.org,
wojackbb@gmail.com
In-Reply-To: <20260613173018.7a0581f1@kernel.org>
Hi Jakub,
Thank you for your comment.
On Wed, 10 Jun 2026 18:41:06 +0800 Jack Wu via B4 Relay wrote:
> Transient build warnings:
>
> +../drivers/net/wwan/t9xx/pcie/mtk_pci_drv_m9xx.c:52:30: warning: symbol 'mtk_dev_cfg_0900' was not declared. Should it be static?
> +../drivers/net/wwan/t9xx/pcie/mtk_ctrl_cfg_m9xx.c:19:22: warning: symbol 'mtk_ctrl_info_m9xx' was not declared. Should it be static?
> +../drivers/net/wwan/t9xx/pcie/mtk_cldma_drv_m9xx.c:33:22: warning: symbol 'mtk_cldma_regs_m9xx' was not declared. Should it be static?
> +../drivers/net/wwan/t9xx/pcie/mtk_cldma_drv_m9xx.c:166:22: warning: symbol 'cldma_drv_ops_m9xx' was not declared. Should it be static?
Will fix in v3. Moved extern declarations into shared headers so each
defining .c file includes its own declaration.
> please also see all the AI code comments at:
> https://sashiko.dev/#/patchset/20260610-t9xx_driver_v1-v2-3-c65addf23b3f@compal.com
Thank you. We have reviewed the AI comments. Below are our
responses for the items under this patch (patch 3):
Q1: Is the reference count for the skb incremented correctly here? If the port
is non-blocking, the caller might immediately drop the reference. Without an
extra reference taken before queueing, the skb could be freed while it still
resides in the queue, resulting in a use-after-free when the worker thread
later accesses the list.
No use-after-free here. The skb is allocated by the port layer
(mtk_port_send_data / mtk_port_common_write) and ownership is
transferred to submit_skb — the caller does not free the skb after
a successful submission. On error returns (-EINVAL, -EIO, -EAGAIN),
the skb is NOT queued and the caller handles cleanup. The skb_queue
operations (skb_queue_head/skb_queue_tail) do not require an extra
reference because the queue becomes the sole owner. This is the
standard kernel pattern — skb ownership transfers to the queue, not
shared between caller and queue.
Q2: Could there be a race condition between setting the virtual address and the
hardware ownership flag? If the worker checks the condition between these two
writes, it might erroneously detect completion and free the buffer before the
transfer even starts.
No race. The tx_done_work checks:
if (!req->data_vm_addr || (gpd_flags & CLDMA_GPD_FLAG_HWO))
break;
It only proceeds when data_vm_addr is set AND HWO is cleared.
In submit_tx, the write order is:
1. req->data_vm_addr = skb->data; (set non-NULL)
2. wmb();
3. gpd_flags |= CLDMA_GPD_FLAG_HWO; (set HWO)
After step 1, data_vm_addr is non-NULL but HWO is set (step 3), so
tx_done_work sees HWO=1 and breaks. It will only process this req
after the hardware clears HWO upon DMA completion. The wmb() ensures
the metadata writes are visible before HWO is set, and the rmb() in
tx_done_work ensures HWO is read before the metadata.
Q3: Does this permanently halt the receive queue if a memory allocation fails
during refill? If the skb allocation fails earlier, the worker exits here
without advancing the free index, which seems to leave the queue stuck
indefinitely on all subsequent executions.
The concern is partially valid. If mtk_cldma_reload_rx_skb() fails
(skb alloc failure), the code jumps to "out" which unmasks the
interrupt. On the next hardware interrupt, rx_done_work runs again
and retries from the same free_idx. If req->skb is NULL (because
reload failed and rx_done set req->skb = NULL after dispatch), the
code hits the "!req->skb" error check and goes to "out" — but "out"
now correctly unmasks the interrupt (fixed in v2), so the next
interrupt will retry. This creates a retry loop that depends on
memory becoming available. Under sustained memory pressure, the RX
queue stalls but recovers once memory is freed. This is acceptable
behavior for a control plane interface with small, infrequent
messages.
Q4: Does this loop safely handle fatal errors from the submission function? It
appears that on errors other than EAGAIN, the loop breaks without unlinking
the skb. The worker loop would then peek the exact same skb on the next
iteration, causing an infinite busy loop that locks up the processor.
The code shown (with kref_put) is from patch 4, not patch 3.
We will fix the issue in patch 4 v3.
Q5: Is a read memory barrier needed after checking the hardware ownership flag?
Without a barrier, the processor might speculatively read the payload length
and data in mtk_cldma_rx_skb_adjust before confirming ownership, leading to
potential data corruption.
The GPD descriptors are allocated from a coherent DMA pool
(dma_pool_zalloc), so CPU cache coherency is guaranteed by the DMA
mapping. A dma_rmb() is not needed here as coherent memory ensures
the CPU always observes the latest values written by the device
without reordering.
Q6: Should the return value of the queue stop function be checked before tearing
down DMA memory? If the hardware fails to stop within the timeout, proceeding
to unmap the memory might result in the active hardware writing to freed
kernel memory.
The concern is valid in theory but not actionable in practice.
cldma_stop_queue() polls the hardware for up to 10 iterations with
usleep. If it times out, the hardware is in a broken state (link
error or device hang). At this point the teardown is part of
device removal or error recovery — there is no safe alternative to
proceeding with cleanup. Skipping the teardown would leak DMA
memory permanently. The synchronize_irq() + flush_work() after
stop_queue ensures no software handlers are in-flight. If the
hardware is truly stuck, the PCIe link is likely already down
(LINK_ERROR_VAL check), making further MMIO access no-ops.
Q7: Does this leak the radix tree nodes and their contents if the array
allocation fails? Performing memory allocations in a teardown path might
permanently leak memory during system memory pressure.
We will fix in v3 by replacing kcalloc +
radix_tree_gang_lookup with radix_tree_for_each_slot() iteration,
eliminating the allocation in the teardown path.
Regarding AI comments for other patches in the series — should we
respond to those under each respective patch thread?
Thanks.
================================================================================================================================================================
This message may contain information which is private, privileged or confidential of Compal Electronics, Inc. If you are not the intended recipient of this message, please notify the sender and destroy/delete the message. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon this information, by persons or entities other than the intended recipient is prohibited.
================================================================================================================================================================
^ permalink raw reply
* Re: [PATCH v1 0/4] trace_hyp_printk() for pKVM/nVHE hypervisor
From: Fuad Tabba @ 2026-06-15 8:30 UTC (permalink / raw)
To: Vincent Donnefort
Cc: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, rostedt, linux-arm-kernel, kvmarm,
kernel-team, qerret
In-Reply-To: <ai-3ii1BtOPP25zZ@google.com>
On Mon, 15 Jun 2026 at 09:28, Vincent Donnefort <vdonnefort@google.com> wrote:
>
> On Sun, Jun 14, 2026 at 01:57:56PM +0100, Fuad Tabba wrote:
> > Hi Vincent,
> >
> > On Fri, 12 Jun 2026 at 15:22, Vincent Donnefort <vdonnefort@google.com> wrote:
> > >
> > > Hi all,
> > >
> > > This series adds a hypervisor event "hyp_printk" which enables
> > > developers to log pretty much anything into the hypervisor tracing
> > > buffer, just like the kernel function trace_printk().
> > >
> > > This enables rich logging from the hypervisor, while leaving all the
> > > string parsing burden to the kernel. This has been the main way of
> > > debugging pKVM in Android.
> >
> > I tested the series on v7.1-rc7 under QEMU (cortex-a53 CPU, pKVM nVHE):
> > - Booted a host under pKVM with a non-protected kvmtool guest (npVM)
> > and a protected kvmtool guest (pVM).
> > - Functional test: added a temporary trace_hyp_printk() call site in
> > handle___kvm_vcpu_run() with 0-arg, 1-arg, and 2-arg calls. Mounted
> > tracefs, enabled the hyp_printk event, ran a kvmtool guest to trigger
> > vcpu_run, read the trace buffer. All expected entries appeared with
> > correctly formatted output.
>
> Thanks for the testing!
>
> >
> > One question: kvm_hyp_trace_init() returns early when
> > is_kernel_in_hyp_mode() is true. On VHE-capable hardware, pKVM uses
> > hVHE. So it seams that the entire hyp tracing subsystem (not just
> > hyp_printk) is non-functional in hVHE mode. Is hVHE support
> > intentionally deferred?
>
> You got me scared for a moment but I did try hVHE and it seems alright:
>
> [ 5.369985] kvm [1]: Protected hVHE mode initialized successfully
>
> $ ls /sys/kernel/tracing/remotes/hypervisor/
>
> is_kernel_in_hyp_mode() just checks if the kernel is running at EL2 which it
> shouldn't in the hVHE case?
I'll try again and report back, must be user error.
/fuad
>
> >
> > Cheers,
> > /fuad
> >
> > >
> > > Even though not strictly related to trace_hyp_printk, I have added the
> > > following two patches:
> > >
> > > * KVM: arm64: Allow early calls to pKVM host_share/unshare_hyp
> > >
> > > This one mainly intends to support one of the new features I have
> > > posted here [1], which allows to enable tracing as early as
> > > possible. I have added it here to limit cross-posting.
> > >
> > > * KVM: arm64: Move kvm_define_hypevents.h to arch/arm64/kvm/
> > >
> > > This one is just a cleanup.
> > >
> > > [1] https://lore.kernel.org/all/20260605163825.1762953-1-vdonnefort@google.com/
> > >
> > > Vincent Donnefort (4):
> > > KVM: arm64: Allow early calls to pKVM host_share/unshare_hyp
> > > KVM: arm64: Move kvm_define_hypevents.h to arch/arm64/kvm/
> > > tracing/remotes: Add REMOTE_EVENT_CUSTOM_PRINTK() helper
> > > KVM: arm64: Add hyp_printk event to nVHE/pKVM hyp
> > >
> > > arch/arm64/include/asm/kvm_asm.h | 4 +-
> > > arch/arm64/include/asm/kvm_hypevents.h | 14 ++++
> > > arch/arm64/include/asm/kvm_hyptrace.h | 8 +++
> > > arch/arm64/kernel/image-vars.h | 1 +
> > > arch/arm64/kernel/vmlinux.lds.S | 4 ++
> > > .../define_hypevents.h} | 0
> > > .../kvm/hyp/include/nvhe/define_events.h | 2 -
> > > arch/arm64/kvm/hyp/include/nvhe/trace.h | 65 +++++++++++++++++++
> > > arch/arm64/kvm/hyp/nvhe/events.c | 6 ++
> > > arch/arm64/kvm/hyp/nvhe/hyp-main.c | 2 +-
> > > arch/arm64/kvm/hyp_trace.c | 60 ++++++++++++++++-
> > > include/trace/define_remote_events.h | 19 +++++-
> > > 12 files changed, 176 insertions(+), 9 deletions(-)
> > > rename arch/arm64/{include/asm/kvm_define_hypevents.h => kvm/define_hypevents.h} (100%)
> > >
> > >
> > > base-commit: 4549871118cf616eecdd2d939f78e3b9e1dddc48
> > > --
> > > 2.54.0.1136.gdb2ca164c4-goog
> > >
^ permalink raw reply
* Re: [PATCH v1 4/4] KVM: arm64: Add hyp_printk event to nVHE/pKVM hyp
From: Vincent Donnefort @ 2026-06-15 8:29 UTC (permalink / raw)
To: Fuad Tabba
Cc: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, rostedt, linux-arm-kernel, kvmarm,
kernel-team, qerret
In-Reply-To: <CA+EHjTwqp=Hjzyn469Gvm-JRNovfnj=0eFB5+Kei_9pRQrnG0Q@mail.gmail.com>
On Sun, Jun 14, 2026 at 04:25:00PM +0100, Fuad Tabba wrote:
> Hi Vincent,
>
> On Fri, 12 Jun 2026 at 15:22, Vincent Donnefort <vdonnefort@google.com> wrote:
> >
> > Create an event to allow developers to log pretty much anything into the
> > hypervisor tracing buffer with trace_hyp_printk(), just like the kernel
> > tracing has the function trace_printk().
> >
> > trace_hyp_printk("foobar");
> > trace_hyp_printk("foo=%d", foo);
> > trace_hyp_printk("foo=%d bar=0x%016llx", foo, bar);
> >
> > To ensure writing into the tracing buffer is fast, store the string
> > format into a kernel-accessible ELF section. The hypervisor only has to
> > write into the event the string ID, which is the delta between the
> > hyp_string_fmt and the start of the ELF section.
> >
> > To not waste tracing buffer data, use a dynamic size. Each
> > argument is 8 bytes and the in-kernel printing function can simply know
> > how many of them there are by looking at the event length.
> >
> > Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
> >
> > diff --git a/arch/arm64/include/asm/kvm_hypevents.h b/arch/arm64/include/asm/kvm_hypevents.h
> > index 743c49bd878f..8465b523cb1d 100644
> > --- a/arch/arm64/include/asm/kvm_hypevents.h
> > +++ b/arch/arm64/include/asm/kvm_hypevents.h
> > @@ -57,4 +57,18 @@ HYP_EVENT(selftest,
> > ),
> > RE_PRINTK("id=%llu", __entry->id)
> > );
> > +
> > +/*
> > + * trace_hyp_printk() has too many specificities to be declared with HYP_EVENT().
> > + * However, we can use a REMOTE_EVENT macro to automatically do the declaration
> > + * for the kernel side.
> > + */
> > +REMOTE_EVENT_CUSTOM_PRINTK(hyp_printk,
> > + 0, /* id will be overwritten during hyp event init */
> > + RE_STRUCT(
> > + re_field(u16, fmt_id)
> > + re_field(u64, args[])
> > + ),
> > + __hyp_trace_printk(evt, seq)
> > +);
> > #endif
> > diff --git a/arch/arm64/include/asm/kvm_hyptrace.h b/arch/arm64/include/asm/kvm_hyptrace.h
> > index de133b735f72..46097105fdd8 100644
> > --- a/arch/arm64/include/asm/kvm_hyptrace.h
> > +++ b/arch/arm64/include/asm/kvm_hyptrace.h
> > @@ -23,4 +23,12 @@ extern struct remote_event __hyp_events_end[];
> > extern struct hyp_event_id __hyp_event_ids_start[];
> > extern struct hyp_event_id __hyp_event_ids_end[];
> >
> > +#define HYP_STRING_FMT_MAX_SIZE 128
> > +
> > +struct hyp_string_fmt {
> > + const char fmt[HYP_STRING_FMT_MAX_SIZE];
> > +};
> > +
> > +extern struct hyp_string_fmt __hyp_string_fmts_start[];
> > +extern struct hyp_string_fmt __hyp_string_fmts_end[];
> > #endif
> > diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
> > index d4c7d45ae6bc..ec03621d7a81 100644
> > --- a/arch/arm64/kernel/image-vars.h
> > +++ b/arch/arm64/kernel/image-vars.h
> > @@ -141,6 +141,7 @@ KVM_NVHE_ALIAS(__hyp_rodata_end);
> > #ifdef CONFIG_NVHE_EL2_TRACING
> > KVM_NVHE_ALIAS(__hyp_event_ids_start);
> > KVM_NVHE_ALIAS(__hyp_event_ids_end);
> > +KVM_NVHE_ALIAS(__hyp_string_fmts_start);
> > #endif
> >
> > /* pKVM static key */
> > diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
> > index e1ac876200a3..b6d62642b6bd 100644
> > --- a/arch/arm64/kernel/vmlinux.lds.S
> > +++ b/arch/arm64/kernel/vmlinux.lds.S
> > @@ -324,6 +324,10 @@ SECTIONS
> > __hyp_events_start = .;
> > *(SORT(_hyp_events.*))
> > __hyp_events_end = .;
> > +
> > + __hyp_string_fmts_start = .;
> > + *(_hyp_string_fmts)
> > + __hyp_string_fmts_end = .;
> > }
> > #endif
> > /*
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/define_events.h b/arch/arm64/kvm/hyp/include/nvhe/define_events.h
> > index 776d4c6cb702..370e8c2d39fe 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/define_events.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/define_events.h
> > @@ -10,5 +10,3 @@
> > #define HYP_EVENT_MULTI_READ
> > #include <asm/kvm_hypevents.h>
> > #undef HYP_EVENT_MULTI_READ
> > -
> > -#undef HYP_EVENT
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/include/nvhe/trace.h
> > index 8813ff250f8e..3d0b5c634bb3 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h
> > @@ -46,6 +46,69 @@ static inline pid_t __tracing_get_vcpu_pid(struct kvm_cpu_context *host_ctxt)
> > void *tracing_reserve_entry(unsigned long length);
> > void tracing_commit_entry(void);
> >
> > +/*
> > + * The trace_hyp_printk boilerplate is too fiddly to be declared with
> > + * HYP_EVENT():
> > + *
> > + * The string format is stored into a kernel-accessible ELF section. The
> > + * hypervisor only writes the format ID.
> > + *
> > + * The function has a variadic prototype. We have no easy way to know each
> > + * argument width so they must all cast to u64.
> > + */
> > +#define REMOTE_EVENT_CUSTOM_PRINTK(...)
> > +
> > +#define __TO_U64_0()
> > +#define __TO_U64_1(x) , (u64)(x)
> > +#define __TO_U64_2(x, ...) , (u64)(x) __TO_U64_1(__VA_ARGS__)
> > +#define __TO_U64_3(x, ...) , (u64)(x) __TO_U64_2(__VA_ARGS__)
> > +#define __TO_U64_4(x, ...) , (u64)(x) __TO_U64_3(__VA_ARGS__)
> > +#define __TO_U64_5(x, ...) , (u64)(x) __TO_U64_4(__VA_ARGS__)
> > +#define __TO_U64_6(x, ...) , (u64)(x) __TO_U64_5(__VA_ARGS__)
> > +#define __TO_U64_7(x, ...) , (u64)(x) __TO_U64_6(__VA_ARGS__)
> > +#define __TO_U64_8(x, ...) , (u64)(x) __TO_U64_7(__VA_ARGS__)
> > +
> > +#define __TO_U64_X(N, ...) CONCATENATE(__TO_U64_, N)(__VA_ARGS__)
> > +#define __TO_U64(...) __TO_U64_X(COUNT_ARGS(__VA_ARGS__), ##__VA_ARGS__)
> > +
> > +REMOTE_EVENT_FORMAT(hyp_printk, HE_STRUCT(he_field(u16, fmt_id) he_field(u64, args[])));
> > +extern struct hyp_event_id hyp_event_id_hyp_printk;
> > +
> > +static __always_inline void __trace_hyp_printk(struct hyp_string_fmt *fmt, int nr_args, ...)
> > +{
> > + struct remote_event_format_hyp_printk *entry;
> > + va_list va;
> > + int i;
> > +
> > + if (!atomic_read(&hyp_event_id_hyp_printk.enabled))
> > + return;
> > +
> > + entry = tracing_reserve_entry(struct_size(entry, args, nr_args));
> > + if (!entry)
> > + return;
> > +
> > + entry->hdr.id = hyp_event_id_hyp_printk.id;
> > + entry->fmt_id = fmt - __hyp_string_fmts_start;
>
> nit: fmt_id is u16, the subtraction is ptrdiff_t. Silent truncation if
> the section ever has more than 65536 entries. Not realistic today, but
> a WARN_ON on the section size in hyp_trace_init_events() would catch
> it at boot for free.
Ack. That wouldn't cost anything. I'll add that in a v2
>
> Reviewed-by: Fuad Tabba <tabba@google.com>
> Tested-by: Fuad Tabba <tabba@google.com>
>
> Cheers,
> /fuad
>
>
> > +
> > + va_start(va, nr_args);
> > + for (i = 0; i < nr_args; i++)
> > + entry->args[i] = va_arg(va, u64);
> > + va_end(va);
> > +
> > + tracing_commit_entry();
> > +}
> > +
> > +
> > +#define trace_hyp_printk(__fmt, __args...) \
> > +do { \
> > + static struct hyp_string_fmt __used __section("_hyp_string_fmts") fmt = { \
> > + .fmt = __fmt \
> > + }; \
> > + BUILD_BUG_ON(sizeof(__fmt) > HYP_STRING_FMT_MAX_SIZE); \
> > + /* __TO_U64 prepends a comma if there are arguments */ \
> > + __trace_hyp_printk(&fmt, COUNT_ARGS(__args) __TO_U64(__args)); \
> > +} while (0)
> > +
> > int __tracing_load(unsigned long desc_va, size_t desc_size);
> > void __tracing_unload(void);
> > int __tracing_enable(bool enable);
> > @@ -58,6 +121,8 @@ static inline void *tracing_reserve_entry(unsigned long length) { return NULL; }
> > static inline void tracing_commit_entry(void) { }
> > #define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \
> > static inline void trace_##__name(__proto) {}
> > +#define REMOTE_EVENT_CUSTOM_PRINTK(...)
> > +#define trace_hyp_printk(fmt, args...) do { } while (0)
> >
> > static inline int __tracing_load(unsigned long desc_va, size_t desc_size) { return -ENODEV; }
> > static inline void __tracing_unload(void) { }
> > diff --git a/arch/arm64/kvm/hyp/nvhe/events.c b/arch/arm64/kvm/hyp/nvhe/events.c
> > index add9383aadb5..12223d2e3618 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/events.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/events.c
> > @@ -9,6 +9,12 @@
> >
> > #include <nvhe/define_events.h>
> >
> > +/*
> > + * The hyp_printk event is not declared with HYP_EVENT in kvm_hypevents.h,
> > + * so we manually add the boilerplate here.
> > + */
> > +HYP_EVENT(hyp_printk, 0, 0, 0, 0);
> > +
> > int __tracing_enable_event(unsigned short id, bool enable)
> > {
> > struct hyp_event_id *event_id = &__hyp_event_ids_start[id];
> > diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c
> > index 821bc93ecdd1..187a8a295d6f 100644
> > --- a/arch/arm64/kvm/hyp_trace.c
> > +++ b/arch/arm64/kvm/hyp_trace.c
> > @@ -391,6 +391,9 @@ static struct trace_remote_callbacks trace_remote_callbacks = {
> >
> > static const char *__hyp_enter_exit_reason_str(u8 reason);
> >
> > +struct remote_event_format_hyp_printk;
> > +static void __hyp_trace_printk(struct remote_event_format_hyp_printk *entry, struct trace_seq *seq);
> > +
> > #include "define_hypevents.h"
> >
> > static const char *__hyp_enter_exit_reason_str(u8 reason)
> > @@ -409,6 +412,61 @@ static const char *__hyp_enter_exit_reason_str(u8 reason)
> > return strs[min(reason, HYP_REASON_UNKNOWN)];
> > }
> >
> > +static void __hyp_trace_printk(struct remote_event_format_hyp_printk *entry, struct trace_seq *seq)
> > +{
> > + const char *fmt = (const char *)(&__hyp_string_fmts_start[entry->fmt_id]);
> > + struct ring_buffer_event *evt = (void *)entry - RB_EVNT_HDR_SIZE;
> > + int nr_args;
> > +
> > + trace_seq_putc(seq, ' ');
> > +
> > + if ((void *)fmt >= (void *)__hyp_string_fmts_end) {
> > + trace_seq_printf(seq, "Unknown hyp_string_fmt ID %d\n", entry->fmt_id);
> > + return;
> > + }
> > +
> > + nr_args = (ring_buffer_event_length(evt) -
> > + offsetof(struct remote_event_format_hyp_printk, args)) / sizeof(entry->args[0]);
> > + switch (nr_args) {
> > + case 0:
> > + trace_seq_printf(seq, fmt);
> > + break;
> > + case 1:
> > + trace_seq_printf(seq, fmt, entry->args[0]);
> > + break;
> > + case 2:
> > + trace_seq_printf(seq, fmt, entry->args[0], entry->args[1]);
> > + break;
> > + case 3:
> > + trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2]);
> > + break;
> > + case 4:
> > + trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2],
> > + entry->args[3]);
> > + break;
> > + case 5:
> > + trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2],
> > + entry->args[3], entry->args[4]);
> > + break;
> > + case 6:
> > + trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2],
> > + entry->args[3], entry->args[4], entry->args[5]);
> > + break;
> > + case 7:
> > + trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2],
> > + entry->args[3], entry->args[4], entry->args[5], entry->args[6]);
> > + break;
> > + default:
> > + trace_seq_printf(seq, fmt, entry->args[0], entry->args[1],
> > + entry->args[2], entry->args[3], entry->args[4], entry->args[5],
> > + entry->args[6], entry->args[7]);
> > + break;
> > + }
> > +
> > + if (seq->buffer[trace_seq_used(seq) - 1] != '\n')
> > + trace_seq_putc(seq, '\n');
> > +}
> > +
> > static void __init hyp_trace_init_events(void)
> > {
> > struct hyp_event_id *hyp_event_id = __hyp_event_ids_start;
> > --
> > 2.54.0.1136.gdb2ca164c4-goog
> >
^ permalink raw reply
* Re: [PATCH v1 0/4] trace_hyp_printk() for pKVM/nVHE hypervisor
From: Vincent Donnefort @ 2026-06-15 8:27 UTC (permalink / raw)
To: Fuad Tabba
Cc: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, rostedt, linux-arm-kernel, kvmarm,
kernel-team, qerret
In-Reply-To: <CA+EHjTxditViT-yd+y-DZ8zM7dATVEpe8qWNGbugq6sL7KN+uw@mail.gmail.com>
On Sun, Jun 14, 2026 at 01:57:56PM +0100, Fuad Tabba wrote:
> Hi Vincent,
>
> On Fri, 12 Jun 2026 at 15:22, Vincent Donnefort <vdonnefort@google.com> wrote:
> >
> > Hi all,
> >
> > This series adds a hypervisor event "hyp_printk" which enables
> > developers to log pretty much anything into the hypervisor tracing
> > buffer, just like the kernel function trace_printk().
> >
> > This enables rich logging from the hypervisor, while leaving all the
> > string parsing burden to the kernel. This has been the main way of
> > debugging pKVM in Android.
>
> I tested the series on v7.1-rc7 under QEMU (cortex-a53 CPU, pKVM nVHE):
> - Booted a host under pKVM with a non-protected kvmtool guest (npVM)
> and a protected kvmtool guest (pVM).
> - Functional test: added a temporary trace_hyp_printk() call site in
> handle___kvm_vcpu_run() with 0-arg, 1-arg, and 2-arg calls. Mounted
> tracefs, enabled the hyp_printk event, ran a kvmtool guest to trigger
> vcpu_run, read the trace buffer. All expected entries appeared with
> correctly formatted output.
Thanks for the testing!
>
> One question: kvm_hyp_trace_init() returns early when
> is_kernel_in_hyp_mode() is true. On VHE-capable hardware, pKVM uses
> hVHE. So it seams that the entire hyp tracing subsystem (not just
> hyp_printk) is non-functional in hVHE mode. Is hVHE support
> intentionally deferred?
You got me scared for a moment but I did try hVHE and it seems alright:
[ 5.369985] kvm [1]: Protected hVHE mode initialized successfully
$ ls /sys/kernel/tracing/remotes/hypervisor/
is_kernel_in_hyp_mode() just checks if the kernel is running at EL2 which it
shouldn't in the hVHE case?
>
> Cheers,
> /fuad
>
> >
> > Even though not strictly related to trace_hyp_printk, I have added the
> > following two patches:
> >
> > * KVM: arm64: Allow early calls to pKVM host_share/unshare_hyp
> >
> > This one mainly intends to support one of the new features I have
> > posted here [1], which allows to enable tracing as early as
> > possible. I have added it here to limit cross-posting.
> >
> > * KVM: arm64: Move kvm_define_hypevents.h to arch/arm64/kvm/
> >
> > This one is just a cleanup.
> >
> > [1] https://lore.kernel.org/all/20260605163825.1762953-1-vdonnefort@google.com/
> >
> > Vincent Donnefort (4):
> > KVM: arm64: Allow early calls to pKVM host_share/unshare_hyp
> > KVM: arm64: Move kvm_define_hypevents.h to arch/arm64/kvm/
> > tracing/remotes: Add REMOTE_EVENT_CUSTOM_PRINTK() helper
> > KVM: arm64: Add hyp_printk event to nVHE/pKVM hyp
> >
> > arch/arm64/include/asm/kvm_asm.h | 4 +-
> > arch/arm64/include/asm/kvm_hypevents.h | 14 ++++
> > arch/arm64/include/asm/kvm_hyptrace.h | 8 +++
> > arch/arm64/kernel/image-vars.h | 1 +
> > arch/arm64/kernel/vmlinux.lds.S | 4 ++
> > .../define_hypevents.h} | 0
> > .../kvm/hyp/include/nvhe/define_events.h | 2 -
> > arch/arm64/kvm/hyp/include/nvhe/trace.h | 65 +++++++++++++++++++
> > arch/arm64/kvm/hyp/nvhe/events.c | 6 ++
> > arch/arm64/kvm/hyp/nvhe/hyp-main.c | 2 +-
> > arch/arm64/kvm/hyp_trace.c | 60 ++++++++++++++++-
> > include/trace/define_remote_events.h | 19 +++++-
> > 12 files changed, 176 insertions(+), 9 deletions(-)
> > rename arch/arm64/{include/asm/kvm_define_hypevents.h => kvm/define_hypevents.h} (100%)
> >
> >
> > base-commit: 4549871118cf616eecdd2d939f78e3b9e1dddc48
> > --
> > 2.54.0.1136.gdb2ca164c4-goog
> >
^ permalink raw reply
* Re: [PATCH v4 2/6] drm/verisilicon: add register-level macros for DC8000
From: Icenowy Zheng @ 2026-06-15 8:24 UTC (permalink / raw)
To: Joey Lu, maarten.lankhorst, mripard, tzimmermann, airlied, simona,
robh, krzk+dt, conor+dt
Cc: ychuang3, schung, yclu4, dri-devel, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260615065003.76661-3-a0987203069@gmail.com>
在 2026-06-15一的 14:49 +0800,Joey Lu写道:
> Add register-level constants needed by the forthcoming DC8000
> (DCUltraLite)
> hardware ops:
>
> VSDC_DISP_IRQ_VSYNC(n) in vs_crtc_regs.h: bit mask for per-output
> VSYNC interrupt bits in DISP_IRQ_STA (0x147C) / DISP_IRQ_EN
> (0x1480),
> which are the IRQ registers used by DCUltraLite in place of the
> DC8200
> TOP_IRQ_ACK / TOP_IRQ_EN registers.
>
> VSDC_FB_CONFIG_ENABLE (bit 0), VSDC_FB_CONFIG_VALID (bit 3) and
> VSDC_FB_CONFIG_RESET (bit 4) in vs_primary_plane_regs.h: control
> bits
> in the FB_CONFIG register used by DCUltraLite for framebuffer
> enable
> and per-frame commit handshake.
Validated against DC8000 register list.
Reviewed-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
>
> No behaviour change for existing DC8200 platforms.
>
> Signed-off-by: Joey Lu <a0987203069@gmail.com>
> ---
> drivers/gpu/drm/verisilicon/vs_crtc_regs.h | 1 +
> drivers/gpu/drm/verisilicon/vs_primary_plane_regs.h | 3 +++
> 2 files changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/verisilicon/vs_crtc_regs.h
> b/drivers/gpu/drm/verisilicon/vs_crtc_regs.h
> index c7930e817635..d4da22b08cd5 100644
> --- a/drivers/gpu/drm/verisilicon/vs_crtc_regs.h
> +++ b/drivers/gpu/drm/verisilicon/vs_crtc_regs.h
> @@ -54,6 +54,7 @@
> #define VSDC_DISP_GAMMA_DATA(n) (0x1460 +
> 0x4 * (n))
>
> #define VSDC_DISP_IRQ_STA 0x147C
> +#define VSDC_DISP_IRQ_VSYNC(n) BIT(n)
>
> #define VSDC_DISP_IRQ_EN 0x1480
>
> diff --git a/drivers/gpu/drm/verisilicon/vs_primary_plane_regs.h
> b/drivers/gpu/drm/verisilicon/vs_primary_plane_regs.h
> index cbb125c46b39..67d4b00f294e 100644
> --- a/drivers/gpu/drm/verisilicon/vs_primary_plane_regs.h
> +++ b/drivers/gpu/drm/verisilicon/vs_primary_plane_regs.h
> @@ -16,6 +16,9 @@
> #define VSDC_FB_STRIDE(n) (0x1408 + 0x4 * (n))
>
> #define VSDC_FB_CONFIG(n) (0x1518 + 0x4 * (n))
> +#define VSDC_FB_CONFIG_ENABLE BIT(0)
> +#define VSDC_FB_CONFIG_VALID BIT(3)
> +#define VSDC_FB_CONFIG_RESET BIT(4)
> #define VSDC_FB_CONFIG_CLEAR_EN BIT(8)
> #define VSDC_FB_CONFIG_ROT_MASK GENMASK(13,
> 11)
> #define VSDC_FB_CONFIG_ROT(v) ((v) << 11)
^ permalink raw reply
* Re: [PATCH v4 1/6] dt-bindings: display: verisilicon, dc: generalize for single-output variants
From: Icenowy Zheng @ 2026-06-15 8:19 UTC (permalink / raw)
To: Joey Lu, maarten.lankhorst, mripard, tzimmermann, airlied, simona,
robh, krzk+dt, conor+dt
Cc: ychuang3, schung, yclu4, dri-devel, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260615065003.76661-2-a0987203069@gmail.com>
在 2026-06-15一的 14:49 +0800,Joey Lu写道:
> The existing schema hard-codes the five-clock/three-reset/dual-port
> topology of the DC8200 IP block, preventing reuse for single-output
> variants such as the Verisilicon DCUltraLite used in the Nuvoton
> MA35D1
> SoC.
>
> Rework the schema so that variant-specific constraints are expressed
> via
> allOf/if blocks:
>
> - Add nuvoton,ma35d1-dcu to the SoC-specific compatible enum. The
> generic verisilicon,dc fallback remains the driver-binding string.
> - Move clock and reset items descriptions into the per-variant
> allOf/if
> blocks; keep only minItems/maxItems at the top level so the base
> schema
> accepts all variants.
> - Restore full items lists for clock-names and reset-names at the top
> level with minItems so the names are validated against the
> descriptions.
> - Keep ports in the global required list and keep
> additionalProperties: false.
> - Add an allOf/if block for thead,th1520-dc8200: five-clock (core,
> axi,
> ahb, pix0, pix1), three-reset (core, axi, ahb), required resets.
> - Add an allOf/if block for nuvoton,ma35d1-dcu: two-clock (core,
> pix0),
> one-reset (core), required resets.
>
> Signed-off-by: Joey Lu <a0987203069@gmail.com>
> ---
> .../bindings/display/verisilicon,dc.yaml | 80
> +++++++++++++++++--
> 1 file changed, 73 insertions(+), 7 deletions(-)
>
> diff --git
> a/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
> b/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
> index 9dc35ab973f2..0c41286b8223 100644
> --- a/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
> +++ b/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
> @@ -17,6 +17,7 @@ properties:
> items:
> - enum:
> - thead,th1520-dc8200
> + - nuvoton,ma35d1-dcu
> - const: verisilicon,dc # DC IPs have discoverable ID/revision
> registers
>
> reg:
> @@ -26,14 +27,12 @@ properties:
> maxItems: 1
>
> clocks:
> - items:
> - - description: DC Core clock
> - - description: DMA AXI bus clock
> - - description: Configuration AHB bus clock
> - - description: Pixel clock of output 0
> - - description: Pixel clock of output 1
Clock descriptions should still be in the global part instead of the
per-compatible part.
In the per-compatible part, clock-names should be constraint for SoCs.
> + minItems: 2
> + maxItems: 5
>
> clock-names:
> + minItems: 2
> + maxItems: 5
> items:
> - const: core
> - const: axi
> @@ -42,12 +41,16 @@ properties:
> - const: pix1
>
> resets:
> + minItems: 1
> + maxItems: 3
> items:
> - description: DC Core reset
> - description: DMA AXI bus reset
> - description: Configuration AHB bus reset
>
> reset-names:
> + minItems: 1
> + maxItems: 3
> items:
> - const: core
> - const: axi
> @@ -59,7 +62,7 @@ properties:
> properties:
> port@0:
> $ref: /schemas/graph.yaml#/properties/port
> - description: The first output channel , endpoint 0 should be
> + description: The first output channel, endpoint 0 should be
If you really want to fix this, please make it a separated patch
instead of doing it here, for commit atomicity.
Thanks,
Icenowy
> used for DPI format output and endpoint 1 should be used
> for DP format output.
>
> @@ -77,6 +80,69 @@ required:
> - clock-names
> - ports
>
> +allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: thead,th1520-dc8200
> + then:
> + properties:
> + clocks:
> + minItems: 5
> + maxItems: 5
> + items:
> + - description: DC Core clock
> + - description: DMA AXI bus clock
> + - description: Configuration AHB bus clock
> + - description: Pixel clock of output 0
> + - description: Pixel clock of output 1
> +
> + clock-names:
> + minItems: 5
> + maxItems: 5
> +
> + resets:
> + minItems: 3
> + maxItems: 3
> +
> + reset-names:
> + minItems: 3
> + maxItems: 3
> +
> + required:
> + - resets
> + - reset-names
> +
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: nuvoton,ma35d1-dcu
> + then:
> + properties:
> + clocks:
> + minItems: 2
> + maxItems: 2
> + items:
> + - description: DC Core clock
> + - description: Pixel clock of output 0
> +
> + clock-names:
> + minItems: 2
> + maxItems: 2
> +
> + resets:
> + minItems: 1
> + maxItems: 1
> +
> + reset-names:
> + maxItems: 1
> +
> + required:
> + - resets
> + - reset-names
> +
> additionalProperties: false
>
> examples:
^ permalink raw reply
* Re: [PATCH 0/3] ARM: dts: stm32: lxa: change stdout-path baud rate from 9600 to 115200
From: Ahmad Fatoum @ 2026-06-15 7:53 UTC (permalink / raw)
To: David Laight
Cc: Alexandre Torgue, Maxime Coquelin, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Leonard Göhrs,
Marc Kleine-Budde, Alexandre Torgue, devicetree, linux-stm32,
linux-arm-kernel, linux-kernel, kernel
In-Reply-To: <20260612075342.6615d66c@pumpkin>
Hello David,
On 6/12/26 8:53 AM, David Laight wrote:
> On Thu, 11 Jun 2026 22:33:18 +0200
> Ahmad Fatoum <a.fatoum@pengutronix.de> wrote:
>
>> Hi David,
>>
>> On 6/11/26 21:43, David Laight wrote:
>>> On Thu, 11 Jun 2026 20:12:32 +0200
>>> Ahmad Fatoum <a.fatoum@pengutronix.de> wrote:
>>>
>>>> The LXA boards are the only STM32 boards that set stdout-path = &uart*
>>>> instead of explicitly specifying a baud rate.
>>>>
>>>> This would mean the default of 9600 is used, but it goes unnoticed when
>>>> booting normally as barebox fixes up a console= line that includes a
>>>> baud rate.
>>>>
>>>> When EFI booting GRUB however, GRUB will not pass along the console=
>>>> line and thus the board ends up with a 9600 baud Linux console,
>>>> confusing users.
>>>
>>> Is it possible to determine the current baud rate (by reading the hardware
>>> register) and default to that value.
>>> Then if grub has initialised the uart the kernel will use the same
>>> baud rate.
>>
>> I think so, yes. In addition to the register divider configuration, one
>> would need the input clock rate as well, but that's not a problem.
>>
>> Do you know if any drivers already do this?
>
> I've seen it done somewhere, certainly x86, but possibly NetBSD.
> That would have been preserving the baud rate set by the bios.
> You don't want the baud rate changing half way through the boot sequence.
I agree in general, but in this case here, the BIOS defaults to 115200:
https://github.com/linux-automation/meta-lxatac/blob/wrynose/meta-lxatac-bsp/recipes-bsp/barebox/files/lxatac/defconfig#L171
https://elixir.bootlin.com/barebox/v2026.06.0/source/common/console.c#L349
Cheers,
Ahmad
>
> David
>
>>
>> Nevertheless, I would like the LXA device trees changed, even if only
>> to align them with all other existing STM32 device trees.
>>
>> Cheers,
>> Ahmad
>>
>>
>>>
>>> David
>>>
>>>>
>>>> This series fixes this. As the device trees were added at different
>>>> times, they are fixed each in a separate commit with its own Fixes: tag.
>>>>
>>>> ---
>>>> Ahmad Fatoum (3):
>>>> ARM: dts: stm32: lxa-mc1: change stdout-path baud rate from 9600 to 115200
>>>> ARM: dts: stm32: lxa-tac: change stdout-path baud rate from 9600 to 115200
>>>> ARM: dts: stm32: fairytux2: change stdout-path baud rate from 9600 to 115200
>>>>
>>>> arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi | 2 +-
>>>> arch/arm/boot/dts/st/stm32mp157c-lxa-mc1.dts | 2 +-
>>>> arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi | 2 +-
>>>> 3 files changed, 3 insertions(+), 3 deletions(-)
>>>> ---
>>>> base-commit: 4549871118cf616eecdd2d939f78e3b9e1dddc48
>>>> change-id: 20260611-lxa-stdout-path-baudrate-7cf454cdae07
>>>>
>>>> Best regards,
>>>> --
>>>> Ahmad Fatoum <a.fatoum@pengutronix.de>
>>>>
>>>>
>>>
>>>
>>
>>
>
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH v3 02/24] firmware: arm_scmi: Reduce the scope of protocols mutex
From: Cristian Marussi @ 2026-06-15 7:48 UTC (permalink / raw)
To: Usama Arif
Cc: Cristian Marussi, linux-kernel, linux-arm-kernel, arm-scmi,
linux-fsdevel, linux-doc, sudeep.holla, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
dan.carpenter, d-gole, jonathan.cameron, elif.topuz, lukasz.luba,
philip.radford, brauner, souvik.chakravarty
In-Reply-To: <20260612101525.340337-1-usama.arif@linux.dev>
On Fri, Jun 12, 2026 at 03:15:24AM -0700, Usama Arif wrote:
> On Sun, 29 Mar 2026 17:33:13 +0100 Cristian Marussi <cristian.marussi@arm.com> wrote:
>
> > Currently the mutex dedicated to the protection of the list of registered
> > protocols is held during all the protocol initialization phase.
> >
> > Such a wide locking region is not needed and causes problem when trying to
> > initialize notifications from within a protocol initialization routine.
> >
> > Reduce the scope of the protocol mutex.
>
> I think this changes more than the mutex scope. scmi_get_protocol_instance()
> can now drop protocols_mtx after idr_find() while scmi_protocol_release()
> can concurrently drop the final reference, remove the IDR entry, and release
> the devres group. Does that leaves a use-after-free window around the returned
> pi?
>
I have to review this mechanism in general in V5 so I will get back to
you on this once I have refreshed my memory on this own code of mine :P
Thanks,
Cristian
^ permalink raw reply
* Re: [PATCH v3 01/24] firmware: arm_scmi: Add new SCMIv4.0 error codes definitions
From: Cristian Marussi @ 2026-06-15 7:44 UTC (permalink / raw)
To: Usama Arif
Cc: Cristian Marussi, linux-kernel, linux-arm-kernel, arm-scmi,
linux-fsdevel, linux-doc, sudeep.holla, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
dan.carpenter, d-gole, jonathan.cameron, elif.topuz, lukasz.luba,
philip.radford, brauner, souvik.chakravarty
In-Reply-To: <20260612101100.186627-1-usama.arif@linux.dev>
On Fri, Jun 12, 2026 at 03:10:59AM -0700, Usama Arif wrote:
> On Sun, 29 Mar 2026 17:33:12 +0100 Cristian Marussi <cristian.marussi@arm.com> wrote:
>
Hi Usama,
Thanks for having a look at this first of all !
I was busy posting a V4 before merge window last week so this late
reply....
I am already planning a V5 in -rc1 in two weeks where beside some more
minor ABI additions I will plan to address any incoming reviews and
some residual minor issues I know about (mostly sparse related)
...but you are CCed already in V4...
> > SCMIv4.0 introduces a couple of new possible protocol error codes: add
> > the needed definitions and mappings to Linux error values.
> >
> > Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
> > ---
> > drivers/firmware/arm_scmi/common.h | 4 ++++
> > 1 file changed, 4 insertions(+)
> >
> > diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
> > index 7c35c95fddba..44af2018e21d 100644
> > --- a/drivers/firmware/arm_scmi/common.h
> > +++ b/drivers/firmware/arm_scmi/common.h
> > @@ -45,6 +45,8 @@ enum scmi_error_codes {
> > SCMI_ERR_GENERIC = -8, /* Generic Error */
> > SCMI_ERR_HARDWARE = -9, /* Hardware Error */
> > SCMI_ERR_PROTOCOL = -10,/* Protocol Error */
> > + SCMI_ERR_IN_USE = -11, /* In Use Error */
> > + SCMI_ERR_PARTIAL = -12, /* Partial Error */
> > };
> >
> > static const int scmi_linux_errmap[] = {
> > @@ -60,6 +62,8 @@ static const int scmi_linux_errmap[] = {
> > -EIO, /* SCMI_ERR_GENERIC */
> > -EREMOTEIO, /* SCMI_ERR_HARDWARE */
> > -EPROTO, /* SCMI_ERR_PROTOCOL */
> > + -EPERM, /* SCMI_ERR_IN_USE */
>
> "In use" reads like a resource-state failure, where -EBUSY would normally be expected.
> -EPERM suggests an authorization failure, which is already represented by SCMI_ERR_ACCESS.
>
The usage of this in Telemetry is indeed a resource state failure that relates to groups usage
and it means something like "this is busy now, so you cannot do that now with this current config"
...but you are definitely right that -EPERM does NOT fit well here and especially is NOT what IN_USE
should signify in general in SCMI as a return code for future users.
I will fix in V5.
Thanks,
Cristian
^ permalink raw reply
* Re: [PATCH v2 0/7] KVM: arm64: Forward FFA_NOTIFICATION* calls to TrustZone
From: Sebastian Ene @ 2026-06-15 7:43 UTC (permalink / raw)
To: Will Deacon
Cc: Vincent Donnefort, catalin.marinas, maz, oupton, joey.gouly,
korneld, kvmarm, linux-arm-kernel, linux-kernel, android-kvm,
mrigendra.chaubey, perlarsen, suzuki.poulose, yuzenghui
In-Reply-To: <ai50fgNHGUqz0muP@willie-the-truck>
On Sun, Jun 14, 2026 at 10:29:34AM +0100, Will Deacon wrote:
> On Wed, Jun 10, 2026 at 02:56:24PM +0100, Vincent Donnefort wrote:
> > On Wed, Jun 10, 2026 at 01:23:04PM +0100, Will Deacon wrote:
> > > On Wed, Jun 10, 2026 at 01:15:44PM +0100, Vincent Donnefort wrote:
> > > > On Wed, Jun 10, 2026 at 11:15:14AM +0100, Will Deacon wrote:
> > > > > On Wed, Jun 10, 2026 at 10:26:59AM +0100, Vincent Donnefort wrote:
> > > > > > On Mon, Jun 08, 2026 at 04:55:42PM +0000, Sebastian Ene wrote:
> > > > > > > Remove the FFA_NOTIFICATION* calls from the blocklist used by the pKVM
> > > > > > > FF-A proxy. This restriction was preventing the use of asynchronous
> > > > > > > signaling mechanisms defined by the Arm FF-A specification to
> > > > > > > communicate with the secure services.
> > > > > > > While these calls are markes as optional, there is no reason why the
> > > > > > > hypervisor proxy would block them because:
> > > > > > >
> > > > > > > 1. Host is the Sole Non-Secure Endpoint: The Host operates as the
> > > > > > > only Non-Secure VM ID (VM ID 0) recognized by the Secure World.
> > > > > > > Because all forwarded notifications are inherently attributed to
> > > > > > > the Host by the SPMC, there is no risk of VM ID spoofing
> > > > > > > originating from the Normal World.
> > > > > > >
> > > > > > > 2. No Memory Pointers or Addresses: The FFA_NOTIFICATION_* ABIs
> > > > > > > operate strictly via register-based parameters, passing only
> > > > > > > VM IDs, VCPU IDs, flags, and bitmaps. Because these calls do
> > > > > > > not contain memory addresses, offsets, or pointers, forwarding
> > > > > > > them doesn't pose a risk of memory-based confused deputy attack
> > > > > > > (e.g., tricking the SPMC into overwriting protected memory).
> > > > > > >
> > > > > > > While the pKVM proxy behaves as a relayer, it doesn't currently have its
> > > > > > > own FF-A ID(only the host has the ID 0). The behavior of the setup
> > > > > > > flow is covered by the spec in the: '10.9 Notification support without
> > > > > > > a Hypervisor'.
> > > > > >
> > > > > > As it is only a relayer. Is it really important to check SBZ arguments and
> > > > > > fields on behalf of Trustzone? It doesn't feel it brings any security. If the
> > > > > > host passes broken arguments, I don't believe this puts pKVM at risk. Does it?
> > > > >
> > > > > I think the problem would be if an update to FF-A allocated some of the
> > > > > currently SBZ bits to implement some functionality that we would want
> > > > > to filter at EL2.
> > > >
> > > > I suppose that would bump the FF-A version and the proxy would reject it?
> > >
> > > Maybe? I don't think they'd _have_ to bump the version number.
> > >
> > > > If we really want to check for those arguments to be 0:
> > > >
> > > > * Shouldn't we extend this check to other FF-A invocations?
> > >
> > > yes, that's what the diff was doing in the reply here:
> > >
> > > https://lore.kernel.org/all/af3fW468-f1KXCrC@google.com/
> > >
> > > but, as I said here:
> > >
> > > https://lore.kernel.org/all/ahmxiFXXTupafbXw@willie-the-truck/
> > >
> > > I don't particularly like the table-driven indirection (the checks
> > > should just be inlined).
> >
> > Ha, sorry I'm late to the party.
> >
> > Perhaps this series should start with adding ffa_check_unused_args_sbz() to the
> > existing allowed FF-A invocations?
Hi Will,
>
> Yes, that part now seems to be missing.
I am a bit worried to apply for all of them the check from the relayer
(ffa_check_unused_args_sbz) because of how it's written in the spec in
(11.2 Reserved parameter convention). To be more specific, there is no
mention of what the relayer is expected to do here (which is what hyp
does). It says 2 things:
1. the caller (in this case the host driver) is expected to zero out
unused args
2. the callee (Trustzone) ignores the values in these registers.
If we enforce SBZ in the relayer but (1) doesn't comply with it, we will
introduce a regression. I left it on purpose without enforcing
ffa_check_unused_args_sbz for the others.
>
> Seb, please can you respin with that included?
>
> Will
Thanks,
Sebastian
^ permalink raw reply
* Re: [PATCH v12 07/15] atomic: Add atomic_cond_read_*_timeout()
From: Ankur Arora @ 2026-06-15 7:41 UTC (permalink / raw)
To: linux-kernel, linux-arch, linux-arm-kernel, linux-pm, bpf
Cc: Ankur Arora, bpf, arnd, catalin.marinas, will, peterz, akpm,
mark.rutland, harisokn, cl, ast, rafael, daniel.lezcano, memxor,
zhenglifeng1, xueshuai, rdunlap, david.laight.linux, broonie,
joao.m.martins, boris.ostrovsky, konrad.wilk, ashok.bhat,
Ankur Arora, Boqun Feng, sashiko-bot
In-Reply-To: <20260608082304.ADEA61F00893@smtp.kernel.org>
sashiko-bot@kernel.org writes:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [High] The `atomic64_cond_read_acquire_timeout` and `atomic64_cond_read_relaxed_timeout` macros can cause torn reads and synchronization failures on 32-bit architectures.
> --
>
> commit aafb3af0335d368d82aaca86bf6b2a18f8ae6033
> Author: Ankur Arora <ankur.a.arora@oracle.com>
>
> atomic: Add atomic_cond_read_*_timeout()
>
> Add atomic load wrappers, atomic_cond_read_*_timeout() and
> atomic64_cond_read_*_timeout() for the cond-load timeout interfaces. Also
> add a short description for the interfaces.
>
>> diff --git a/include/linux/atomic.h b/include/linux/atomic.h
>> index 8dd57c3a99e9b..5bcb86e077845 100644
>> --- a/include/linux/atomic.h
>> +++ b/include/linux/atomic.h
>
> [ ... ]
>
>> @@ -31,6 +31,16 @@
>> #define atomic64_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c))
>> #define atomic64_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c))
>>
>> +#define atomic_cond_read_acquire_timeout(v, c, e, t) \
>> + smp_cond_load_acquire_timeout(&(v)->counter, (c), (e), (t))
>> +#define atomic_cond_read_relaxed_timeout(v, c, e, t) \
>> + smp_cond_load_relaxed_timeout(&(v)->counter, (c), (e), (t))
>> +
>> +#define atomic64_cond_read_acquire_timeout(v, c, e, t) \
>> + smp_cond_load_acquire_timeout(&(v)->counter, (c), (e), (t))
>> +#define atomic64_cond_read_relaxed_timeout(v, c, e, t) \
>> + smp_cond_load_relaxed_timeout(&(v)->counter, (c), (e), (t))
>
> [Severity: High]
> Will this cause torn reads and synchronization failures on 32-bit
> architectures?
>
> On 32-bit platforms, atomic64_t operations typically rely on spinlocks or
> specific instructions to prevent tearing. These new macros bypass the
> architecture-specific atomic64_read() and directly use
> smp_cond_load_acquire_timeout() and smp_cond_load_relaxed_timeout() on the
> counter member.
>
> These macros poll using a lockless READ_ONCE(). On 32-bit systems, a 64-bit
> READ_ONCE() compiles into two separate 32-bit memory loads. If concurrent
> writers modify the counter via spinlocked atomic64 operations, the lockless
> polling loop could observe torn (partially updated) reads.
So, yes 32bit would run into torn reads but it shouldn't really be using
atomic64_cond_* interfaces.
Those interfaces are typically used via atomic_long_cond -- which should
be using atomic64_cond_* only if CONFIG_64BIT is defined.
Ankur
> If a torn read spuriously satisfies the polling condition, the loop might exit
> prematurely with a corrupt value.
^ permalink raw reply
* Re: [PATCH v12 06/15] asm-generic: barrier: Add smp_cond_load_acquire_timeout()
From: Ankur Arora @ 2026-06-15 7:32 UTC (permalink / raw)
To: linux-kernel, linux-arch, linux-arm-kernel, linux-pm, bpf
Cc: arnd, catalin.marinas, will, peterz, akpm, mark.rutland, harisokn,
cl, ast, rafael, daniel.lezcano, memxor, zhenglifeng1, xueshuai,
rdunlap, david.laight.linux, broonie, joao.m.martins,
boris.ostrovsky, konrad.wilk, ashok.bhat, sashiko-bot
In-Reply-To: <20260608082746.399BB1F00898@smtp.kernel.org>
sashiko-bot@kernel.org writes:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [High] ACQUIRE semantics violation in `smp_cond_load_acquire_timeout()` on weakly-ordered architectures.
> --
>
> commit 0c67207964772b92d28f5af7e4a97ea44a103e9b
> Author: Ankur Arora <ankur.a.arora@oracle.com>
>
> asm-generic: barrier: Add smp_cond_load_acquire_timeout()
>
> This commit adds the acquire variant of smp_cond_load_relaxed_timeout().
> It attempts to provide acquire ordering by reusing the relaxed variant and
> adding a control dependency combined with smp_acquire__after_ctrl_dep().
>
>> diff --git a/include/asm-generic/barrier.h b/include/asm-generic/barrier.h
>> index c56df9513a084..0ab26e98842c0 100644
>> --- a/include/asm-generic/barrier.h
>> +++ b/include/asm-generic/barrier.h
>
> [ ... ]
>
>> +/**
>> + * smp_cond_load_acquire_timeout() - (Spin) wait for cond with ACQUIRE ordering
>> + * until a timeout expires.
>> + * @ptr: pointer to the variable to wait on.
>> + * @cond_expr: boolean expression to wait for.
>> + * @time_expr_ns: monotonic expression that evaluates to time in ns or,
>> + * on failure, returns a negative value.
>> + * @timeout_ns: timeout value in ns
>> + * (Both of the above are assumed to be compatible with s64.)
>> + *
>> + * Equivalent to using smp_cond_load_acquire() on the condition variable with
>> + * a timeout.
>> + */
>> +#ifndef smp_cond_load_acquire_timeout
>> +#define smp_cond_load_acquire_timeout(ptr, cond_expr, \
>> + time_expr_ns, timeout_ns) \
>> +({ \
>> + __unqual_scalar_typeof(*(ptr)) VAL; \
>> + VAL = smp_cond_load_relaxed_timeout(ptr, cond_expr, \
>> + time_expr_ns, \
>> + timeout_ns); \
>> + if (cond_expr) \
>> + barrier(); \
>> + smp_acquire__after_ctrl_dep(); \
>
> [Severity: High]
> Does this sequence correctly establish a control dependency for the caller's
> subsequent instructions?
>
> According to Documentation/memory-barriers.txt, control dependencies only
> apply to stores executed strictly within the conditional clauses (the true
> or false branches), not to code following the if statement. Since the
> caller's subsequent stores reside outside this conditional block, they
> appear unconditional to the CPU.
Yes, this is a problem. One way to fix this would be to add a full
acquire barrier in the failure path:
VAL = smp_cond_load_relaxed_timeout(ptr, cond_expr,
time_expr_ns,
timeout_ns);
if (!cond_expr)
VAL = smp_load_acquire();
else
smp_acquire__after_ctrl_dep();
(typeof(*(ptr)))VAL;
However, this seems like overkill since there are likely few situations
where we need an acquire barrier on the failure path.
AFAICT rqspinlock doesn't seem to need one.
Unless someone has an objection that's what I plan to do.
Ankur
> Furthermore, smp_acquire__after_ctrl_dep() typically falls back to
> smp_rmb(). On weakly-ordered architectures like RISC-V, where smp_rmb() is
> implemented as "fence r, r" and only enforces load-to-load ordering, could
> the CPU speculatively execute subsequent stores before the final load of VAL
> completes?
>
> Could this violate the expected acquire semantics if the caller relies on
> the barrier in the timeout or failure path?
>
>> + (typeof(*(ptr)))VAL; \
>> +})
>> +#endif
--
ankur
^ permalink raw reply
* Re: [PATCH v3 0/6] Add CAMSS and IMX577 sensor support for Shikra EVK
From: Nihal Kumar Gupta @ 2026-06-15 7:27 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma,
Krzysztof Kozlowski
In-Reply-To: <20260615-shikra-camss-review-v3-0-8183481f48d0@oss.qualcomm.com>
On 15-06-2026 12:42, Nihal Kumar Gupta wrote:
> - Add blank line between iommus and power-domains in CAMSS node (Vladimir)
> - Fix data-lanes numbering to start from 1 in all endpoints (Vladimir)
> - Move cam1_reset_default pinctrl state from board .dts files into the
> mezzanine .dtso overlay files (Vladimir)
> - Collect Reviewed-by tags
> - Link to v2: https://lore.kernel.org/r/20260608-shikra-camss-review-v2-0-ca1936bf1219@oss.qualcomm.com
Hi Vladimir,
Apologies, I had tested the changes with data-lanes = <1 2 3 4>
but mistakenly removed them before sending. Will fix and send v4.
I've incorporated other comments.
--
Regards,
Nihal Kumar Gupta
^ permalink raw reply
* Re: [PATCH] net: ethtool: mm: Increase FPE verification retry count
From: Nazle Asmade, Muhammad Nazim Amirul @ 2026-06-15 7:26 UTC (permalink / raw)
To: Jakub Kicinski
Cc: netdev@vger.kernel.org, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@google.com, pabeni@redhat.com,
mcoquelin.stm32@gmail.com, alexandre.torgue@foss.st.com,
rmk+kernel@armlinux.org.uk, maxime.chevallier@bootlin.com,
linux-stm32@st-md-mailman.stormreply.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20260609171750.7c5709ac@kernel.org>
On 10/6/2026 8:17 am, Jakub Kicinski wrote:
> On Thu, 4 Jun 2026 19:56:31 -0700
> muhammad.nazim.amirul.nazle.asmade@altera.com wrote:
>> The current FPE verification retry count is set to 3. However,
>> the IEEE 802.3br standard does not specify a fixed value for this.
>> A retry count of 3 may be insufficient when the remote device is
>> slow to respond during link-up. Increase the retry count to 20 to
>> improve robustness.
>
> You need to CC the author / expert on this code, please repost
> with the CC fixed.
Reposted, Thanks Jackub!
https://lore.kernel.org/all/20260615072436.26128-1-muhammad.nazim.amirul.nazle.asmade@altera.com/
^ permalink raw reply
* [PATCH v7 9/9] arm64: dts: mediatek: Add MediaTek MT6392 PMIC dtsi
From: Luca Leonardo Scorcia @ 2026-06-15 7:16 UTC (permalink / raw)
To: linux-mediatek
Cc: Val Packett, Luca Leonardo Scorcia, Dmitry Torokhov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sen Chu, Sean Wang,
Macpaul Lin, Lee Jones, Matthias Brugger,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown,
Linus Walleij, Louis-Alexis Eyraud, Julien Massot, Fabien Parent,
Akari Tsuyukusa, Chen Zhong, linux-input, devicetree,
linux-kernel, linux-pm, linux-arm-kernel, linux-gpio
In-Reply-To: <20260615071836.362883-1-l.scorcia@gmail.com>
From: Val Packett <val@packett.cool>
Add the dts to be included by all boards using the MT6392 PMIC,
providing support for regulator, keys, pinctrl and RTC.
Signed-off-by: Val Packett <val@packett.cool>
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
---
arch/arm64/boot/dts/mediatek/mt6392.dtsi | 75 ++++++++++++++++++++++++
1 file changed, 75 insertions(+)
create mode 100644 arch/arm64/boot/dts/mediatek/mt6392.dtsi
diff --git a/arch/arm64/boot/dts/mediatek/mt6392.dtsi b/arch/arm64/boot/dts/mediatek/mt6392.dtsi
new file mode 100644
index 000000000000..81f15d76a05a
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt6392.dtsi
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Copyright (c) 2024 Val Packett <val@packett.cool>
+ * Copyright (c) 2026 Luca Leonardo Scorcia <l.scorcia@gmail.com>
+ */
+
+#include <dt-bindings/input/input.h>
+
+&pwrap {
+ pmic: pmic {
+ compatible = "mediatek,mt6392", "mediatek,mt6323";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ mt6392keys: keys {
+ compatible = "mediatek,mt6392-keys";
+
+ key-power {
+ linux,keycodes = <KEY_POWER>;
+ wakeup-source;
+ };
+
+ key-home {
+ linux,keycodes = <KEY_HOME>;
+ wakeup-source;
+ };
+ };
+
+ mt6392pio: pinctrl {
+ compatible = "mediatek,mt6392-pinctrl";
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ mt6392rtc: rtc {
+ compatible = "mediatek,mt6392-rtc", "mediatek,mt6323-rtc";
+ };
+
+ mt6392regulators: regulators {
+ compatible = "mediatek,mt6392-regulator";
+
+ /* Fixed supply defined in the data sheet */
+ avddldo-supply = <&mt6392_vsys_reg>;
+
+ mt6392_vcore_reg: vcore { };
+ mt6392_vproc_reg: vproc { };
+ mt6392_vsys_reg: vsys { };
+ mt6392_vaud28_reg: vaud28 { };
+ mt6392_vxo22_reg: vxo22 { };
+ mt6392_vaud22_reg: vaud22 { };
+ mt6392_vadc18_reg: vadc18 { };
+ mt6392_vcama_reg: vcama { };
+ mt6392_vcn35_reg: vcn35 { };
+ mt6392_vio28_reg: vio28 { };
+ mt6392_vusb_reg: vusb { };
+ mt6392_vmc_reg: vmc { };
+ mt6392_vmch_reg: vmch { };
+ mt6392_vemc3v3_reg: vemc3v3 { };
+ mt6392_vcamaf_reg: vcamaf { };
+ mt6392_vgp1_reg: vgp1 { };
+ mt6392_vgp2_reg: vgp2 { };
+ mt6392_vefuse_reg: vefuse { };
+ mt6392_vm25_reg: vm25 { };
+ mt6392_vdig18_reg: vdig18 { };
+ mt6392_vm_reg: vm { };
+ mt6392_vio18_reg: vio18 { };
+ mt6392_vcn18_reg: vcn18 { };
+ mt6392_vcamd_reg: vcamd { };
+ mt6392_vcamio_reg: vcamio { };
+ mt6392_vrtc_reg: vrtc { };
+ };
+ };
+};
--
2.43.0
^ permalink raw reply related
* [PATCH v7 8/9] regulator: Add MediaTek MT6392 regulator
From: Luca Leonardo Scorcia @ 2026-06-15 7:16 UTC (permalink / raw)
To: linux-mediatek
Cc: Fabien Parent, Val Packett, Luca Leonardo Scorcia,
Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sen Chu, Sean Wang, Macpaul Lin, Lee Jones, Matthias Brugger,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown,
Linus Walleij, Louis-Alexis Eyraud, Julien Massot,
Akari Tsuyukusa, Chen Zhong, linux-input, devicetree,
linux-kernel, linux-pm, linux-arm-kernel, linux-gpio
In-Reply-To: <20260615071836.362883-1-l.scorcia@gmail.com>
From: Fabien Parent <parent.f@gmail.com>
The MT6392 is a regulator found on boards based on the MediaTek
MT8167, MT8516, and probably other SoCs. It is a so called PMIC and
connects as a slave to a SoC using SPI, wrapped inside PWRAP.
Signed-off-by: Fabien Parent <parent.f@gmail.com>
Co-developed-by: Val Packett <val@packett.cool>
Signed-off-by: Val Packett <val@packett.cool>
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
---
drivers/regulator/Kconfig | 9 +
drivers/regulator/Makefile | 1 +
drivers/regulator/mt6392-regulator.c | 756 +++++++++++++++++++++
include/linux/regulator/mt6392-regulator.h | 42 ++
4 files changed, 808 insertions(+)
create mode 100644 drivers/regulator/mt6392-regulator.c
create mode 100644 include/linux/regulator/mt6392-regulator.h
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index a54a549196fe..ae375b9e6391 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1001,6 +1001,15 @@ config REGULATOR_MT6380
This driver supports the control of different power rails of device
through regulator interface.
+config REGULATOR_MT6392
+ tristate "MediaTek MT6392 PMIC"
+ depends on MFD_MT6397
+ help
+ Say y here to select this option to enable the power regulator of
+ MediaTek MT6392 PMIC.
+ This driver supports the control of different power rails of device
+ through regulator interface.
+
config REGULATOR_MT6397
tristate "MediaTek MT6397 PMIC"
depends on MFD_MT6397
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 134eee274dbf..a8e795a1eda1 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -118,6 +118,7 @@ obj-$(CONFIG_REGULATOR_MT6360) += mt6360-regulator.o
obj-$(CONFIG_REGULATOR_MT6363) += mt6363-regulator.o
obj-$(CONFIG_REGULATOR_MT6370) += mt6370-regulator.o
obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
+obj-$(CONFIG_REGULATOR_MT6392) += mt6392-regulator.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
obj-$(CONFIG_REGULATOR_MTK_DVFSRC) += mtk-dvfsrc-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_LABIBB) += qcom-labibb-regulator.o
diff --git a/drivers/regulator/mt6392-regulator.c b/drivers/regulator/mt6392-regulator.c
new file mode 100644
index 000000000000..1f91aac3917a
--- /dev/null
+++ b/drivers/regulator/mt6392-regulator.c
@@ -0,0 +1,756 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ * Copyright (c) 2020 BayLibre, SAS.
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ * Author: Fabien Parent <fparent@baylibre.com>
+ * Author: Luca Leonardo Scorcia <l.scorcia@gmail.com>
+ *
+ * The data sheet for MT6392 regulators is spotty to say the least,
+ * many important registers/fields are missing and the ones that aren't
+ * lack crucial information. Some useful details have been retrieved from
+ * Android sources.
+ * The driver code is mostly based on the MT6397 one.
+ */
+
+#include <linux/module.h>
+#include <linux/linear_range.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/mt6397/core.h>
+#include <linux/mfd/mt6392/registers.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/mt6392-regulator.h>
+#include <linux/regulator/of_regulator.h>
+
+/*
+ * Buck mode constants which may be used in devicetree properties (eg.
+ * regulator-initial-mode, regulator-allowed-modes).
+ * See the manufacturer's datasheet for more information on these modes.
+ */
+#define MT6392_BUCK_MODE_AUTO 0
+#define MT6392_BUCK_MODE_FORCE_PWM 1
+
+/*
+ * LDO mode constants which may be used in devicetree properties (eg.
+ * regulator-initial-mode, regulator-allowed-modes).
+ * See the manufacturer's datasheet for more information on these modes.
+ */
+#define MT6392_LDO_MODE_NORMAL 0
+#define MT6392_LDO_MODE_LP 1
+
+/**
+ * MT6392 regulators' information
+ *
+ * @desc: standard fields of regulator description.
+ * @qi_status_reg: Register to query enable signal status of regulators
+ * @qi_status_mask: Mask to query enable signal status of regulators (RO)
+ * @vselctrl_reg: Vsel control mode selector register
+ * @vselctrl_mask: Vsel control mode selector mask (RO)
+ * @vsel_reg_mode_reg: Vsel register when Vsel control mode selector = 0 (Register mode)
+ * @vsel_reg_mode_mask: Vsel register mask in Register mode (RW)
+ * @vsel_normal_mode_reg: Vsel register when Vsel control mode selector = 1 (Normal mode)
+ * @vsel_normal_mode_mask: Vsel register mask in Register mode (RW)
+ * @pwm_modeset_reg: Register to control buck mode (Auto/Force PWM)
+ * @pwm_modeset_mask: Mask to control buck mode (RW)
+ * @lp_modeget_reg: Register to get LDO low-power mode
+ * @lp_modeget_mask: Mask to get LDO low-power mode (RO)
+ * @lp_modeset_reg: Register to control LDO low-power mode
+ * @lp_modeset_mask: Mask to control LDO low-power mode (WO)
+ */
+struct mt6392_regulator_info {
+ struct regulator_desc desc;
+ u32 qi_status_reg;
+ u32 qi_status_mask;
+ u32 vselctrl_reg;
+ u32 vselctrl_mask;
+ u32 vsel_reg_mode_reg;
+ u32 vsel_reg_mode_mask;
+ u32 vsel_normal_mode_reg;
+ u32 vsel_normal_mode_mask;
+ u32 pwm_modeset_reg;
+ u32 pwm_modeset_mask;
+ u32 lp_modeget_reg;
+ u32 lp_modeget_mask;
+ u32 lp_modeset_reg;
+ u32 lp_modeset_mask;
+};
+
+#define MT6392_BUCK(match, vreg, supply, min, max, step, volt_ranges, \
+ _qi_status_reg, _qi_status_mask, _enable_reg, _enable_mask, \
+ _vselctrl_reg, _vselctrl_mask, \
+ _vsel_reg_mode_reg, _vsel_reg_mode_mask, \
+ _vsel_normal_mode_reg, _vsel_normal_mode_mask, \
+ _pwm_modeset_reg, _pwm_modeset_mask, _ramp_delay) \
+[MT6392_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .supply_name = supply, \
+ .of_match = of_match_ptr(match), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .ops = &mt6392_volt_range_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6392_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = ((max) - (min)) / (step) + 1, \
+ .linear_ranges = volt_ranges, \
+ .n_linear_ranges = ARRAY_SIZE(volt_ranges), \
+ .enable_reg = _enable_reg, \
+ .enable_mask = _enable_mask, \
+ .ramp_delay = _ramp_delay, \
+ }, \
+ .qi_status_reg = _qi_status_reg, \
+ .qi_status_mask = _qi_status_mask, \
+ .vselctrl_reg = _vselctrl_reg, \
+ .vselctrl_mask = _vselctrl_mask, \
+ .vsel_reg_mode_reg = _vsel_reg_mode_reg, \
+ .vsel_reg_mode_mask = _vsel_reg_mode_mask, \
+ .vsel_normal_mode_reg = _vsel_normal_mode_reg, \
+ .vsel_normal_mode_mask = _vsel_normal_mode_mask, \
+ .pwm_modeset_reg = _pwm_modeset_reg, \
+ .pwm_modeset_mask = _pwm_modeset_mask, \
+}
+
+#define MT6392_LDO(match, vreg, supply, ldo_volt_table, \
+ _qi_status_reg, _qi_status_mask, \
+ _enable_reg, _enable_mask, \
+ _vsel_reg, _vsel_mask, \
+ _lp_modeget_reg, _lp_modeget_mask, \
+ _lp_modeset_reg, _lp_modeset_mask, \
+ _enable_time) \
+[MT6392_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .supply_name = supply, \
+ .of_match = of_match_ptr(match), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .ops = &mt6392_volt_table_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6392_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = ARRAY_SIZE(ldo_volt_table), \
+ .volt_table = ldo_volt_table, \
+ .vsel_reg = _vsel_reg, \
+ .vsel_mask = _vsel_mask, \
+ .enable_reg = _enable_reg, \
+ .enable_mask = _enable_mask, \
+ .enable_time = _enable_time, \
+ }, \
+ .qi_status_reg = _qi_status_reg, \
+ .qi_status_mask = _qi_status_mask, \
+ .lp_modeget_reg = _lp_modeget_reg, \
+ .lp_modeget_mask = _lp_modeget_mask, \
+ .lp_modeset_reg = _lp_modeset_reg, \
+ .lp_modeset_mask = _lp_modeset_mask, \
+}
+
+#define MT6392_LDO_LINEAR(match, vreg, supply, min, max, step, \
+ volt_ranges, \
+ _qi_status_reg, _qi_status_mask, \
+ _enable_reg, _enable_mask, \
+ _vsel_reg, _vsel_mask, \
+ _lp_modeget_reg, _lp_modeget_mask, \
+ _lp_modeset_reg, _lp_modeset_mask, \
+ _enable_time) \
+[MT6392_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .supply_name = supply, \
+ .of_match = of_match_ptr(match), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .ops = &mt6392_volt_ldo_range_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6392_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = ((max) - (min)) / (step) + 1, \
+ .linear_ranges = volt_ranges, \
+ .n_linear_ranges = ARRAY_SIZE(volt_ranges), \
+ .vsel_reg = _vsel_reg, \
+ .vsel_mask = _vsel_mask, \
+ .enable_reg = _enable_reg, \
+ .enable_mask = _enable_mask, \
+ .enable_time = _enable_time, \
+ }, \
+ .qi_status_reg = _qi_status_reg, \
+ .qi_status_mask = _qi_status_mask, \
+ .lp_modeget_reg = _lp_modeget_reg, \
+ .lp_modeget_mask = _lp_modeget_mask, \
+ .lp_modeset_reg = _lp_modeset_reg, \
+ .lp_modeset_mask = _lp_modeset_mask, \
+}
+
+#define MT6392_REG_FIXED(match, vreg, supply, volt, \
+ _qi_status_reg, _qi_status_mask, \
+ _enable_reg, _enable_mask, \
+ _lp_modeget_reg, _lp_modeget_mask, \
+ _lp_modeset_reg, _lp_modeset_mask, \
+ _enable_time) \
+[MT6392_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .supply_name = supply, \
+ .of_match = of_match_ptr(match), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .ops = &mt6392_volt_fixed_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6392_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = 1, \
+ .min_uV = volt, \
+ .enable_reg = _enable_reg, \
+ .enable_mask = _enable_mask, \
+ .enable_time = _enable_time, \
+ }, \
+ .qi_status_reg = _qi_status_reg, \
+ .qi_status_mask = _qi_status_mask, \
+ .lp_modeget_reg = _lp_modeget_reg, \
+ .lp_modeget_mask = _lp_modeget_mask, \
+ .lp_modeset_reg = _lp_modeset_reg, \
+ .lp_modeset_mask = _lp_modeset_mask, \
+}
+
+#define MT6392_REG_FIXED_NO_MODE(match, vreg, supply, volt, \
+ _qi_status_reg, _qi_status_mask, \
+ _enable_reg, _enable_mask, _enable_time) \
+[MT6392_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .supply_name = supply, \
+ .of_match = of_match_ptr(match), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .ops = &mt6392_volt_fixed_no_mode_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6392_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = 1, \
+ .min_uV = volt, \
+ .enable_reg = _enable_reg, \
+ .enable_mask = _enable_mask, \
+ .enable_time = _enable_time, \
+ }, \
+ .qi_status_reg = _qi_status_reg, \
+ .qi_status_mask = _qi_status_mask, \
+}
+
+#define MT6392_REG(match, vreg, supply, volt) \
+[MT6392_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .supply_name = supply, \
+ .of_match = of_match_ptr(match), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .ops = &mt6392_volt_no_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6392_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = 1, \
+ .min_uV = volt, \
+ }, \
+}
+
+static const struct linear_range buck_volt_range1[] = {
+ REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250),
+};
+
+static const struct linear_range buck_volt_range2[] = {
+ REGULATOR_LINEAR_RANGE(1400000, 0, 0x7f, 12500),
+};
+
+static const u32 ldo_volt_table1[] = {
+ 1800000, 1900000, 2000000, 2200000,
+};
+
+static const struct linear_range ldo_volt_range2[] = {
+ REGULATOR_LINEAR_RANGE(3300000, 0, 3, 100000),
+};
+
+static const u32 ldo_volt_table3[] = {
+ 1800000, 3300000,
+};
+
+static const u32 ldo_volt_table4[] = {
+ 3000000, 3300000,
+};
+
+static const u32 ldo_volt_table5[] = {
+ 1200000, 1300000, 1500000, 1800000, 2000000, 2800000, 3000000, 3300000,
+};
+
+static const u32 ldo_volt_table6[] = {
+ 1240000, 1390000,
+};
+
+static const u32 ldo_volt_table7[] = {
+ 1200000, 1300000, 1500000, 1800000,
+};
+
+static const u32 ldo_volt_table8[] = {
+ 1800000, 2000000,
+};
+
+static int mt6392_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+ int ret, val = 0;
+ struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+ u32 reg_value;
+
+ if (!info->pwm_modeset_mask) {
+ dev_err(&rdev->dev, "regulator %s doesn't support set_mode\n", info->desc.name);
+ return -EINVAL;
+ }
+
+ switch (mode) {
+ case REGULATOR_MODE_FAST:
+ val = MT6392_BUCK_MODE_FORCE_PWM;
+ break;
+ case REGULATOR_MODE_NORMAL:
+ val = MT6392_BUCK_MODE_AUTO;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ val <<= ffs(info->pwm_modeset_mask) - 1;
+
+ ret = regmap_update_bits(rdev->regmap, info->pwm_modeset_reg,
+ info->pwm_modeset_mask, val);
+
+ if (regmap_read(rdev->regmap, info->pwm_modeset_reg, ®_value) < 0) {
+ dev_err(&rdev->dev, "Failed to read register value\n");
+ return -EIO;
+ }
+
+ dev_info(&rdev->dev, "%s: info->pwm_modeset_reg 0x%x = 0x%x\n",
+ info->desc.name, info->pwm_modeset_reg, reg_value);
+
+ return ret;
+}
+
+static unsigned int mt6392_buck_get_mode(struct regulator_dev *rdev)
+{
+ unsigned int val;
+ unsigned int mode;
+ int ret;
+ struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+
+ if (!info->pwm_modeset_mask) {
+ dev_err(&rdev->dev, "regulator %s doesn't support get_mode\n", info->desc.name);
+ return -EINVAL;
+ }
+
+ ret = regmap_read(rdev->regmap, info->pwm_modeset_reg, &val);
+ if (ret < 0)
+ return ret;
+
+ val &= info->pwm_modeset_mask;
+ val >>= ffs(info->pwm_modeset_mask) - 1;
+
+ if (val & 0x1)
+ mode = REGULATOR_MODE_FAST;
+ else
+ mode = REGULATOR_MODE_NORMAL;
+
+ return mode;
+}
+
+static int mt6392_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+ int ret, val = 0;
+ struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+
+ if (!info->lp_modeset_mask) {
+ dev_err(&rdev->dev, "regulator %s doesn't support set_mode\n",
+ info->desc.name);
+ return -EINVAL;
+ }
+
+ switch (mode) {
+ case REGULATOR_MODE_STANDBY:
+ val = MT6392_LDO_MODE_LP;
+ break;
+ case REGULATOR_MODE_NORMAL:
+ val = MT6392_LDO_MODE_NORMAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ val <<= ffs(info->lp_modeset_mask) - 1;
+
+ ret = regmap_update_bits(rdev->regmap, info->lp_modeset_reg,
+ info->lp_modeset_mask, val);
+
+ return ret;
+}
+
+static unsigned int mt6392_ldo_get_mode(struct regulator_dev *rdev)
+{
+ unsigned int val;
+ unsigned int mode;
+ int ret;
+ struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+
+ if (!info->lp_modeset_mask) {
+ dev_err(&rdev->dev, "regulator %s doesn't support get_mode\n",
+ info->desc.name);
+ return -EINVAL;
+ }
+
+ ret = regmap_read(rdev->regmap, info->lp_modeset_reg, &val);
+ if (ret < 0)
+ return ret;
+
+ val &= info->lp_modeset_mask;
+ val >>= ffs(info->lp_modeset_mask) - 1;
+
+ if (val & 0x1)
+ mode = REGULATOR_MODE_STANDBY;
+ else
+ mode = REGULATOR_MODE_NORMAL;
+
+ return mode;
+}
+
+static int mt6392_get_status(struct regulator_dev *rdev)
+{
+ int ret;
+ u32 regval;
+ struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+
+ ret = regmap_read(rdev->regmap, info->qi_status_reg, ®val);
+ if (ret != 0) {
+ dev_err(&rdev->dev, "Failed to read qi_status_reg: %d\n", ret);
+ return ret;
+ }
+
+ return (regval & info->qi_status_mask) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
+}
+
+static const struct regulator_ops mt6392_volt_range_ops = {
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_status = mt6392_get_status,
+ .set_mode = mt6392_buck_set_mode,
+ .get_mode = mt6392_buck_get_mode,
+};
+
+static const struct regulator_ops mt6392_volt_table_ops = {
+ .list_voltage = regulator_list_voltage_table,
+ .map_voltage = regulator_map_voltage_iterate,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_status = mt6392_get_status,
+ .set_mode = mt6392_ldo_set_mode,
+ .get_mode = mt6392_ldo_get_mode,
+};
+
+static const struct regulator_ops mt6392_volt_ldo_range_ops = {
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_status = mt6392_get_status,
+ .set_mode = mt6392_ldo_set_mode,
+ .get_mode = mt6392_ldo_get_mode,
+};
+
+static const struct regulator_ops mt6392_volt_fixed_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_status = mt6392_get_status,
+ .set_mode = mt6392_ldo_set_mode,
+ .get_mode = mt6392_ldo_get_mode,
+};
+
+static const struct regulator_ops mt6392_volt_fixed_no_mode_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_status = mt6392_get_status,
+};
+
+static const struct regulator_ops mt6392_volt_no_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+};
+
+/* The array is indexed by id(MT6392_ID_XXX) */
+static struct mt6392_regulator_info mt6392_regulators[] = {
+ MT6392_BUCK("vproc", VPROC, "vproc", 700000, 1493750, 6250,
+ buck_volt_range1,
+ MT6392_VPROC_CON7, BIT(13), // Regulator status
+ MT6392_VPROC_CON7, BIT(0), // Regulator enable
+ MT6392_VPROC_CON5, BIT(0), // Vsel ctrl mode selector,not present in data sheet
+ MT6392_VPROC_CON9, GENMASK(6, 0), // Vsel when control mode = register (0)
+ MT6392_VPROC_CON10, GENMASK(6, 0), // Vsel when control mode = normal (1)
+ MT6392_VPROC_CON2, BIT(8), // Auto / Force PWM mode
+ 12500),
+ MT6392_BUCK("vsys", VSYS, "vsys", 1400000, 2987500, 12500,
+ buck_volt_range2,
+ MT6392_VSYS_CON7, BIT(13),
+ MT6392_VSYS_CON7, BIT(0),
+ MT6392_VSYS_CON5, BIT(0), // Not present in data sheet
+ MT6392_VSYS_CON9, GENMASK(6, 0),
+ MT6392_VSYS_CON10, GENMASK(6, 0),
+ MT6392_VSYS_CON2, BIT(8),
+ 25000),
+ MT6392_BUCK("vcore", VCORE, "vcore", 700000, 1493750, 6250,
+ buck_volt_range1,
+ MT6392_VCORE_CON7, BIT(13),
+ MT6392_VCORE_CON7, BIT(0),
+ MT6392_VCORE_CON5, BIT(0), // Not present in data sheet
+ MT6392_VCORE_CON9, GENMASK(6, 0),
+ MT6392_VCORE_CON10, GENMASK(6, 0),
+ MT6392_VCORE_CON2, BIT(8),
+ 12500),
+
+ MT6392_REG_FIXED("vxo22", VXO22, "ldo1", 2200000,
+ MT6392_ANALDO_CON1, BIT(15),
+ MT6392_ANALDO_CON1, BIT(10), // Not present in data sheet
+ MT6392_ANALDO_CON1, BIT(7),
+ MT6392_ANALDO_CON1, BIT(1), // Not present in data sheet
+ 110),
+ MT6392_LDO("vaud22", VAUD22, "ldo1", ldo_volt_table1,
+ MT6392_ANALDO_CON2, BIT(15),
+ MT6392_ANALDO_CON2, BIT(14), // Not present in data sheet
+ MT6392_ANALDO_CON8, GENMASK(6, 5), // Not present in data sheet
+ MT6392_ANALDO_CON2, BIT(7),
+ MT6392_ANALDO_CON2, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_REG_FIXED_NO_MODE("vcama", VCAMA, "ldo1", 2800000,
+ MT6392_ANALDO_CON4, BIT(15),
+ MT6392_ANALDO_CON4, BIT(15),
+ 264),
+ MT6392_REG_FIXED("vaud28", VAUD28, "ldo1", 2800000,
+ MT6392_ANALDO_CON23, BIT(15),
+ MT6392_ANALDO_CON23, BIT(14), // Not present in data sheet
+ MT6392_ANALDO_CON23, BIT(7),
+ MT6392_ANALDO_CON23, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_REG_FIXED("vadc18", VADC18, "ldo1", 1800000,
+ MT6392_ANALDO_CON25, BIT(15),
+ MT6392_ANALDO_CON25, BIT(14), // Not present in data sheet
+ MT6392_ANALDO_CON25, BIT(7),
+ MT6392_ANALDO_CON25, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_LDO_LINEAR("vcn35", VCN35, "ldo2", 3300000, 3600000, 100000, ldo_volt_range2,
+ MT6392_ANALDO_CON17, BIT(15), // Not present in data sheet
+ MT6392_ANALDO_CON21, BIT(12), // Not present in data sheet
+ MT6392_ANALDO_CON16, GENMASK(4, 3),
+ MT6392_ANALDO_CON21, BIT(7),
+ MT6392_ANALDO_CON21, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_REG_FIXED("vio28", VIO28, "ldo2", 2800000,
+ MT6392_DIGLDO_CON0, BIT(15),
+ MT6392_DIGLDO_CON0, BIT(14), // Not present in data sheet
+ MT6392_DIGLDO_CON0, BIT(7),
+ MT6392_DIGLDO_CON0, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_REG_FIXED("vusb", VUSB, "ldo3", 3300000,
+ MT6392_DIGLDO_CON2, BIT(15),
+ MT6392_DIGLDO_CON2, BIT(14), // Not present in data sheet
+ MT6392_DIGLDO_CON2, BIT(7),
+ MT6392_DIGLDO_CON2, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_LDO("vmc", VMC, "ldo2", ldo_volt_table3,
+ MT6392_DIGLDO_CON3, BIT(15),
+ MT6392_DIGLDO_CON3, BIT(12),
+ MT6392_DIGLDO_CON24, BIT(4),
+ MT6392_DIGLDO_CON3, BIT(7),
+ MT6392_DIGLDO_CON3, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_LDO("vmch", VMCH, "ldo2", ldo_volt_table4,
+ MT6392_DIGLDO_CON5, BIT(15),
+ MT6392_DIGLDO_CON5, BIT(14),
+ MT6392_DIGLDO_CON26, BIT(7),
+ MT6392_DIGLDO_CON5, BIT(7),
+ MT6392_DIGLDO_CON5, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_LDO("vemc3v3", VEMC3V3, "ldo3", ldo_volt_table4,
+ MT6392_DIGLDO_CON6, BIT(15),
+ MT6392_DIGLDO_CON6, BIT(14), // Not present in data sheet
+ MT6392_DIGLDO_CON27, BIT(7),
+ MT6392_DIGLDO_CON6, BIT(7),
+ MT6392_DIGLDO_CON6, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_LDO("vgp1", VGP1, "ldo3", ldo_volt_table5,
+ MT6392_DIGLDO_CON7, BIT(15),
+ MT6392_DIGLDO_CON7, BIT(15),
+ MT6392_DIGLDO_CON28, GENMASK(7, 5),
+ MT6392_DIGLDO_CON7, BIT(7),
+ MT6392_DIGLDO_CON7, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_LDO("vgp2", VGP2, "ldo3", ldo_volt_table5,
+ MT6392_DIGLDO_CON8, BIT(15),
+ MT6392_DIGLDO_CON8, BIT(15),
+ MT6392_DIGLDO_CON29, GENMASK(7, 5),
+ MT6392_DIGLDO_CON8, BIT(7),
+ MT6392_DIGLDO_CON8, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_REG_FIXED("vcn18", VCN18, "avddldo", 1800000,
+ MT6392_DIGLDO_CON11, BIT(15),
+ MT6392_DIGLDO_CON11, BIT(14), // Not present in data sheet
+ MT6392_DIGLDO_CON11, BIT(7),
+ MT6392_DIGLDO_CON11, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_LDO("vcamaf", VCAMAF, "ldo3", ldo_volt_table5,
+ MT6392_DIGLDO_CON31, BIT(15),
+ MT6392_DIGLDO_CON31, BIT(15),
+ MT6392_DIGLDO_CON32, GENMASK(7, 5),
+ MT6392_DIGLDO_CON31, BIT(7),
+ MT6392_DIGLDO_CON31, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_LDO("vm", VM, "avddldo", ldo_volt_table6,
+ MT6392_DIGLDO_CON47, BIT(15),
+ MT6392_DIGLDO_CON47, BIT(14), // Not present in data sheet
+ MT6392_DIGLDO_CON48, GENMASK(5, 4), // Not present in data sheet
+ MT6392_DIGLDO_CON47, BIT(7), // Not present in data sheet
+ MT6392_DIGLDO_CON47, BIT(1),
+ 264),
+ MT6392_REG_FIXED("vio18", VIO18, "avddldo", 1800000,
+ MT6392_DIGLDO_CON49, BIT(15),
+ MT6392_DIGLDO_CON49, BIT(14), // Not present in data sheet
+ MT6392_DIGLDO_CON49, BIT(7),
+ MT6392_DIGLDO_CON49, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_LDO("vcamd", VCAMD, "avddldo", ldo_volt_table7,
+ MT6392_DIGLDO_CON51, BIT(15),
+ MT6392_DIGLDO_CON51, BIT(14),
+ MT6392_DIGLDO_CON52, GENMASK(6, 5),
+ MT6392_DIGLDO_CON51, BIT(7),
+ MT6392_DIGLDO_CON51, BIT(1),
+ 264),
+ MT6392_REG_FIXED("vcamio", VCAMIO, "avddldo", 1800000,
+ MT6392_DIGLDO_CON53, BIT(15),
+ MT6392_DIGLDO_CON53, BIT(14),
+ MT6392_DIGLDO_CON53, BIT(7),
+ MT6392_DIGLDO_CON53, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_REG_FIXED("vm25", VM25, "ldo3", 2500000,
+ MT6392_DIGLDO_CON55, BIT(15),
+ MT6392_DIGLDO_CON55, BIT(14), // Not present in data sheet
+ MT6392_DIGLDO_CON55, BIT(7),
+ MT6392_DIGLDO_CON55, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_LDO("vefuse", VEFUSE, "ldo2", ldo_volt_table8,
+ MT6392_DIGLDO_CON57, BIT(15),
+ MT6392_DIGLDO_CON57, BIT(14), // Not present in data sheet
+ MT6392_DIGLDO_CON58, BIT(5), // Not present in data sheet
+ MT6392_DIGLDO_CON57, BIT(7),
+ MT6392_DIGLDO_CON57, BIT(1), // Not present in data sheet
+ 264),
+ MT6392_REG("vdig18", VDIG18, "ldo2", 1800000), // Internal non changeable regulator
+ MT6392_REG_FIXED_NO_MODE("vrtc", VRTC, "ldo1", 2800000,
+ MT6392_DIGLDO_CON15, BIT(15),
+ MT6392_DIGLDO_CON15, BIT(8), // Not present in data sheet
+ 264)
+};
+
+// Buck regulators can be in Register mode or Normal mode.
+// Each mode uses a different register to set the desired voltage.
+static int mt6392_set_buck_vsel_reg(struct platform_device *pdev)
+{
+ struct mt6397_chip *mt6392 = dev_get_drvdata(pdev->dev.parent);
+ int i;
+ u32 regval;
+
+ for (i = 0; i < MT6392_MAX_REGULATOR; i++) {
+ if (mt6392_regulators[i].vselctrl_reg) {
+ // Read the vselctrl_reg register
+ if (regmap_read(mt6392->regmap,
+ mt6392_regulators[i].vselctrl_reg,
+ ®val) < 0) {
+ dev_err(&pdev->dev,
+ "Failed to read buck ctrl\n");
+ return -EIO;
+ }
+
+ // vselctrl_reg[vselctrl_mask] defines the mode
+ if (regval & mt6392_regulators[i].vselctrl_mask) {
+ // Regulator in Normal mode
+ mt6392_regulators[i].desc.vsel_reg =
+ mt6392_regulators[i].vsel_normal_mode_reg;
+ mt6392_regulators[i].desc.vsel_mask =
+ mt6392_regulators[i].vsel_normal_mode_mask;
+ } else {
+ // Regulator in Register mode
+ mt6392_regulators[i].desc.vsel_reg =
+ mt6392_regulators[i].vsel_reg_mode_reg;
+ mt6392_regulators[i].desc.vsel_mask =
+ mt6392_regulators[i].vsel_reg_mode_mask;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int mt6392_regulator_probe(struct platform_device *pdev)
+{
+ struct mt6397_chip *mt6392 = dev_get_drvdata(pdev->dev.parent);
+ struct regulator_config config = {};
+ struct regulator_dev *rdev;
+ int i;
+
+ device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+
+ // Initialize the bucks' vsel_reg and vsel_mask according to current HW state
+ if (mt6392_set_buck_vsel_reg(pdev))
+ return -EIO;
+
+ config.dev = mt6392->dev;
+ config.regmap = mt6392->regmap;
+ for (i = 0; i < MT6392_MAX_REGULATOR; i++) {
+ config.driver_data = &mt6392_regulators[i];
+
+ rdev = devm_regulator_register(&pdev->dev,
+ &mt6392_regulators[i].desc,
+ &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "failed to register %s\n",
+ mt6392_regulators[i].desc.name);
+ return PTR_ERR(rdev);
+ }
+ }
+
+ return 0;
+}
+
+static const struct platform_device_id mt6392_platform_ids[] = {
+ { .name = "mt6392-regulator" },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, mt6392_platform_ids);
+
+static struct platform_driver mt6392_regulator_driver = {
+ .driver = {
+ .name = "mt6392-regulator",
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ },
+ .probe = mt6392_regulator_probe,
+ .id_table = mt6392_platform_ids,
+};
+
+module_platform_driver(mt6392_regulator_driver);
+
+MODULE_AUTHOR("Chen Zhong <chen.zhong@mediatek.com>");
+MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6392 PMIC");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/regulator/mt6392-regulator.h b/include/linux/regulator/mt6392-regulator.h
new file mode 100644
index 000000000000..0eccd085b062
--- /dev/null
+++ b/include/linux/regulator/mt6392-regulator.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ */
+
+#ifndef __LINUX_REGULATOR_MT6392_H
+#define __LINUX_REGULATOR_MT6392_H
+
+enum {
+ MT6392_ID_VPROC = 0,
+ MT6392_ID_VSYS,
+ MT6392_ID_VCORE,
+ MT6392_ID_VXO22,
+ MT6392_ID_VAUD22,
+ MT6392_ID_VCAMA,
+ MT6392_ID_VAUD28,
+ MT6392_ID_VADC18,
+ MT6392_ID_VCN35,
+ MT6392_ID_VIO28,
+ MT6392_ID_VUSB = 10,
+ MT6392_ID_VMC,
+ MT6392_ID_VMCH,
+ MT6392_ID_VEMC3V3,
+ MT6392_ID_VGP1,
+ MT6392_ID_VGP2,
+ MT6392_ID_VCN18,
+ MT6392_ID_VCAMAF,
+ MT6392_ID_VM,
+ MT6392_ID_VIO18,
+ MT6392_ID_VCAMD,
+ MT6392_ID_VCAMIO,
+ MT6392_ID_VM25,
+ MT6392_ID_VEFUSE,
+ MT6392_ID_VDIG18,
+ MT6392_ID_VRTC,
+ MT6392_ID_RG_MAX,
+};
+
+#define MT6392_MAX_REGULATOR MT6392_ID_RG_MAX
+
+#endif /* __LINUX_REGULATOR_MT6392_H */
--
2.43.0
^ permalink raw reply related
* [PATCH v7 7/9] pinctrl: mediatek: mt6397: Add MediaTek MT6392
From: Luca Leonardo Scorcia @ 2026-06-15 7:16 UTC (permalink / raw)
To: linux-mediatek
Cc: Luca Leonardo Scorcia, AngeloGioacchino Del Regno,
Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sen Chu, Sean Wang, Macpaul Lin, Lee Jones, Matthias Brugger,
Liam Girdwood, Mark Brown, Linus Walleij, Louis-Alexis Eyraud,
Val Packett, Julien Massot, Fabien Parent, Akari Tsuyukusa,
Chen Zhong, linux-input, devicetree, linux-kernel, linux-pm,
linux-arm-kernel, linux-gpio
In-Reply-To: <20260615071836.362883-1-l.scorcia@gmail.com>
Add support for the MT6392 pinctrl device, which is very similar to
MT6397 with a handful of different property values and its own pins
definition.
Update the MT6397 driver to retrieve device data from the match table and
use it for driver init.
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/pinctrl/mediatek/pinctrl-mt6397.c | 37 ++++++++++-
drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h | 64 +++++++++++++++++++
2 files changed, 99 insertions(+), 2 deletions(-)
create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6397.c b/drivers/pinctrl/mediatek/pinctrl-mt6397.c
index 03d0f65d7bcc..8ba02e70595c 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6397.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6397.c
@@ -12,10 +12,32 @@
#include <linux/mfd/mt6397/core.h>
#include "pinctrl-mtk-common.h"
+#include "pinctrl-mtk-mt6392.h"
#include "pinctrl-mtk-mt6397.h"
#define MT6397_PIN_REG_BASE 0xc000
+static const struct mtk_pinctrl_devdata mt6392_pinctrl_data = {
+ .pins = mtk_pins_mt6392,
+ .npins = ARRAY_SIZE(mtk_pins_mt6392),
+ .dir_offset = (MT6397_PIN_REG_BASE + 0x000),
+ .ies_offset = MTK_PINCTRL_NOT_SUPPORT,
+ .smt_offset = MTK_PINCTRL_NOT_SUPPORT,
+ .pullen_offset = (MT6397_PIN_REG_BASE + 0x020),
+ .pullsel_offset = (MT6397_PIN_REG_BASE + 0x040),
+ .dout_offset = (MT6397_PIN_REG_BASE + 0x080),
+ .din_offset = (MT6397_PIN_REG_BASE + 0x0a0),
+ .pinmux_offset = (MT6397_PIN_REG_BASE + 0x0c0),
+ .type1_start = 7,
+ .type1_end = 7,
+ .port_shf = 3,
+ .port_mask = 0x3,
+ .port_align = 2,
+ .mode_mask = 0xf,
+ .mode_per_reg = 5,
+ .mode_shf = 4,
+};
+
static const struct mtk_pinctrl_devdata mt6397_pinctrl_data = {
.pins = mtk_pins_mt6397,
.npins = ARRAY_SIZE(mtk_pins_mt6397),
@@ -40,13 +62,24 @@ static const struct mtk_pinctrl_devdata mt6397_pinctrl_data = {
static int mt6397_pinctrl_probe(struct platform_device *pdev)
{
struct mt6397_chip *mt6397;
+ const struct mtk_pinctrl_devdata *data;
+
+ data = device_get_match_data(&pdev->dev);
+ if (!data)
+ return -ENOENT;
mt6397 = dev_get_drvdata(pdev->dev.parent);
- return mtk_pctrl_init(pdev, &mt6397_pinctrl_data, mt6397->regmap);
+ return mtk_pctrl_init(pdev, data, mt6397->regmap);
}
static const struct of_device_id mt6397_pctrl_match[] = {
- { .compatible = "mediatek,mt6397-pinctrl", },
+ {
+ .compatible = "mediatek,mt6392-pinctrl",
+ .data = &mt6392_pinctrl_data
+ }, {
+ .compatible = "mediatek,mt6397-pinctrl",
+ .data = &mt6397_pinctrl_data
+ },
{ }
};
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h
new file mode 100644
index 000000000000..e7241af28fdb
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PINCTRL_MTK_MT6392_H
+#define __PINCTRL_MTK_MT6392_H
+
+#include <linux/pinctrl/pinctrl.h>
+#include "pinctrl-mtk-common.h"
+
+static const struct mtk_desc_pin mtk_pins_mt6392[] = {
+ MTK_PIN(PINCTRL_PIN(0, "INT"),
+ NULL, "mt6392",
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+ MTK_FUNCTION(0, "GPIO0"),
+ MTK_FUNCTION(1, "INT"),
+ MTK_FUNCTION(5, "TEST_CK2"),
+ MTK_FUNCTION(6, "TEST_IN1"),
+ MTK_FUNCTION(7, "TEST_OUT1")
+ ),
+ MTK_PIN(PINCTRL_PIN(1, "SRCLKEN"),
+ NULL, "mt6392",
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+ MTK_FUNCTION(0, "GPIO1"),
+ MTK_FUNCTION(1, "SRCLKEN"),
+ MTK_FUNCTION(5, "TEST_CK0"),
+ MTK_FUNCTION(6, "TEST_IN2"),
+ MTK_FUNCTION(7, "TEST_OUT2")
+ ),
+ MTK_PIN(PINCTRL_PIN(2, "RTC_32K1V8"),
+ NULL, "mt6392",
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+ MTK_FUNCTION(0, "GPIO2"),
+ MTK_FUNCTION(1, "RTC_32K1V8"),
+ MTK_FUNCTION(5, "TEST_CK1"),
+ MTK_FUNCTION(6, "TEST_IN3"),
+ MTK_FUNCTION(7, "TEST_OUT3")
+ ),
+ MTK_PIN(PINCTRL_PIN(3, "SPI_CLK"),
+ NULL, "mt6392",
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+ MTK_FUNCTION(0, "GPIO3"),
+ MTK_FUNCTION(1, "SPI_CLK")
+ ),
+ MTK_PIN(PINCTRL_PIN(4, "SPI_CSN"),
+ NULL, "mt6392",
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+ MTK_FUNCTION(0, "GPIO4"),
+ MTK_FUNCTION(1, "SPI_CSN")
+ ),
+ MTK_PIN(PINCTRL_PIN(5, "SPI_MOSI"),
+ NULL, "mt6392",
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+ MTK_FUNCTION(0, "GPIO5"),
+ MTK_FUNCTION(1, "SPI_MOSI")
+ ),
+ MTK_PIN(PINCTRL_PIN(6, "SPI_MISO"),
+ NULL, "mt6392",
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+ MTK_FUNCTION(0, "GPIO6"),
+ MTK_FUNCTION(1, "SPI_MISO"),
+ MTK_FUNCTION(6, "TEST_IN4"),
+ MTK_FUNCTION(7, "TEST_OUT4")
+ ),
+};
+
+#endif /* __PINCTRL_MTK_MT6392_H */
--
2.43.0
^ permalink raw reply related
* [PATCH v7 6/9] input: keyboard: mtk-pmic-keys: Add MT6392 support
From: Luca Leonardo Scorcia @ 2026-06-15 7:16 UTC (permalink / raw)
To: linux-mediatek
Cc: Val Packett, Luca Leonardo Scorcia, AngeloGioacchino Del Regno,
Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sen Chu, Sean Wang, Macpaul Lin, Lee Jones, Matthias Brugger,
Liam Girdwood, Mark Brown, Linus Walleij, Julien Massot,
Louis-Alexis Eyraud, Fabien Parent, Akari Tsuyukusa, Chen Zhong,
linux-input, devicetree, linux-kernel, linux-pm, linux-arm-kernel,
linux-gpio
In-Reply-To: <20260615071836.362883-1-l.scorcia@gmail.com>
From: Val Packett <val@packett.cool>
Add support for the MT6392 PMIC to the keys driver.
Signed-off-by: Val Packett <val@packett.cool>
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/keyboard/mtk-pmic-keys.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c
index c78d9f6d97c4..8b4a89fce4fb 100644
--- a/drivers/input/keyboard/mtk-pmic-keys.c
+++ b/drivers/input/keyboard/mtk-pmic-keys.c
@@ -13,6 +13,7 @@
#include <linux/mfd/mt6357/registers.h>
#include <linux/mfd/mt6358/registers.h>
#include <linux/mfd/mt6359/registers.h>
+#include <linux/mfd/mt6392/registers.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6397/registers.h>
#include <linux/module.h>
@@ -69,6 +70,19 @@ static const struct mtk_pmic_regs mt6397_regs = {
.rst_lprst_mask = MTK_PMIC_RST_DU_MASK,
};
+static const struct mtk_pmic_regs mt6392_regs = {
+ .keys_regs[MTK_PMIC_PWRKEY_INDEX] =
+ MTK_PMIC_KEYS_REGS(MT6392_CHRSTATUS, 0x2,
+ MT6392_INT_MISC_CON, 0x10,
+ MTK_PMIC_PWRKEY_RST),
+ .keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
+ MTK_PMIC_KEYS_REGS(MT6392_CHRSTATUS, 0x4,
+ MT6392_INT_MISC_CON, 0x8,
+ MTK_PMIC_HOMEKEY_RST),
+ .pmic_rst_reg = MT6392_TOP_RST_MISC,
+ .rst_lprst_mask = MTK_PMIC_RST_DU_MASK,
+};
+
static const struct mtk_pmic_regs mt6323_regs = {
.keys_regs[MTK_PMIC_PWRKEY_INDEX] =
MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS,
@@ -301,6 +315,9 @@ static const struct of_device_id of_mtk_pmic_keys_match_tbl[] = {
{
.compatible = "mediatek,mt6397-keys",
.data = &mt6397_regs,
+ }, {
+ .compatible = "mediatek,mt6392-keys",
+ .data = &mt6392_regs,
}, {
.compatible = "mediatek,mt6323-keys",
.data = &mt6323_regs,
--
2.43.0
^ permalink raw reply related
* [PATCH v7 5/9] mfd: mt6397: Add support for MT6392 PMIC
From: Luca Leonardo Scorcia @ 2026-06-15 7:16 UTC (permalink / raw)
To: linux-mediatek
Cc: Fabien Parent, Val Packett, Luca Leonardo Scorcia,
AngeloGioacchino Del Regno, Dmitry Torokhov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sen Chu, Sean Wang,
Macpaul Lin, Lee Jones, Matthias Brugger, Liam Girdwood,
Mark Brown, Linus Walleij, Louis-Alexis Eyraud, Julien Massot,
Akari Tsuyukusa, Chen Zhong, linux-input, devicetree,
linux-kernel, linux-pm, linux-arm-kernel, linux-gpio
In-Reply-To: <20260615071836.362883-1-l.scorcia@gmail.com>
From: Fabien Parent <parent.f@gmail.com>
Align the MT6397 PMIC driver to other MFD drivers by passing only an
identifier through mt6397_of_match[*].data and add support for the MT6392
PMIC and its regulator, RTC, keys and pinctrl devices.
The keys device manages two buttons named PWRKEY and FCHR_ENB, the latter
is identified as "Force charging disable" in the data sheet but it also
says "Merge with HOMEKEY", so call it "Home" for consistency.
Signed-off-by: Fabien Parent <parent.f@gmail.com>
Signed-off-by: Val Packett <val@packett.cool>
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/mfd/mt6397-core.c | 98 ++++--
drivers/mfd/mt6397-irq.c | 8 +
include/linux/mfd/mt6392/core.h | 43 +++
include/linux/mfd/mt6392/registers.h | 488 +++++++++++++++++++++++++++
include/linux/mfd/mt6397/core.h | 1 +
5 files changed, 612 insertions(+), 26 deletions(-)
create mode 100644 include/linux/mfd/mt6392/core.h
create mode 100644 include/linux/mfd/mt6392/registers.h
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index ccd97d66d7f1..f683e878543e 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -18,6 +18,7 @@
#include <linux/mfd/mt6357/core.h>
#include <linux/mfd/mt6358/core.h>
#include <linux/mfd/mt6359/core.h>
+#include <linux/mfd/mt6392/core.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6323/registers.h>
#include <linux/mfd/mt6328/registers.h>
@@ -25,6 +26,7 @@
#include <linux/mfd/mt6357/registers.h>
#include <linux/mfd/mt6358/registers.h>
#include <linux/mfd/mt6359/registers.h>
+#include <linux/mfd/mt6392/registers.h>
#include <linux/mfd/mt6397/registers.h>
#define MT6323_RTC_BASE 0x8000
@@ -39,6 +41,9 @@
#define MT6358_RTC_BASE 0x0588
#define MT6358_RTC_SIZE 0x3c
+#define MT6392_RTC_BASE 0x8000
+#define MT6392_RTC_SIZE 0x3e
+
#define MT6397_RTC_BASE 0xe000
#define MT6397_RTC_SIZE 0x3e
@@ -65,6 +70,11 @@ static const struct resource mt6358_rtc_resources[] = {
DEFINE_RES_IRQ(MT6358_IRQ_RTC),
};
+static const struct resource mt6392_rtc_resources[] = {
+ DEFINE_RES_MEM(MT6392_RTC_BASE, MT6392_RTC_SIZE),
+ DEFINE_RES_IRQ(MT6392_IRQ_RTC),
+};
+
static const struct resource mt6397_rtc_resources[] = {
DEFINE_RES_MEM(MT6397_RTC_BASE, MT6397_RTC_SIZE),
DEFINE_RES_IRQ(MT6397_IRQ_RTC),
@@ -114,6 +124,11 @@ static const struct resource mt6331_keys_resources[] = {
DEFINE_RES_IRQ_NAMED(MT6331_IRQ_STATUS_HOMEKEY, "homekey"),
};
+static const struct resource mt6392_keys_resources[] = {
+ DEFINE_RES_IRQ_NAMED(MT6392_IRQ_PWRKEY, "powerkey"),
+ DEFINE_RES_IRQ_NAMED(MT6392_IRQ_FCHRKEY, "homekey"),
+};
+
static const struct resource mt6397_keys_resources[] = {
DEFINE_RES_IRQ_NAMED(MT6397_IRQ_PWRKEY, "powerkey"),
DEFINE_RES_IRQ_NAMED(MT6397_IRQ_HOMEKEY, "homekey"),
@@ -193,6 +208,16 @@ static const struct mfd_cell mt6359_devs[] = {
"mediatek,mt6359-accdet"),
};
+static const struct mfd_cell mt6392_devs[] = {
+ MFD_CELL_OF("mt6392-keys", mt6392_keys_resources, NULL, 0, 0,
+ "mediatek,mt6392-keys"),
+ MFD_CELL_OF("mt6392-pinctrl", NULL, NULL, 0, 0,
+ "mediatek,mt6392-pinctrl"),
+ MFD_CELL_NAME("mt6392-regulator"),
+ MFD_CELL_OF("mt6392-rtc", mt6392_rtc_resources, NULL, 0, 0,
+ "mediatek,mt6392-rtc"),
+};
+
static const struct mfd_cell mt6397_devs[] = {
MFD_CELL_OF("mt6397-rtc", mt6397_rtc_resources, NULL, 0, 0,
"mediatek,mt6397-rtc"),
@@ -264,6 +289,14 @@ static const struct chip_data mt6359_core = {
.irq_init = mt6358_irq_init,
};
+static const struct chip_data mt6392_core = {
+ .cid_addr = MT6392_CID,
+ .cid_shift = 0,
+ .cells = mt6392_devs,
+ .cell_size = ARRAY_SIZE(mt6392_devs),
+ .irq_init = mt6397_irq_init,
+};
+
static const struct chip_data mt6397_core = {
.cid_addr = MT6397_CID,
.cid_shift = 0,
@@ -278,6 +311,7 @@ static int mt6397_probe(struct platform_device *pdev)
unsigned int id = 0;
struct mt6397_chip *pmic;
const struct chip_data *pmic_core;
+ int chip_variant;
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic)
@@ -293,9 +327,36 @@ static int mt6397_probe(struct platform_device *pdev)
if (!pmic->regmap)
return -ENODEV;
- pmic_core = of_device_get_match_data(&pdev->dev);
- if (!pmic_core)
+ chip_variant = (unsigned int)(uintptr_t)device_get_match_data(&pdev->dev);
+ switch (chip_variant) {
+ case MT6323_CHIP_ID:
+ pmic_core = &mt6323_core;
+ break;
+ case MT6328_CHIP_ID:
+ pmic_core = &mt6328_core;
+ break;
+ case MT6331_CHIP_ID:
+ pmic_core = &mt6331_mt6332_core;
+ break;
+ case MT6357_CHIP_ID:
+ pmic_core = &mt6357_core;
+ break;
+ case MT6358_CHIP_ID:
+ pmic_core = &mt6358_core;
+ break;
+ case MT6359_CHIP_ID:
+ pmic_core = &mt6359_core;
+ break;
+ case MT6392_CHIP_ID:
+ pmic_core = &mt6392_core;
+ break;
+ case MT6397_CHIP_ID:
+ pmic_core = &mt6397_core;
+ break;
+ default:
+ dev_err(&pdev->dev, "Device not supported\n");
return -ENODEV;
+ }
ret = regmap_read(pmic->regmap, pmic_core->cid_addr, &id);
if (ret) {
@@ -327,30 +388,15 @@ static int mt6397_probe(struct platform_device *pdev)
}
static const struct of_device_id mt6397_of_match[] = {
- {
- .compatible = "mediatek,mt6323",
- .data = &mt6323_core,
- }, {
- .compatible = "mediatek,mt6328",
- .data = &mt6328_core,
- }, {
- .compatible = "mediatek,mt6331",
- .data = &mt6331_mt6332_core,
- }, {
- .compatible = "mediatek,mt6357",
- .data = &mt6357_core,
- }, {
- .compatible = "mediatek,mt6358",
- .data = &mt6358_core,
- }, {
- .compatible = "mediatek,mt6359",
- .data = &mt6359_core,
- }, {
- .compatible = "mediatek,mt6397",
- .data = &mt6397_core,
- }, {
- /* sentinel */
- }
+ { .compatible = "mediatek,mt6323", .data = (void *)MT6323_CHIP_ID, },
+ { .compatible = "mediatek,mt6328", .data = (void *)MT6328_CHIP_ID, },
+ { .compatible = "mediatek,mt6331", .data = (void *)MT6331_CHIP_ID, },
+ { .compatible = "mediatek,mt6357", .data = (void *)MT6357_CHIP_ID, },
+ { .compatible = "mediatek,mt6358", .data = (void *)MT6358_CHIP_ID, },
+ { .compatible = "mediatek,mt6359", .data = (void *)MT6359_CHIP_ID, },
+ { .compatible = "mediatek,mt6392", .data = (void *)MT6392_CHIP_ID, },
+ { .compatible = "mediatek,mt6397", .data = (void *)MT6397_CHIP_ID, },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mt6397_of_match);
diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c
index 5d2e5459f744..80ea5b92d232 100644
--- a/drivers/mfd/mt6397-irq.c
+++ b/drivers/mfd/mt6397-irq.c
@@ -15,6 +15,8 @@
#include <linux/mfd/mt6328/registers.h>
#include <linux/mfd/mt6331/core.h>
#include <linux/mfd/mt6331/registers.h>
+#include <linux/mfd/mt6392/core.h>
+#include <linux/mfd/mt6392/registers.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6397/registers.h>
@@ -203,6 +205,12 @@ int mt6397_irq_init(struct mt6397_chip *chip)
chip->int_status[0] = MT6397_INT_STATUS0;
chip->int_status[1] = MT6397_INT_STATUS1;
break;
+ case MT6392_CHIP_ID:
+ chip->int_con[0] = MT6392_INT_CON0;
+ chip->int_con[1] = MT6392_INT_CON1;
+ chip->int_status[0] = MT6392_INT_STATUS0;
+ chip->int_status[1] = MT6392_INT_STATUS1;
+ break;
default:
dev_err(chip->dev, "unsupported chip: 0x%x\n", chip->chip_id);
diff --git a/include/linux/mfd/mt6392/core.h b/include/linux/mfd/mt6392/core.h
new file mode 100644
index 000000000000..8777b3abf929
--- /dev/null
+++ b/include/linux/mfd/mt6392/core.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ * Copyright (c) 2026 Luca Leonardo Scorcia <l.scorcia@gmail.com>
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ */
+
+#ifndef __MFD_MT6392_CORE_H__
+#define __MFD_MT6392_CORE_H__
+
+enum mt6392_irq_numbers {
+ MT6392_IRQ_SPKL_AB = 0,
+ MT6392_IRQ_SPKL,
+ MT6392_IRQ_BAT_L,
+ MT6392_IRQ_BAT_H,
+ MT6392_IRQ_WATCHDOG,
+ MT6392_IRQ_PWRKEY,
+ MT6392_IRQ_THR_L,
+ MT6392_IRQ_THR_H,
+ MT6392_IRQ_VBATON_UNDET,
+ MT6392_IRQ_BVALID_DET,
+ MT6392_IRQ_CHRDET,
+ MT6392_IRQ_OV,
+ MT6392_IRQ_LDO = 16,
+ MT6392_IRQ_FCHRKEY,
+ MT6392_IRQ_RELEASE_PWRKEY,
+ MT6392_IRQ_RELEASE_FCHRKEY,
+ MT6392_IRQ_RTC,
+ MT6392_IRQ_VPROC,
+ MT6392_IRQ_VSYS,
+ MT6392_IRQ_VCORE,
+ MT6392_IRQ_TYPE_C_CC,
+ MT6392_IRQ_TYPEC_H_MAX,
+ MT6392_IRQ_TYPEC_H_MIN,
+ MT6392_IRQ_TYPEC_L_MAX,
+ MT6392_IRQ_TYPEC_L_MIN,
+ MT6392_IRQ_THR_MAX,
+ MT6392_IRQ_THR_MIN,
+ MT6392_IRQ_NAG_C_DLTV,
+ MT6392_IRQ_NR,
+};
+
+#endif /* __MFD_MT6392_CORE_H__ */
diff --git a/include/linux/mfd/mt6392/registers.h b/include/linux/mfd/mt6392/registers.h
new file mode 100644
index 000000000000..68fe9af448f5
--- /dev/null
+++ b/include/linux/mfd/mt6392/registers.h
@@ -0,0 +1,488 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ * Copyright (c) 2026 Luca Leonardo Scorcia <l.scorcia@gmail.com>
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ */
+
+#ifndef __MFD_MT6392_REGISTERS_H__
+#define __MFD_MT6392_REGISTERS_H__
+
+/* PMIC Registers */
+#define MT6392_CHR_CON0 0x0000
+#define MT6392_CHR_CON1 0x0002
+#define MT6392_CHR_CON2 0x0004
+#define MT6392_CHR_CON3 0x0006
+#define MT6392_CHR_CON4 0x0008
+#define MT6392_CHR_CON5 0x000A
+#define MT6392_CHR_CON6 0x000C
+#define MT6392_CHR_CON7 0x000E
+#define MT6392_CHR_CON8 0x0010
+#define MT6392_CHR_CON9 0x0012
+#define MT6392_CHR_CON10 0x0014
+#define MT6392_CHR_CON11 0x0016
+#define MT6392_CHR_CON12 0x0018
+#define MT6392_CHR_CON13 0x001A
+#define MT6392_CHR_CON14 0x001C
+#define MT6392_CHR_CON15 0x001E
+#define MT6392_CHR_CON16 0x0020
+#define MT6392_CHR_CON17 0x0022
+#define MT6392_CHR_CON18 0x0024
+#define MT6392_CHR_CON19 0x0026
+#define MT6392_CHR_CON20 0x0028
+#define MT6392_CHR_CON21 0x002A
+#define MT6392_CHR_CON22 0x002C
+#define MT6392_CHR_CON23 0x002E
+#define MT6392_CHR_CON24 0x0030
+#define MT6392_CHR_CON25 0x0032
+#define MT6392_CHR_CON26 0x0034
+#define MT6392_CHR_CON27 0x0036
+#define MT6392_CHR_CON28 0x0038
+#define MT6392_CHR_CON29 0x003A
+#define MT6392_STRUP_CON0 0x003C
+#define MT6392_STRUP_CON2 0x003E
+#define MT6392_STRUP_CON3 0x0040
+#define MT6392_STRUP_CON4 0x0042
+#define MT6392_STRUP_CON5 0x0044
+#define MT6392_STRUP_CON6 0x0046
+#define MT6392_STRUP_CON7 0x0048
+#define MT6392_STRUP_CON8 0x004A
+#define MT6392_STRUP_CON9 0x004C
+#define MT6392_STRUP_CON10 0x004E
+#define MT6392_STRUP_CON11 0x0050
+#define MT6392_SPK_CON0 0x0052
+#define MT6392_SPK_CON1 0x0054
+#define MT6392_SPK_CON2 0x0056
+#define MT6392_SPK_CON6 0x005E
+#define MT6392_SPK_CON7 0x0060
+#define MT6392_SPK_CON8 0x0062
+#define MT6392_SPK_CON9 0x0064
+#define MT6392_SPK_CON10 0x0066
+#define MT6392_SPK_CON11 0x0068
+#define MT6392_SPK_CON12 0x006A
+#define MT6392_STRUP_CON12 0x006E
+#define MT6392_STRUP_CON13 0x0070
+#define MT6392_STRUP_CON14 0x0072
+#define MT6392_STRUP_CON15 0x0074
+#define MT6392_STRUP_CON16 0x0076
+#define MT6392_STRUP_CON17 0x0078
+#define MT6392_STRUP_CON18 0x007A
+#define MT6392_STRUP_CON19 0x007C
+#define MT6392_STRUP_CON20 0x007E
+#define MT6392_CID 0x0100
+#define MT6392_TOP_CKPDN0 0x0102
+#define MT6392_TOP_CKPDN0_SET 0x0104
+#define MT6392_TOP_CKPDN0_CLR 0x0106
+#define MT6392_TOP_CKPDN1 0x0108
+#define MT6392_TOP_CKPDN1_SET 0x010A
+#define MT6392_TOP_CKPDN1_CLR 0x010C
+#define MT6392_TOP_CKPDN2 0x010E
+#define MT6392_TOP_CKPDN2_SET 0x0110
+#define MT6392_TOP_CKPDN2_CLR 0x0112
+#define MT6392_TOP_RST_CON 0x0114
+#define MT6392_TOP_RST_CON_SET 0x0116
+#define MT6392_TOP_RST_CON_CLR 0x0118
+#define MT6392_TOP_RST_MISC 0x011A
+#define MT6392_TOP_RST_MISC_SET 0x011C
+#define MT6392_TOP_RST_MISC_CLR 0x011E
+#define MT6392_TOP_CKCON0 0x0120
+#define MT6392_TOP_CKCON0_SET 0x0122
+#define MT6392_TOP_CKCON0_CLR 0x0124
+#define MT6392_TOP_CKCON1 0x0126
+#define MT6392_TOP_CKCON1_SET 0x0128
+#define MT6392_TOP_CKCON1_CLR 0x012A
+#define MT6392_TOP_CKTST0 0x012C
+#define MT6392_TOP_CKTST1 0x012E
+#define MT6392_TOP_CKTST2 0x0130
+#define MT6392_TEST_OUT 0x0132
+#define MT6392_TEST_CON0 0x0134
+#define MT6392_TEST_CON1 0x0136
+#define MT6392_EN_STATUS0 0x0138
+#define MT6392_EN_STATUS1 0x013A
+#define MT6392_OCSTATUS0 0x013C
+#define MT6392_OCSTATUS1 0x013E
+#define MT6392_PGSTATUS 0x0140
+#define MT6392_CHRSTATUS 0x0142
+#define MT6392_TDSEL_CON 0x0144
+#define MT6392_RDSEL_CON 0x0146
+#define MT6392_SMT_CON0 0x0148
+#define MT6392_SMT_CON1 0x014A
+#define MT6392_DRV_CON0 0x0152
+#define MT6392_DRV_CON1 0x0154
+#define MT6392_INT_CON0 0x0160
+#define MT6392_INT_CON0_SET 0x0162
+#define MT6392_INT_CON0_CLR 0x0164
+#define MT6392_INT_CON1 0x0166
+#define MT6392_INT_CON1_SET 0x0168
+#define MT6392_INT_CON1_CLR 0x016A
+#define MT6392_INT_MISC_CON 0x016C
+#define MT6392_INT_MISC_CON_SET 0x016E
+#define MT6392_INT_MISC_CON_CLR 0x0170
+#define MT6392_INT_STATUS0 0x0172
+#define MT6392_INT_STATUS1 0x0174
+#define MT6392_OC_GEAR_0 0x0176
+#define MT6392_OC_GEAR_1 0x0178
+#define MT6392_OC_GEAR_2 0x017A
+#define MT6392_OC_CTL_VPROC 0x017C
+#define MT6392_OC_CTL_VSYS 0x017E
+#define MT6392_OC_CTL_VCORE 0x0180
+#define MT6392_FQMTR_CON0 0x0182
+#define MT6392_FQMTR_CON1 0x0184
+#define MT6392_FQMTR_CON2 0x0186
+#define MT6392_RG_SPI_CON 0x0188
+#define MT6392_DEW_DIO_EN 0x018A
+#define MT6392_DEW_READ_TEST 0x018C
+#define MT6392_DEW_WRITE_TEST 0x018E
+#define MT6392_DEW_CRC_SWRST 0x0190
+#define MT6392_DEW_CRC_EN 0x0192
+#define MT6392_DEW_CRC_VAL 0x0194
+#define MT6392_DEW_DBG_MON_SEL 0x0196
+#define MT6392_DEW_CIPHER_KEY_SEL 0x0198
+#define MT6392_DEW_CIPHER_IV_SEL 0x019A
+#define MT6392_DEW_CIPHER_EN 0x019C
+#define MT6392_DEW_CIPHER_RDY 0x019E
+#define MT6392_DEW_CIPHER_MODE 0x01A0
+#define MT6392_DEW_CIPHER_SWRST 0x01A2
+#define MT6392_DEW_RDDMY_NO 0x01A4
+#define MT6392_DEW_RDATA_DLY_SEL 0x01A6
+#define MT6392_CLK_TRIM_CON0 0x01A8
+#define MT6392_BUCK_CON0 0x0200
+#define MT6392_BUCK_CON1 0x0202
+#define MT6392_BUCK_CON2 0x0204
+#define MT6392_BUCK_CON3 0x0206
+#define MT6392_BUCK_CON4 0x0208
+#define MT6392_BUCK_CON5 0x020A
+#define MT6392_VPROC_CON0 0x020C
+#define MT6392_VPROC_CON1 0x020E
+#define MT6392_VPROC_CON2 0x0210
+#define MT6392_VPROC_CON3 0x0212
+#define MT6392_VPROC_CON4 0x0214
+#define MT6392_VPROC_CON5 0x0216
+#define MT6392_VPROC_CON7 0x021A
+#define MT6392_VPROC_CON8 0x021C
+#define MT6392_VPROC_CON9 0x021E
+#define MT6392_VPROC_CON10 0x0220
+#define MT6392_VPROC_CON11 0x0222
+#define MT6392_VPROC_CON12 0x0224
+#define MT6392_VPROC_CON13 0x0226
+#define MT6392_VPROC_CON14 0x0228
+#define MT6392_VPROC_CON15 0x022A
+#define MT6392_VPROC_CON18 0x0230
+#define MT6392_VSYS_CON0 0x0232
+#define MT6392_VSYS_CON1 0x0234
+#define MT6392_VSYS_CON2 0x0236
+#define MT6392_VSYS_CON3 0x0238
+#define MT6392_VSYS_CON4 0x023A
+#define MT6392_VSYS_CON5 0x023C
+#define MT6392_VSYS_CON7 0x0240
+#define MT6392_VSYS_CON8 0x0242
+#define MT6392_VSYS_CON9 0x0244
+#define MT6392_VSYS_CON10 0x0246
+#define MT6392_VSYS_CON11 0x0248
+#define MT6392_VSYS_CON12 0x024A
+#define MT6392_VSYS_CON13 0x024C
+#define MT6392_VSYS_CON14 0x024E
+#define MT6392_VSYS_CON15 0x0250
+#define MT6392_VSYS_CON18 0x0256
+#define MT6392_BUCK_OC_CON0 0x0258
+#define MT6392_BUCK_OC_CON1 0x025A
+#define MT6392_BUCK_OC_CON2 0x025C
+#define MT6392_BUCK_OC_CON3 0x025E
+#define MT6392_BUCK_OC_CON4 0x0260
+#define MT6392_BUCK_OC_VPROC_CON0 0x0262
+#define MT6392_BUCK_OC_VCORE_CON0 0x0264
+#define MT6392_BUCK_OC_VSYS_CON0 0x0266
+#define MT6392_BUCK_ANA_MON_CON0 0x0268
+#define MT6392_BUCK_EFUSE_OC_CON0 0x026A
+#define MT6392_VCORE_CON0 0x0300
+#define MT6392_VCORE_CON1 0x0302
+#define MT6392_VCORE_CON2 0x0304
+#define MT6392_VCORE_CON3 0x0306
+#define MT6392_VCORE_CON4 0x0308
+#define MT6392_VCORE_CON5 0x030A
+#define MT6392_VCORE_CON7 0x030E
+#define MT6392_VCORE_CON8 0x0310
+#define MT6392_VCORE_CON9 0x0312
+#define MT6392_VCORE_CON10 0x0314
+#define MT6392_VCORE_CON11 0x0316
+#define MT6392_VCORE_CON12 0x0318
+#define MT6392_VCORE_CON13 0x031A
+#define MT6392_VCORE_CON14 0x031C
+#define MT6392_VCORE_CON15 0x031E
+#define MT6392_VCORE_CON18 0x0324
+#define MT6392_BUCK_K_CON0 0x032A
+#define MT6392_BUCK_K_CON1 0x032C
+#define MT6392_BUCK_K_CON2 0x032E
+#define MT6392_ANALDO_CON0 0x0400
+#define MT6392_ANALDO_CON1 0x0402
+#define MT6392_ANALDO_CON2 0x0404
+#define MT6392_ANALDO_CON3 0x0406
+#define MT6392_ANALDO_CON4 0x0408
+#define MT6392_ANALDO_CON6 0x040C
+#define MT6392_ANALDO_CON7 0x040E
+#define MT6392_ANALDO_CON8 0x0410
+#define MT6392_ANALDO_CON10 0x0412
+#define MT6392_ANALDO_CON15 0x0414
+#define MT6392_ANALDO_CON16 0x0416
+#define MT6392_ANALDO_CON17 0x0418
+#define MT6392_ANALDO_CON21 0x0420
+#define MT6392_ANALDO_CON22 0x0422
+#define MT6392_ANALDO_CON23 0x0424
+#define MT6392_ANALDO_CON24 0x0426
+#define MT6392_ANALDO_CON25 0x0428
+#define MT6392_ANALDO_CON26 0x042A
+#define MT6392_ANALDO_CON27 0x042C
+#define MT6392_ANALDO_CON28 0x042E
+#define MT6392_ANALDO_CON29 0x0430
+#define MT6392_DIGLDO_CON0 0x0500
+#define MT6392_DIGLDO_CON2 0x0502
+#define MT6392_DIGLDO_CON3 0x0504
+#define MT6392_DIGLDO_CON5 0x0506
+#define MT6392_DIGLDO_CON6 0x0508
+#define MT6392_DIGLDO_CON7 0x050A
+#define MT6392_DIGLDO_CON8 0x050C
+#define MT6392_DIGLDO_CON10 0x0510
+#define MT6392_DIGLDO_CON11 0x0512
+#define MT6392_DIGLDO_CON12 0x0514
+#define MT6392_DIGLDO_CON15 0x051A
+#define MT6392_DIGLDO_CON20 0x0524
+#define MT6392_DIGLDO_CON21 0x0526
+#define MT6392_DIGLDO_CON23 0x0528
+#define MT6392_DIGLDO_CON24 0x052A
+#define MT6392_DIGLDO_CON26 0x052C
+#define MT6392_DIGLDO_CON27 0x052E
+#define MT6392_DIGLDO_CON28 0x0530
+#define MT6392_DIGLDO_CON29 0x0532
+#define MT6392_DIGLDO_CON30 0x0534
+#define MT6392_DIGLDO_CON31 0x0536
+#define MT6392_DIGLDO_CON32 0x0538
+#define MT6392_DIGLDO_CON33 0x053A
+#define MT6392_DIGLDO_CON36 0x0540
+#define MT6392_DIGLDO_CON41 0x0546
+#define MT6392_DIGLDO_CON44 0x054C
+#define MT6392_DIGLDO_CON47 0x0552
+#define MT6392_DIGLDO_CON48 0x0554
+#define MT6392_DIGLDO_CON49 0x0556
+#define MT6392_DIGLDO_CON50 0x0558
+#define MT6392_DIGLDO_CON51 0x055A
+#define MT6392_DIGLDO_CON52 0x055C
+#define MT6392_DIGLDO_CON53 0x055E
+#define MT6392_DIGLDO_CON54 0x0560
+#define MT6392_DIGLDO_CON55 0x0562
+#define MT6392_DIGLDO_CON56 0x0564
+#define MT6392_DIGLDO_CON57 0x0566
+#define MT6392_DIGLDO_CON58 0x0568
+#define MT6392_DIGLDO_CON59 0x056A
+#define MT6392_DIGLDO_CON60 0x056C
+#define MT6392_DIGLDO_CON61 0x056E
+#define MT6392_DIGLDO_CON62 0x0570
+#define MT6392_DIGLDO_CON63 0x0572
+#define MT6392_EFUSE_CON0 0x0600
+#define MT6392_EFUSE_CON1 0x0602
+#define MT6392_EFUSE_CON2 0x0604
+#define MT6392_EFUSE_CON3 0x0606
+#define MT6392_EFUSE_CON4 0x0608
+#define MT6392_EFUSE_CON5 0x060A
+#define MT6392_EFUSE_CON6 0x060C
+#define MT6392_EFUSE_VAL_0_15 0x060E
+#define MT6392_EFUSE_VAL_16_31 0x0610
+#define MT6392_EFUSE_VAL_32_47 0x0612
+#define MT6392_EFUSE_VAL_48_63 0x0614
+#define MT6392_EFUSE_VAL_64_79 0x0616
+#define MT6392_EFUSE_VAL_80_95 0x0618
+#define MT6392_EFUSE_VAL_96_111 0x061A
+#define MT6392_EFUSE_VAL_112_127 0x061C
+#define MT6392_EFUSE_VAL_128_143 0x061E
+#define MT6392_EFUSE_VAL_144_159 0x0620
+#define MT6392_EFUSE_VAL_160_175 0x0622
+#define MT6392_EFUSE_VAL_176_191 0x0624
+#define MT6392_EFUSE_VAL_192_207 0x0626
+#define MT6392_EFUSE_VAL_208_223 0x0628
+#define MT6392_EFUSE_VAL_224_239 0x062A
+#define MT6392_EFUSE_VAL_240_255 0x062C
+#define MT6392_EFUSE_VAL_256_271 0x062E
+#define MT6392_EFUSE_VAL_272_287 0x0630
+#define MT6392_EFUSE_VAL_288_303 0x0632
+#define MT6392_EFUSE_VAL_304_319 0x0634
+#define MT6392_EFUSE_VAL_320_335 0x0636
+#define MT6392_EFUSE_VAL_336_351 0x0638
+#define MT6392_EFUSE_VAL_352_367 0x063A
+#define MT6392_EFUSE_VAL_368_383 0x063C
+#define MT6392_EFUSE_VAL_384_399 0x063E
+#define MT6392_EFUSE_VAL_400_415 0x0640
+#define MT6392_EFUSE_VAL_416_431 0x0642
+#define MT6392_RTC_MIX_CON0 0x0644
+#define MT6392_RTC_MIX_CON1 0x0646
+#define MT6392_EFUSE_VAL_432_447 0x0648
+#define MT6392_EFUSE_VAL_448_463 0x064A
+#define MT6392_EFUSE_VAL_464_479 0x064C
+#define MT6392_EFUSE_VAL_480_495 0x064E
+#define MT6392_EFUSE_VAL_496_511 0x0650
+#define MT6392_EFUSE_DOUT_0_15 0x0652
+#define MT6392_EFUSE_DOUT_16_31 0x0654
+#define MT6392_EFUSE_DOUT_32_47 0x0656
+#define MT6392_EFUSE_DOUT_48_63 0x0658
+#define MT6392_EFUSE_DOUT_64_79 0x065A
+#define MT6392_EFUSE_DOUT_80_95 0x065C
+#define MT6392_EFUSE_DOUT_96_111 0x065E
+#define MT6392_EFUSE_DOUT_112_127 0x0660
+#define MT6392_EFUSE_DOUT_128_143 0x0662
+#define MT6392_EFUSE_DOUT_144_159 0x0664
+#define MT6392_EFUSE_DOUT_160_175 0x0666
+#define MT6392_EFUSE_DOUT_176_191 0x0668
+#define MT6392_EFUSE_DOUT_192_207 0x066A
+#define MT6392_EFUSE_DOUT_208_223 0x066C
+#define MT6392_EFUSE_DOUT_224_239 0x066E
+#define MT6392_EFUSE_DOUT_240_255 0x0670
+#define MT6392_EFUSE_DOUT_256_271 0x0672
+#define MT6392_EFUSE_DOUT_272_287 0x0674
+#define MT6392_EFUSE_DOUT_288_303 0x0676
+#define MT6392_EFUSE_DOUT_304_319 0x0678
+#define MT6392_EFUSE_DOUT_320_335 0x067A
+#define MT6392_EFUSE_DOUT_336_351 0x067C
+#define MT6392_EFUSE_DOUT_352_367 0x067E
+#define MT6392_EFUSE_DOUT_368_383 0x0680
+#define MT6392_EFUSE_DOUT_384_399 0x0682
+#define MT6392_EFUSE_DOUT_400_415 0x0684
+#define MT6392_EFUSE_DOUT_416_431 0x0686
+#define MT6392_EFUSE_DOUT_432_447 0x0688
+#define MT6392_EFUSE_DOUT_448_463 0x068A
+#define MT6392_EFUSE_DOUT_464_479 0x068C
+#define MT6392_EFUSE_DOUT_480_495 0x068E
+#define MT6392_EFUSE_DOUT_496_511 0x0690
+#define MT6392_EFUSE_CON7 0x0692
+#define MT6392_EFUSE_CON8 0x0694
+#define MT6392_EFUSE_CON9 0x0696
+#define MT6392_AUXADC_ADC0 0x0700
+#define MT6392_AUXADC_ADC1 0x0702
+#define MT6392_AUXADC_ADC2 0x0704
+#define MT6392_AUXADC_ADC3 0x0706
+#define MT6392_AUXADC_ADC4 0x0708
+#define MT6392_AUXADC_ADC5 0x070A
+#define MT6392_AUXADC_ADC6 0x070C
+#define MT6392_AUXADC_ADC7 0x070E
+#define MT6392_AUXADC_ADC8 0x0710
+#define MT6392_AUXADC_ADC9 0x0712
+#define MT6392_AUXADC_ADC10 0x0714
+#define MT6392_AUXADC_ADC11 0x0716
+#define MT6392_AUXADC_ADC12 0x0718
+#define MT6392_AUXADC_ADC13 0x071A
+#define MT6392_AUXADC_ADC14 0x071C
+#define MT6392_AUXADC_ADC15 0x071E
+#define MT6392_AUXADC_ADC16 0x0720
+#define MT6392_AUXADC_ADC17 0x0722
+#define MT6392_AUXADC_ADC18 0x0724
+#define MT6392_AUXADC_ADC19 0x0726
+#define MT6392_AUXADC_ADC20 0x0728
+#define MT6392_AUXADC_ADC21 0x072A
+#define MT6392_AUXADC_ADC22 0x072C
+#define MT6392_AUXADC_STA0 0x072E
+#define MT6392_AUXADC_STA1 0x0730
+#define MT6392_AUXADC_RQST0 0x0732
+#define MT6392_AUXADC_RQST0_SET 0x0734
+#define MT6392_AUXADC_RQST0_CLR 0x0736
+#define MT6392_AUXADC_CON0 0x0738
+#define MT6392_AUXADC_CON0_SET 0x073A
+#define MT6392_AUXADC_CON0_CLR 0x073C
+#define MT6392_AUXADC_CON1 0x073E
+#define MT6392_AUXADC_CON2 0x0740
+#define MT6392_AUXADC_CON3 0x0742
+#define MT6392_AUXADC_CON4 0x0744
+#define MT6392_AUXADC_CON5 0x0746
+#define MT6392_AUXADC_CON6 0x0748
+#define MT6392_AUXADC_CON7 0x074A
+#define MT6392_AUXADC_CON8 0x074C
+#define MT6392_AUXADC_CON9 0x074E
+#define MT6392_AUXADC_CON10 0x0750
+#define MT6392_AUXADC_CON11 0x0752
+#define MT6392_AUXADC_CON12 0x0754
+#define MT6392_AUXADC_CON13 0x0756
+#define MT6392_AUXADC_CON14 0x0758
+#define MT6392_AUXADC_CON15 0x075A
+#define MT6392_AUXADC_CON16 0x075C
+#define MT6392_AUXADC_AUTORPT0 0x075E
+#define MT6392_AUXADC_LBAT0 0x0760
+#define MT6392_AUXADC_LBAT1 0x0762
+#define MT6392_AUXADC_LBAT2 0x0764
+#define MT6392_AUXADC_LBAT3 0x0766
+#define MT6392_AUXADC_LBAT4 0x0768
+#define MT6392_AUXADC_LBAT5 0x076A
+#define MT6392_AUXADC_LBAT6 0x076C
+#define MT6392_AUXADC_THR0 0x076E
+#define MT6392_AUXADC_THR1 0x0770
+#define MT6392_AUXADC_THR2 0x0772
+#define MT6392_AUXADC_THR3 0x0774
+#define MT6392_AUXADC_THR4 0x0776
+#define MT6392_AUXADC_THR5 0x0778
+#define MT6392_AUXADC_THR6 0x077A
+#define MT6392_AUXADC_EFUSE0 0x077C
+#define MT6392_AUXADC_EFUSE1 0x077E
+#define MT6392_AUXADC_EFUSE2 0x0780
+#define MT6392_AUXADC_EFUSE3 0x0782
+#define MT6392_AUXADC_EFUSE4 0x0784
+#define MT6392_AUXADC_EFUSE5 0x0786
+#define MT6392_AUXADC_NAG_0 0x0788
+#define MT6392_AUXADC_NAG_1 0x078A
+#define MT6392_AUXADC_NAG_2 0x078C
+#define MT6392_AUXADC_NAG_3 0x078E
+#define MT6392_AUXADC_NAG_4 0x0790
+#define MT6392_AUXADC_NAG_5 0x0792
+#define MT6392_AUXADC_NAG_6 0x0794
+#define MT6392_AUXADC_NAG_7 0x0796
+#define MT6392_AUXADC_NAG_8 0x0798
+#define MT6392_AUXADC_TYPEC_H_1 0x079A
+#define MT6392_AUXADC_TYPEC_H_2 0x079C
+#define MT6392_AUXADC_TYPEC_H_3 0x079E
+#define MT6392_AUXADC_TYPEC_H_4 0x07A0
+#define MT6392_AUXADC_TYPEC_H_5 0x07A2
+#define MT6392_AUXADC_TYPEC_H_6 0x07A4
+#define MT6392_AUXADC_TYPEC_H_7 0x07A6
+#define MT6392_AUXADC_TYPEC_L_1 0x07A8
+#define MT6392_AUXADC_TYPEC_L_2 0x07AA
+#define MT6392_AUXADC_TYPEC_L_3 0x07AC
+#define MT6392_AUXADC_TYPEC_L_4 0x07AE
+#define MT6392_AUXADC_TYPEC_L_5 0x07B0
+#define MT6392_AUXADC_TYPEC_L_6 0x07B2
+#define MT6392_AUXADC_TYPEC_L_7 0x07B4
+#define MT6392_AUXADC_NAG_9 0x07B6
+#define MT6392_TYPE_C_PHY_RG_0 0x0800
+#define MT6392_TYPE_C_PHY_RG_CC_RESERVE_CSR 0x0802
+#define MT6392_TYPE_C_VCMP_CTRL 0x0804
+#define MT6392_TYPE_C_CTRL 0x0806
+#define MT6392_TYPE_C_CC_SW_CTRL 0x080a
+#define MT6392_TYPE_C_CC_VOL_PERIODIC_MEAS_VAL 0x080c
+#define MT6392_TYPE_C_CC_VOL_DEBOUNCE_CNT_VAL 0x080e
+#define MT6392_TYPE_C_DRP_SRC_CNT_VAL_0 0x0810
+#define MT6392_TYPE_C_DRP_SNK_CNT_VAL_0 0x0814
+#define MT6392_TYPE_C_DRP_TRY_CNT_VAL_0 0x0818
+#define MT6392_TYPE_C_CC_SRC_DEFAULT_DAC_VAL 0x0820
+#define MT6392_TYPE_C_CC_SRC_15_DAC_VAL 0x0822
+#define MT6392_TYPE_C_CC_SRC_30_DAC_VAL 0x0824
+#define MT6392_TYPE_C_CC_SNK_DAC_VAL_0 0x0828
+#define MT6392_TYPE_C_CC_SNK_DAC_VAL_1 0x082a
+#define MT6392_TYPE_C_INTR_EN_0 0x0830
+#define MT6392_TYPE_C_INTR_EN_2 0x0834
+#define MT6392_TYPE_C_INTR_0 0x0838
+#define MT6392_TYPE_C_INTR_2 0x083C
+#define MT6392_TYPE_C_CC_STATUS 0x0840
+#define MT6392_TYPE_C_PWR_STATUS 0x0842
+#define MT6392_TYPE_C_PHY_RG_CC1_RESISTENCE_0 0x0844
+#define MT6392_TYPE_C_PHY_RG_CC1_RESISTENCE_1 0x0846
+#define MT6392_TYPE_C_PHY_RG_CC2_RESISTENCE_0 0x0848
+#define MT6392_TYPE_C_PHY_RG_CC2_RESISTENCE_1 0x084a
+#define MT6392_TYPE_C_CC_SW_FORCE_MODE_ENABLE_0 0x0860
+#define MT6392_TYPE_C_CC_SW_FORCE_MODE_VAL_0 0x0864
+#define MT6392_TYPE_C_CC_SW_FORCE_MODE_VAL_1 0x0866
+#define MT6392_TYPE_C_CC_SW_FORCE_MODE_ENABLE_1 0x0868
+#define MT6392_TYPE_C_CC_SW_FORCE_MODE_VAL_2 0x086c
+#define MT6392_TYPE_C_CC_DAC_CALI_CTRL 0x0870
+#define MT6392_TYPE_C_CC_DAC_CALI_RESULT 0x0872
+#define MT6392_TYPE_C_DEBUG_PORT_SELECT_0 0x0880
+#define MT6392_TYPE_C_DEBUG_PORT_SELECT_1 0x0882
+#define MT6392_TYPE_C_DEBUG_MODE_SELECT 0x0884
+#define MT6392_TYPE_C_DEBUG_OUT_READ_0 0x0888
+#define MT6392_TYPE_C_DEBUG_OUT_READ_1 0x088a
+#define MT6392_TYPE_C_SW_DEBUG_PORT_0 0x088c
+#define MT6392_TYPE_C_SW_DEBUG_PORT_1 0x088e
+
+#endif /* __MFD_MT6392_REGISTERS_H__ */
diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h
index 340fc72e22aa..3729a6856c13 100644
--- a/include/linux/mfd/mt6397/core.h
+++ b/include/linux/mfd/mt6397/core.h
@@ -20,6 +20,7 @@ enum chip_id {
MT6359_CHIP_ID = 0x59,
MT6366_CHIP_ID = 0x66,
MT6391_CHIP_ID = 0x91,
+ MT6392_CHIP_ID = 0x92,
MT6397_CHIP_ID = 0x97,
};
--
2.43.0
^ permalink raw reply related
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