* [PATCH v6 04/16] clk: qcom: dispcc-qcm2290: Enable runtime PM support
From: Imran Shaik @ 2026-07-18 12:56 UTC (permalink / raw)
To: Bjorn Andersson, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Loic Poulain,
Brian Masney, Dmitry Baryshkov
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm, linux-clk,
devicetree, linux-kernel, Imran Shaik
In-Reply-To: <20260718-shikra-dispcc-gpucc-v6-0-62703e05ef0f@oss.qualcomm.com>
The QCM2290 DISPCC is now associated with a power domain (RPMPD_CX) to
propagate genpd performance state votes to the CX rail. Set use_rpm to
true so that a runtime PM reference is acquired and released around probe,
instead of leaving a permanent 'enable' vote on the power domain.
Fixes: cc517ea3333f ("clk: qcom: Add display clock controller driver for QCM2290")
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
drivers/clk/qcom/dispcc-qcm2290.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/clk/qcom/dispcc-qcm2290.c b/drivers/clk/qcom/dispcc-qcm2290.c
index 50a0705128a37073a077b560d0c9e57544d54348..2350ce7f46d9f6e395c87c7a00669b10e8bce3d3 100644
--- a/drivers/clk/qcom/dispcc-qcm2290.c
+++ b/drivers/clk/qcom/dispcc-qcm2290.c
@@ -515,6 +515,7 @@ static const struct qcom_cc_desc disp_cc_qcm2290_desc = {
.num_gdscs = ARRAY_SIZE(disp_cc_qcm2290_gdscs),
.resets = disp_cc_qcm2290_resets,
.num_resets = ARRAY_SIZE(disp_cc_qcm2290_resets),
+ .use_rpm = true,
.driver_data = &disp_cc_qcm2290_driver_data,
};
--
2.34.1
^ permalink raw reply related
* [PATCH v6 03/16] clk: qcom: dispcc-qcm2290: Move to the latest common qcom_cc_probe() model
From: Imran Shaik @ 2026-07-18 12:56 UTC (permalink / raw)
To: Bjorn Andersson, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Loic Poulain,
Brian Masney, Dmitry Baryshkov
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm, linux-clk,
devicetree, linux-kernel, Imran Shaik, Konrad Dybcio,
Dmitry Baryshkov
In-Reply-To: <20260718-shikra-dispcc-gpucc-v6-0-62703e05ef0f@oss.qualcomm.com>
Update the QCM2290 DISPCC driver to use the qcom_cc_probe() model by moving
the critical clocks handling and PLL configurations from probe to the
driver_data to align with the latest convention.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
drivers/clk/qcom/dispcc-qcm2290.c | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/clk/qcom/dispcc-qcm2290.c b/drivers/clk/qcom/dispcc-qcm2290.c
index 4d6aad280ae178426bb70528fcd9699627359ef2..50a0705128a37073a077b560d0c9e57544d54348 100644
--- a/drivers/clk/qcom/dispcc-qcm2290.c
+++ b/drivers/clk/qcom/dispcc-qcm2290.c
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2021, Linaro Ltd.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/clk-provider.h>
@@ -48,6 +49,7 @@ static const struct alpha_pll_config disp_cc_pll0_config = {
static struct clk_alpha_pll disp_cc_pll0 = {
.offset = 0x0,
+ .config = &disp_cc_pll0_config,
.vco_table = spark_vco,
.num_vco = ARRAY_SIZE(spark_vco),
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
@@ -482,6 +484,14 @@ static struct clk_regmap *disp_cc_qcm2290_clocks[] = {
[DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,
};
+static struct clk_alpha_pll *disp_cc_qcm2290_plls[] = {
+ &disp_cc_pll0,
+};
+
+static const u32 disp_cc_qcm2290_critical_cbcrs[] = {
+ 0x604c, /* DISP_CC_XO_CLK */
+};
+
static const struct regmap_config disp_cc_qcm2290_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -490,6 +500,13 @@ static const struct regmap_config disp_cc_qcm2290_regmap_config = {
.fast_io = true,
};
+static const struct qcom_cc_driver_data disp_cc_qcm2290_driver_data = {
+ .alpha_plls = disp_cc_qcm2290_plls,
+ .num_alpha_plls = ARRAY_SIZE(disp_cc_qcm2290_plls),
+ .clk_cbcrs = disp_cc_qcm2290_critical_cbcrs,
+ .num_clk_cbcrs = ARRAY_SIZE(disp_cc_qcm2290_critical_cbcrs),
+};
+
static const struct qcom_cc_desc disp_cc_qcm2290_desc = {
.config = &disp_cc_qcm2290_regmap_config,
.clks = disp_cc_qcm2290_clocks,
@@ -498,6 +515,7 @@ static const struct qcom_cc_desc disp_cc_qcm2290_desc = {
.num_gdscs = ARRAY_SIZE(disp_cc_qcm2290_gdscs),
.resets = disp_cc_qcm2290_resets,
.num_resets = ARRAY_SIZE(disp_cc_qcm2290_resets),
+ .driver_data = &disp_cc_qcm2290_driver_data,
};
static const struct of_device_id disp_cc_qcm2290_match_table[] = {
@@ -508,25 +526,7 @@ MODULE_DEVICE_TABLE(of, disp_cc_qcm2290_match_table);
static int disp_cc_qcm2290_probe(struct platform_device *pdev)
{
- struct regmap *regmap;
- int ret;
-
- regmap = qcom_cc_map(pdev, &disp_cc_qcm2290_desc);
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- clk_alpha_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
-
- /* Keep some clocks always-on */
- qcom_branch_set_clk_en(regmap, 0x604c); /* DISP_CC_XO_CLK */
-
- ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_qcm2290_desc, regmap);
- if (ret) {
- dev_err(&pdev->dev, "Failed to register DISP CC clocks\n");
- return ret;
- }
-
- return ret;
+ return qcom_cc_probe(pdev, &disp_cc_qcm2290_desc);
}
static struct platform_driver disp_cc_qcm2290_driver = {
--
2.34.1
^ permalink raw reply related
* [PATCH v6 02/16] clk: qcom: gcc-qcm2290: Keep the critical clocks always-on from probe
From: Imran Shaik @ 2026-07-18 12:56 UTC (permalink / raw)
To: Bjorn Andersson, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Loic Poulain,
Brian Masney, Dmitry Baryshkov
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm, linux-clk,
devicetree, linux-kernel, Imran Shaik, Konrad Dybcio,
Dmitry Baryshkov
In-Reply-To: <20260718-shikra-dispcc-gpucc-v6-0-62703e05ef0f@oss.qualcomm.com>
Some GCC branch clocks are required to be kept always-on due to the
hardware requirements. Drop the modelling of those always-on QCM2290 GCC
clocks and use the latest .clk_cbcr convention to keep them enabled from
probe.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
drivers/clk/qcom/gcc-qcm2290.c | 113 ++++++-----------------------------------
1 file changed, 15 insertions(+), 98 deletions(-)
diff --git a/drivers/clk/qcom/gcc-qcm2290.c b/drivers/clk/qcom/gcc-qcm2290.c
index 6684cab63ae1160848631d1f8cd3c9cb691ff4ec..c6de8d368ec4c69d38f59a8efaed6d66ab14a5b8 100644
--- a/drivers/clk/qcom/gcc-qcm2290.c
+++ b/drivers/clk/qcom/gcc-qcm2290.c
@@ -1397,36 +1397,6 @@ static struct clk_branch gcc_cam_throttle_rt_clk = {
},
};
-static struct clk_branch gcc_camera_ahb_clk = {
- .halt_reg = 0x17008,
- .halt_check = BRANCH_HALT_DELAY,
- .hwcg_reg = 0x17008,
- .hwcg_bit = 1,
- .clkr = {
- .enable_reg = 0x17008,
- .enable_mask = BIT(0),
- .hw.init = &(struct clk_init_data){
- .name = "gcc_camera_ahb_clk",
- .flags = CLK_IS_CRITICAL,
- .ops = &clk_branch2_ops,
- },
- },
-};
-
-static struct clk_branch gcc_camera_xo_clk = {
- .halt_reg = 0x17028,
- .halt_check = BRANCH_HALT,
- .clkr = {
- .enable_reg = 0x17028,
- .enable_mask = BIT(0),
- .hw.init = &(struct clk_init_data){
- .name = "gcc_camera_xo_clk",
- .flags = CLK_IS_CRITICAL,
- .ops = &clk_branch2_ops,
- },
- },
-};
-
static struct clk_branch gcc_camss_axi_clk = {
.halt_reg = 0x58044,
.halt_check = BRANCH_HALT,
@@ -1825,22 +1795,6 @@ static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = {
},
};
-static struct clk_branch gcc_disp_ahb_clk = {
- .halt_reg = 0x1700c,
- .halt_check = BRANCH_HALT,
- .hwcg_reg = 0x1700c,
- .hwcg_bit = 1,
- .clkr = {
- .enable_reg = 0x1700c,
- .enable_mask = BIT(0),
- .hw.init = &(struct clk_init_data){
- .name = "gcc_disp_ahb_clk",
- .flags = CLK_IS_CRITICAL,
- .ops = &clk_branch2_ops,
- },
- },
-};
-
static struct clk_regmap_div gcc_disp_gpll0_clk_src = {
.reg = 0x17058,
.shift = 0,
@@ -1899,20 +1853,6 @@ static struct clk_branch gcc_disp_throttle_core_clk = {
},
};
-static struct clk_branch gcc_disp_xo_clk = {
- .halt_reg = 0x1702c,
- .halt_check = BRANCH_HALT,
- .clkr = {
- .enable_reg = 0x1702c,
- .enable_mask = BIT(0),
- .hw.init = &(struct clk_init_data){
- .name = "gcc_disp_xo_clk",
- .flags = CLK_IS_CRITICAL,
- .ops = &clk_branch2_ops,
- },
- },
-};
-
static struct clk_branch gcc_gp1_clk = {
.halt_reg = 0x4d000,
.halt_check = BRANCH_HALT,
@@ -1964,22 +1904,6 @@ static struct clk_branch gcc_gp3_clk = {
},
};
-static struct clk_branch gcc_gpu_cfg_ahb_clk = {
- .halt_reg = 0x36004,
- .halt_check = BRANCH_HALT,
- .hwcg_reg = 0x36004,
- .hwcg_bit = 1,
- .clkr = {
- .enable_reg = 0x36004,
- .enable_mask = BIT(0),
- .hw.init = &(struct clk_init_data){
- .name = "gcc_gpu_cfg_ahb_clk",
- .flags = CLK_IS_CRITICAL,
- .ops = &clk_branch2_ops,
- },
- },
-};
-
static struct clk_branch gcc_gpu_gpll0_clk_src = {
.halt_check = BRANCH_HALT_DELAY,
.clkr = {
@@ -2439,22 +2363,6 @@ static struct clk_branch gcc_sdcc2_apps_clk = {
},
};
-static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = {
- .halt_reg = 0x2b06c,
- .halt_check = BRANCH_HALT_VOTED,
- .hwcg_reg = 0x2b06c,
- .hwcg_bit = 1,
- .clkr = {
- .enable_reg = 0x79004,
- .enable_mask = BIT(0),
- .hw.init = &(struct clk_init_data){
- .name = "gcc_sys_noc_cpuss_ahb_clk",
- .flags = CLK_IS_CRITICAL,
- .ops = &clk_branch2_ops,
- },
- },
-};
-
static struct clk_branch gcc_sys_noc_usb3_prim_axi_clk = {
.halt_reg = 0x1a080,
.halt_check = BRANCH_HALT,
@@ -2775,8 +2683,6 @@ static struct clk_regmap *gcc_qcm2290_clocks[] = {
[GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
[GCC_CAM_THROTTLE_NRT_CLK] = &gcc_cam_throttle_nrt_clk.clkr,
[GCC_CAM_THROTTLE_RT_CLK] = &gcc_cam_throttle_rt_clk.clkr,
- [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr,
- [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr,
[GCC_CAMSS_AXI_CLK] = &gcc_camss_axi_clk.clkr,
[GCC_CAMSS_AXI_CLK_SRC] = &gcc_camss_axi_clk_src.clkr,
[GCC_CAMSS_CAMNOC_ATB_CLK] = &gcc_camss_camnoc_atb_clk.clkr,
@@ -2817,19 +2723,16 @@ static struct clk_regmap *gcc_qcm2290_clocks[] = {
[GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr,
[GCC_CAMSS_TOP_AHB_CLK_SRC] = &gcc_camss_top_ahb_clk_src.clkr,
[GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr,
- [GCC_DISP_AHB_CLK] = &gcc_disp_ahb_clk.clkr,
[GCC_DISP_GPLL0_CLK_SRC] = &gcc_disp_gpll0_clk_src.clkr,
[GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr,
[GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr,
[GCC_DISP_THROTTLE_CORE_CLK] = &gcc_disp_throttle_core_clk.clkr,
- [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr,
[GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
[GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr,
[GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
[GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr,
[GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
[GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr,
- [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr,
[GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr,
[GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr,
[GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr,
@@ -2870,7 +2773,6 @@ static struct clk_regmap *gcc_qcm2290_clocks[] = {
[GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
[GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
[GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr,
- [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr,
[GCC_SYS_NOC_USB3_PRIM_AXI_CLK] = &gcc_sys_noc_usb3_prim_axi_clk.clkr,
[GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr,
[GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr,
@@ -2943,6 +2845,15 @@ static struct gdsc *gcc_qcm2290_gdscs[] = {
[HLOS1_VOTE_MM_SNOC_MMU_TBU_NRT_GDSC] = &hlos1_vote_mm_snoc_mmu_tbu_nrt_gdsc,
};
+static const u32 gcc_qcm2290_critical_cbcrs[] = {
+ 0x17008, /* GCC_CAMERA_AHB_CLK */
+ 0x17028, /* GCC_CAMERA_XO_CLK */
+ 0x1700c, /* GCC_DISP_AHB_CLK */
+ 0x1702c, /* GCC_DISP_XO_CLK */
+ 0x36004, /* GCC_GPU_CFG_AHB_CLK */
+ 0x79004, /* GCC_SYS_NOC_CPUSS_AHB_CLK */
+};
+
static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src),
@@ -2960,6 +2871,11 @@ static const struct regmap_config gcc_qcm2290_regmap_config = {
.fast_io = true,
};
+static const struct qcom_cc_driver_data gcc_qcm2290_driver_data = {
+ .clk_cbcrs = gcc_qcm2290_critical_cbcrs,
+ .num_clk_cbcrs = ARRAY_SIZE(gcc_qcm2290_critical_cbcrs),
+};
+
static const struct qcom_cc_desc gcc_qcm2290_desc = {
.config = &gcc_qcm2290_regmap_config,
.clks = gcc_qcm2290_clocks,
@@ -2968,6 +2884,7 @@ static const struct qcom_cc_desc gcc_qcm2290_desc = {
.num_resets = ARRAY_SIZE(gcc_qcm2290_resets),
.gdscs = gcc_qcm2290_gdscs,
.num_gdscs = ARRAY_SIZE(gcc_qcm2290_gdscs),
+ .driver_data = &gcc_qcm2290_driver_data,
};
static const struct of_device_id gcc_qcm2290_match_table[] = {
--
2.34.1
^ permalink raw reply related
* [PATCH v6 01/16] dt-bindings: clock: qcom,qcm2290-dispcc: Add missing power-domains property
From: Imran Shaik @ 2026-07-18 12:56 UTC (permalink / raw)
To: Bjorn Andersson, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Loic Poulain,
Brian Masney, Dmitry Baryshkov
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm, linux-clk,
devicetree, linux-kernel, Imran Shaik, Krzysztof Kozlowski
In-Reply-To: <20260718-shikra-dispcc-gpucc-v6-0-62703e05ef0f@oss.qualcomm.com>
Add the missing power-domains property to associate DISPCC with RPMPD_CX.
This is to ensure the genpd performance state votes on the GDSC to get
propagated to the CX rail and to avoid the rail under-voltage conditions.
This change breaks ABI, as the power-domains property is marked as
required.
Fixes: 85cedb4e0c9d ("dt-bindings: clock: Add qualcomm QCM2290 DISPCC bindings")
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
Documentation/devicetree/bindings/clock/qcom,qcm2290-dispcc.yaml | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/qcom,qcm2290-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,qcm2290-dispcc.yaml
index 4a533b45eec2d8e7b866c3436bfe6f80fcd714fb..e9c2326adfd285444257b96f5adc68e27213281f 100644
--- a/Documentation/devicetree/bindings/clock/qcom,qcm2290-dispcc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,qcm2290-dispcc.yaml
@@ -37,10 +37,15 @@ properties:
- const: dsi0_phy_pll_out_byteclk
- const: dsi0_phy_pll_out_dsiclk
+ power-domains:
+ items:
+ - description: CX domain
+
required:
- compatible
- clocks
- clock-names
+ - power-domains
- '#power-domain-cells'
allOf:
@@ -53,6 +58,7 @@ examples:
#include <dt-bindings/clock/qcom,dispcc-qcm2290.h>
#include <dt-bindings/clock/qcom,gcc-qcm2290.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
+ #include <dt-bindings/power/qcom-rpmpd.h>
clock-controller@5f00000 {
compatible = "qcom,qcm2290-dispcc";
reg = <0x5f00000 0x20000>;
@@ -68,6 +74,7 @@ examples:
"gcc_disp_gpll0_div_clk_src",
"dsi0_phy_pll_out_byteclk",
"dsi0_phy_pll_out_dsiclk";
+ power-domains = <&rpmpd RPMPD_VDDCX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
--
2.34.1
^ permalink raw reply related
* [PATCH v6 00/16] clk: qcom: Add DISPCC and GPUCC support for the Qualcomm Shikra SoC
From: Imran Shaik @ 2026-07-18 12:56 UTC (permalink / raw)
To: Bjorn Andersson, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Loic Poulain,
Brian Masney, Dmitry Baryshkov
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm, linux-clk,
devicetree, linux-kernel, Imran Shaik, Krzysztof Kozlowski,
Konrad Dybcio, Dmitry Baryshkov
This series adds support for the Display clock controller (DISPCC) and
GPU Clock Controller (GPUCC) on Qualcomm Shikra SoC, by reusing the
respective QCM2290 SoC drivers, and adds fix-ups for the QCM2290 Clock
drivers.
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
Changes in v6:
- Rebased on next-20260716, as the dependent RPMCC/GCC and Shikra base DTS
changes were merged.
- Collected all Reviewed-by tags received on v5.
- Added the Fixes tags to relevant patches [Dmitry/Konrad]
- Reordered the series to place the fix patches at top of the series [Dmitry]
- Updated the DISPCC driver to use use_rpm, as required by the
power-domain fix-up changes [Konrad]
- Dropped the additional external clock, index-based driver, and DTS
changes to avoid an ABI change that has no functional impact [Krzysztof/Konrad]
- Updated the commit text for few patches [Konard/Dmitry]
- Link to v5: https://lore.kernel.org/r/20260703-shikra-dispcc-gpucc-v5-0-cc13826d4d5a@oss.qualcomm.com
Changes in v5:
- Collected all Reviewed-by tags received on v4.
- Updated the commit text of the bindings patches [Krzysztof]
- Converted only the critical GCC clocks to the latest clk_cbcr convention
- Reorganize the series into logically independent patches [Krzysztof/Dmitry]
- Added CX power domain support for DISPCC [Konrad]
- Dropped DSI1 PHY clock input support from the driver, as these clocks
are not referenced by any frequency table.
- Dropped moving dispcc driver to DT index approach patch as the
external sleep_clk is not there in the DTS, and no functional impact.
- Dropped HW_CTRL_TRIGGER patch as it is not applicable [Konrad]
- Link to v4: https://lore.kernel.org/r/20260604-shikra-dispcc-gpucc-v4-0-8204f1029311@oss.qualcomm.com
Changes in v4:
- Included new patch for Shikra DISPCC/GPUCC DT node support
- Link to v3: https://lore.kernel.org/r/20260601-shikra-dispcc-gpucc-v3-0-61c1ba3735e8@oss.qualcomm.com
Changes in v3:
- Updated the QCM2290 GCC patch to use the .clk_cbcr convention
- Extended the QCM2290 GPUCC bindings to add DSI1 PHY and Sleep clocks
- Separated the patches as per the review comments in v2 series
- Added Agatti DISPCC DT node changes as per the latest bindings changes
- Link to v2: https://lore.kernel.org/r/20260528-shikra-dispcc-gpucc-v2-0-953f246a0fbb@oss.qualcomm.com
Changes in v2:
- Dropped QCM2290 GCC critical clocks modelling to kept them ON from probe.
- Updated the QCM2290 DISPCC/GPUCC bindings to align for Shikra drivers reuse.
- Reused the QCM2290 DISPCC driver for Shikra without modernizing
(keeping the clock-names approach) for now to avoid potential bindings ABI breakage.
- Modernized QCM2290 GPUCC driver to use common qcom_cc_probe() model
and reuse for Shikra.
- Link to v1: https://lore.kernel.org/r/20260513-shikra-dispcc-gpucc-v1-0-5fd673146ab2@oss.qualcomm.com
---
Imran Shaik (16):
dt-bindings: clock: qcom,qcm2290-dispcc: Add missing power-domains property
clk: qcom: gcc-qcm2290: Keep the critical clocks always-on from probe
clk: qcom: dispcc-qcm2290: Move to the latest common qcom_cc_probe() model
clk: qcom: dispcc-qcm2290: Enable runtime PM support
clk: qcom: qcm2290: Set POLL_CFG_GDSCR flag for DISPCC and GPUCC GDSCs
clk: qcom: qcm2290: Add RETAIN_FF_ENABLE flag for DISPCC and GPUCC GDSCs
clk: qcom: qcm2290: Update DISPCC and GPUCC GDSC *wait_val values
clk: qcom: gpucc-qcm2290: Drop pm_clk handling
clk: qcom: gpucc-qcm2290: Move to the latest common qcom_cc_probe() model
clk: qcom: gpucc-qcm2290: Keep the critical clocks always-on from probe
clk: qcom: gpucc-qcm2290: Park RCG's clk source at XO during disable
arm64: dts: qcom: agatti: Add missing CX power domain to DISPCC
dt-bindings: clock: qcom: Add Qualcomm Shikra Display clock controller
dt-bindings: clock: qcom: Add Qualcomm Shikra GPU clock controller
clk: qcom: Add support for Qualcomm GPU Clock Controller on Shikra
arm64: dts: qcom: shikra: Add support for DISPCC/GPUCC nodes
.../bindings/clock/qcom,qcm2290-dispcc.yaml | 15 ++-
.../bindings/clock/qcom,qcm2290-gpucc.yaml | 4 +-
arch/arm64/boot/dts/qcom/agatti.dtsi | 1 +
arch/arm64/boot/dts/qcom/shikra.dtsi | 36 +++++++
drivers/clk/qcom/dispcc-qcm2290.c | 44 ++++----
drivers/clk/qcom/gcc-qcm2290.c | 113 +++------------------
drivers/clk/qcom/gpucc-qcm2290.c | 102 ++++++++-----------
7 files changed, 137 insertions(+), 178 deletions(-)
---
base-commit: 1a1757b76427f6201bfe0bf1bea9f7574f332a93
change-id: 20260513-shikra-dispcc-gpucc-6f59c23020f5
Best regards,
--
Imran Shaik <imran.shaik@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH 2/5] arm64: dts: qcom: Add Kalambo SoC
From: sashiko-bot @ 2026-07-18 12:17 UTC (permalink / raw)
To: Gopikrishna Garmidi; +Cc: robh, devicetree, conor+dt
In-Reply-To: <20260718-b4-kalambo-crd-v1-2-a1069b5a2757@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] The bandwidth monitor (`bwmon_cluster0`) for the removed CPU cluster 0 is neither disabled nor removed.
- [High] Thermal sensors (`tsens0`) and thermal zones monitoring the removed CPU cluster 0 are left active.
- [Medium] Incomplete update of SCMI SCP low-priority shared memory register windows creates an asymmetric channel configuration.
--
--- Patch [2]: [PATCH 2/5] arm64: dts: qcom: Add Kalambo SoC ---
commit c5f01045fbad11461a4f9c8629b706f4e0af8944
Author: Gopikrishna Garmidi <gopikrishna.garmidi@oss.qualcomm.com>
arm64: dts: qcom: Add Kalambo SoC
Introduce support for the Qualcomm Kalambo SoC. It is derived from Mahua
with CPU cluster 0 removed, leaving it with just cluster 1. As a result,
the PDP mailbox and SCP low-priority register windows are updated to
match the reduced CPU complex. Everything else should work as-is.
[ ... ]
> diff --git a/arch/arm64/boot/dts/qcom/kalambo.dtsi b/arch/arm64/boot/dts/qcom/kalambo.dtsi
> new file mode 100644
> index 0000000000000..a56ff68b57b47
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/kalambo.dtsi
> @@ -0,0 +1,29 @@
> +// SPDX-License-Identifier: BSD-3-Clause
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +#include "mahua.dtsi"
> +
> +/delete-node/ &cluster0_pd;
> +/delete-node/ &cpu_map_cluster0;
[Severity: High]
Since cluster 0 is removed, does the bandwidth monitor (bwmon_cluster0) also
need to be disabled?
The qcom,glymur-cpu-bwmon driver automatically probes bwmon_cluster0 during
boot. If left active, it will attempt to map and access MMIO registers at
0x0100c400 for a physical cluster that no longer exists in the SoC, which
can result in a hardware/bus fault (SError) and system crash.
Looking at glymur.dtsi, the node cannot be safely deleted with /delete-node/
because it houses the cpu_bwmon_opp_table used by the remaining clusters:
bwmon_cluster0: pmu@100c400 {
compatible = "qcom,glymur-cpu-bwmon", "qcom,sdm845-bwmon";
Should this be explicitly marked with status = "disabled" instead?
[Severity: High]
Similarly, should the thermal sensors (tsens0) and the thermal zones
monitoring cluster 0 be explicitly removed?
The thermal framework will initialize and poll the active cpu-0-*-thermal
zones, which attempt to read from tsens0 registers corresponding to the
absent cluster 0. This can also trigger an SError crashing the system or
cause fatal thermal subsystem errors.
For example, glymur.dtsi defines these zones:
cpu-0-0-0-thermal {
thermal-sensors = <&tsens0 1>;
Should &tsens0 and the un-labeled cluster 0 thermal zones inside
&thermal_zones be deleted?
> +/delete-node/ &cpu0;
> +/delete-node/ &cpu1;
> +/delete-node/ &cpu2;
> +/delete-node/ &cpu3;
> +/delete-node/ &cpu4;
> +/delete-node/ &cpu5;
> +/delete-node/ &cpu_pd0;
> +/delete-node/ &cpu_pd1;
> +/delete-node/ &cpu_pd2;
> +/delete-node/ &cpu_pd3;
> +/delete-node/ &cpu_pd4;
> +/delete-node/ &cpu_pd5;
> +
> +&pdp0_mbox {
> + reg = <0 0x17610000 0 0x8000>, <0 0x1a980000 0 0x8000>;
> +};
> +
> +&cpu_scp_lpri1 {
> + reg = <0x180 0x60>;
> +};
[Severity: Medium]
Does the TX window (cpu_scp_lpri0) need to be updated to match the
reduced CPU complex as well?
The commit shrinks the RX window size (cpu_scp_lpri1) from 0x180 to 0x60,
but misses the TX window, which remains oversized at 0x180:
cpu_scp_lpri0: scp-sram-section@0 {
compatible = "arm,scmi-shmem";
reg = <0x0 0x180>;
};
If the system firmware expects both windows to be symmetrically shrunk and
contiguous, this asymmetric configuration might cause SCMI initialization to
fail.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260718-b4-kalambo-crd-v1-0-a1069b5a2757@oss.qualcomm.com?part=2
^ permalink raw reply
* Re: [PATCH 3/5] arm64: dts: qcom: Add Kalambo CRD
From: sashiko-bot @ 2026-07-18 12:16 UTC (permalink / raw)
To: Gopikrishna Garmidi; +Cc: devicetree, robh, conor+dt
In-Reply-To: <20260718-b4-kalambo-crd-v1-3-a1069b5a2757@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The device tree leaves orphaned nodes for the physically absent PMIC 'D', leading to invalid SPMI device probing and thermal zone registration.
--
--- Patch [3]: [PATCH 3/5] arm64: dts: qcom: Add Kalambo CRD ---
commit aaa6e566ef6b80e52c726e5cb734189e7e8ad2a3
Author: Gopikrishna Garmidi <gopikrishna.garmidi@oss.qualcomm.com>
arm64: dts: qcom: Add Kalambo CRD
Introduce support for the CRD based on the Qualcomm Kalambo SoC.
It reuses the common CRD board description and drops the PMIC nodes
not present on this design.
> diff --git a/arch/arm64/boot/dts/qcom/kalambo-crd.dts b/arch/arm64/boot/dts/qcom/kalambo-crd.dts
> new file mode 100644
> index 0000000000000..b4441807f4602
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/kalambo-crd.dts
> @@ -0,0 +1,21 @@
> +// SPDX-License-Identifier: BSD-3-Clause
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +/dts-v1/;
> +
> +#include "kalambo.dtsi"
> +#include "glymur-crd.dtsi"
> +
> +/delete-node/ &pmcx0102_d_e0;
> +/delete-node/ &pmcx0102_d0_thermal;
[Severity: Medium]
Are the deletions for the SPMI bus 1 endpoint and its thermal zone missing
here?
This drops the SPMI bus 0 endpoint for PMIC D, but seems to leave the bus 1
endpoint (&pmcx0102_d_e1) and its thermal zone (&pmcx0102_d1_thermal) active.
Since the PMIC is physically absent, attempting to probe the orphaned bus 1
device and poll the absent thermal sensor can cause SPMI bus timeouts,
deferred probes, and log spam from the thermal framework.
Should &pmcx0102_d_e1 and &pmcx0102_d1_thermal also be deleted in this block?
> +/delete-node/ &pmh0104_i_e0;
> +/delete-node/ &pmh0104_i0_thermal;
> +/delete-node/ &pmh0104_j_e0;
> +/delete-node/ &pmh0104_j0_thermal;
> +
> +/ {
> + model = "Qualcomm Technologies, Inc. Kalambo CRD";
> + compatible = "qcom,kalambo-crd", "qcom,kalambo";
> +};
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260718-b4-kalambo-crd-v1-0-a1069b5a2757@oss.qualcomm.com?part=3
^ permalink raw reply
* Re: [PATCH 4/5] firmware: qcom: scm: Allow QSEECOM on Kalambo CRD
From: sashiko-bot @ 2026-07-18 12:15 UTC (permalink / raw)
To: Gopikrishna Garmidi; +Cc: devicetree, robh, conor+dt
In-Reply-To: <20260718-b4-kalambo-crd-v1-4-a1069b5a2757@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Incorrect error check for irq_create_fwspec_mapping() return value breaks deferred probing and causes permanent probe failure.
--
--- Patch [4]: [PATCH 4/5] firmware: qcom: scm: Allow QSEECOM on Kalambo CRD ---
commit 64635e7b37ce27df0438767be7b9b4011a0fa5f6
Author: Gopikrishna Garmidi <gopikrishna.garmidi@oss.qualcomm.com>
firmware: qcom: scm: Allow QSEECOM on Kalambo CRD
This commit adds the Kalambo CRD board to the QSEECOM allowlist. This
enables access to efivars on this platform.
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index f35f2ee391304..d1cc6c908daa4 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -2327,6 +2327,7 @@ static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
> { .compatible = "microsoft,romulus15", },
> { .compatible = "qcom,glymur-crd" },
> { .compatible = "qcom,hamoa-iot-evk" },
> + { .compatible = "qcom,kalambo-crd" },
[Severity: High]
This is a pre-existing issue, but I noticed a potential problem in
qcom_scm_probe() related to how the return value of qcom_scm_get_waitq_irq()
is checked.
When qcom_scm probes before the interrupt controller,
irq_create_fwspec_mapping() fails to find the IRQ domain and returns 0 to
indicate a failure to map the IRQ.
drivers/firmware/qcom/qcom_scm.c:qcom_scm_get_waitq_irq() {
...
return irq_create_fwspec_mapping(&fwspec);
}
This means qcom_scm_get_waitq_irq() can return 0. However, in qcom_scm_probe():
drivers/firmware/qcom/qcom_scm.c:qcom_scm_probe() {
...
irq = qcom_scm_get_waitq_irq(scm);
if (irq < 0)
irq = platform_get_irq_optional(pdev, 0);
...
}
Should this check be if irq <= 0?
By only checking irq < 0, a return value of 0 bypasses the fallback to
platform_get_irq_optional(). This function would have correctly deferred the
probe by returning -EPROBE_DEFER.
Does this instead cause the driver to attempt to request IRQ 0 via
devm_request_threaded_irq(), which would fail with -EINVAL and result in a
permanent probe failure for the qcom_scm driver during boot?
> { .compatible = "qcom,mahua-crd" },
> { .compatible = "qcom,purwa-iot-evk" },
> { .compatible = "qcom,sc8180x-primus" },
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260718-b4-kalambo-crd-v1-0-a1069b5a2757@oss.qualcomm.com?part=4
^ permalink raw reply
* Re: [PATCH 1/5] dt-bindings: arm: qcom: Document Kalambo SoC and board
From: sashiko-bot @ 2026-07-18 12:13 UTC (permalink / raw)
To: Gopikrishna Garmidi; +Cc: robh, devicetree, conor+dt
In-Reply-To: <20260718-b4-kalambo-crd-v1-1-a1069b5a2757@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The Kalambo SoC compatible string schema lacks a fallback to its base Mahua SoC, preventing reuse of existing kernel drivers.
--
--- Patch [1]: [PATCH 1/5] dt-bindings: arm: qcom: Document Kalambo SoC and board ---
commit 495e4544978416b176f59d42fe901afdd835094e
Author: Gopikrishna Garmidi <gopikrishna.garmidi@oss.qualcomm.com>
dt-bindings: arm: qcom: Document Kalambo SoC and board
This commit documents the compatible strings for the Qualcomm Kalambo SoC
and its Compute Reference Device (CRD) board. The Kalambo SoC is noted as
a derivative of the Mahua SoC with CPU cluster 0 removed.
> diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
> index c7c9a92796846..b0c07a57bda69 100644
> --- a/Documentation/devicetree/bindings/arm/qcom.yaml
> +++ b/Documentation/devicetree/bindings/arm/qcom.yaml
[ ... ]
> @@ -174,6 +174,11 @@ properties:
> - qcom,kaanapali-qrd
> - const: qcom,kaanapali
>
> + - items:
> + - enum:
> + - qcom,kalambo-crd
> + - const: qcom,kalambo
[Severity: Medium]
Since the commit message mentions Kalambo is a derivative of Mahua, should
this strict two-item list include a fallback to "qcom,mahua"?
Without the fallback, core drivers that match strictly on "qcom,mahua"
(like qcom_pd_mapper and ubwc_config) might fail to probe, or the device
tree will fail dt_binding_check validation if the fallback is actually
included in the device tree nodes.
> +
> - items:
> - enum:
> - qcom,mahua-crd
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260718-b4-kalambo-crd-v1-0-a1069b5a2757@oss.qualcomm.com?part=1
^ permalink raw reply
* [PATCH 5/5] soc: qcom: ubwc: Add Kalambo UBWC config
From: Gopikrishna Garmidi @ 2026-07-18 12:06 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Sibi Sankar, Pankaj Patil
Cc: Rajendra Nayak, linux-arm-msm, devicetree, linux-kernel,
Gopikrishna Garmidi
In-Reply-To: <20260718-b4-kalambo-crd-v1-0-a1069b5a2757@oss.qualcomm.com>
Qualcomm Kalambo is a derivative of the Mahua SoC and shares the same
Universal Bandwidth Compression (UBWC) configuration. Add the Kalambo
compatible to the UBWC configuration table to enable support.
Signed-off-by: Gopikrishna Garmidi <gopikrishna.garmidi@oss.qualcomm.com>
---
drivers/soc/qcom/ubwc_config.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/soc/qcom/ubwc_config.c b/drivers/soc/qcom/ubwc_config.c
index 0209a02c390f..c5f79210ad52 100644
--- a/drivers/soc/qcom/ubwc_config.c
+++ b/drivers/soc/qcom/ubwc_config.c
@@ -112,6 +112,7 @@ static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = {
{ .compatible = "qcom,eliza", .data = &ubwc_5_0_hbb15 },
{ .compatible = "qcom,glymur", .data = &glymur_data},
{ .compatible = "qcom,kaanapali", .data = &ubwc_6_0_hbb16 },
+ { .compatible = "qcom,kalambo", .data = &glymur_data },
{ .compatible = "qcom,mahua", .data = &glymur_data },
{ .compatible = "qcom,milos", .data = &milos_data },
{ .compatible = "qcom,msm8226", .data = &no_ubwc_data },
--
2.34.1
^ permalink raw reply related
* [PATCH 4/5] firmware: qcom: scm: Allow QSEECOM on Kalambo CRD
From: Gopikrishna Garmidi @ 2026-07-18 12:06 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Sibi Sankar, Pankaj Patil
Cc: Rajendra Nayak, linux-arm-msm, devicetree, linux-kernel,
Gopikrishna Garmidi
In-Reply-To: <20260718-b4-kalambo-crd-v1-0-a1069b5a2757@oss.qualcomm.com>
Add Kalambo CRD board to the QSEECOM allowlist for enabling access to
efivars.
Signed-off-by: Gopikrishna Garmidi <gopikrishna.garmidi@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index f35f2ee39130..d1cc6c908daa 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -2327,6 +2327,7 @@ static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
{ .compatible = "microsoft,romulus15", },
{ .compatible = "qcom,glymur-crd" },
{ .compatible = "qcom,hamoa-iot-evk" },
+ { .compatible = "qcom,kalambo-crd" },
{ .compatible = "qcom,mahua-crd" },
{ .compatible = "qcom,purwa-iot-evk" },
{ .compatible = "qcom,sc8180x-primus" },
--
2.34.1
^ permalink raw reply related
* [PATCH 3/5] arm64: dts: qcom: Add Kalambo CRD
From: Gopikrishna Garmidi @ 2026-07-18 12:06 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Sibi Sankar, Pankaj Patil
Cc: Rajendra Nayak, linux-arm-msm, devicetree, linux-kernel,
Gopikrishna Garmidi
In-Reply-To: <20260718-b4-kalambo-crd-v1-0-a1069b5a2757@oss.qualcomm.com>
Introduce support for the CRD based on the Qualcomm Kalambo SoC. Similar
to Mahua, it is pin-to-pin compatible with the Glymur CRD. It reuses the
common CRD board description and drops the PMIC nodes not present on this
design.
Signed-off-by: Gopikrishna Garmidi <gopikrishna.garmidi@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/Makefile | 1 +
arch/arm64/boot/dts/qcom/kalambo-crd.dts | 21 +++++++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index e05414290d8e..0ea4d6696aee 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -43,6 +43,7 @@ dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp454.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq9650-rdp488.dtb
dtb-$(CONFIG_ARCH_QCOM) += kaanapali-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += kaanapali-qrd.dtb
+dtb-$(CONFIG_ARCH_QCOM) += kalambo-crd.dtb
dtb-$(CONFIG_ARCH_QCOM) += lemans-evk.dtb
lemans-evk-camera-csi1-imx577-dtbs := lemans-evk.dtb lemans-evk-camera-csi1-imx577.dtbo
diff --git a/arch/arm64/boot/dts/qcom/kalambo-crd.dts b/arch/arm64/boot/dts/qcom/kalambo-crd.dts
new file mode 100644
index 000000000000..b4441807f460
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/kalambo-crd.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+/dts-v1/;
+
+#include "kalambo.dtsi"
+#include "glymur-crd.dtsi"
+
+/delete-node/ &pmcx0102_d_e0;
+/delete-node/ &pmcx0102_d0_thermal;
+/delete-node/ &pmh0104_i_e0;
+/delete-node/ &pmh0104_i0_thermal;
+/delete-node/ &pmh0104_j_e0;
+/delete-node/ &pmh0104_j0_thermal;
+
+/ {
+ model = "Qualcomm Technologies, Inc. Kalambo CRD";
+ compatible = "qcom,kalambo-crd", "qcom,kalambo";
+};
--
2.34.1
^ permalink raw reply related
* [PATCH 2/5] arm64: dts: qcom: Add Kalambo SoC
From: Gopikrishna Garmidi @ 2026-07-18 12:06 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Sibi Sankar, Pankaj Patil
Cc: Rajendra Nayak, linux-arm-msm, devicetree, linux-kernel,
Gopikrishna Garmidi
In-Reply-To: <20260718-b4-kalambo-crd-v1-0-a1069b5a2757@oss.qualcomm.com>
Introduce support for the Qualcomm Kalambo SoC. It is derived from Mahua
with CPU cluster 0 removed, leaving it with just cluster 1. As a result,
the PDP mailbox and SCP low-priority register windows are updated to
match the reduced CPU complex. Everything else should work as-is.
Add a label to the Glymur cluster0 cpu-map node to allow its removal on
derived SoCs.
Signed-off-by: Gopikrishna Garmidi <gopikrishna.garmidi@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/glymur.dtsi | 2 +-
arch/arm64/boot/dts/qcom/kalambo.dtsi | 29 +++++++++++++++++++++++++++++
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi
index 55d91c696a3a..f2feef362be5 100644
--- a/arch/arm64/boot/dts/qcom/glymur.dtsi
+++ b/arch/arm64/boot/dts/qcom/glymur.dtsi
@@ -275,7 +275,7 @@ cpu17: cpu@20500 {
};
cpu-map {
- cluster0 {
+ cpu_map_cluster0: cluster0 {
core0 {
cpu = <&cpu0>;
};
diff --git a/arch/arm64/boot/dts/qcom/kalambo.dtsi b/arch/arm64/boot/dts/qcom/kalambo.dtsi
new file mode 100644
index 000000000000..a56ff68b57b4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/kalambo.dtsi
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include "mahua.dtsi"
+
+/delete-node/ &cluster0_pd;
+/delete-node/ &cpu_map_cluster0;
+/delete-node/ &cpu0;
+/delete-node/ &cpu1;
+/delete-node/ &cpu2;
+/delete-node/ &cpu3;
+/delete-node/ &cpu4;
+/delete-node/ &cpu5;
+/delete-node/ &cpu_pd0;
+/delete-node/ &cpu_pd1;
+/delete-node/ &cpu_pd2;
+/delete-node/ &cpu_pd3;
+/delete-node/ &cpu_pd4;
+/delete-node/ &cpu_pd5;
+
+&pdp0_mbox {
+ reg = <0 0x17610000 0 0x8000>, <0 0x1a980000 0 0x8000>;
+};
+
+&cpu_scp_lpri1 {
+ reg = <0x180 0x60>;
+};
--
2.34.1
^ permalink raw reply related
* [PATCH 1/5] dt-bindings: arm: qcom: Document Kalambo SoC and board
From: Gopikrishna Garmidi @ 2026-07-18 12:06 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Sibi Sankar, Pankaj Patil
Cc: Rajendra Nayak, linux-arm-msm, devicetree, linux-kernel,
Gopikrishna Garmidi
In-Reply-To: <20260718-b4-kalambo-crd-v1-0-a1069b5a2757@oss.qualcomm.com>
Qualcomm Kalambo is a derivative of the Mahua SoC with CPU cluster 0
removed, leaving it with just cluster 1. Document the compatible strings
for the Kalambo SoC and the Compute Reference Device (CRD) board based
on it.
Signed-off-by: Gopikrishna Garmidi <gopikrishna.garmidi@oss.qualcomm.com>
---
Documentation/devicetree/bindings/arm/qcom.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index c7c9a9279684..b0c07a57bda6 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -174,6 +174,11 @@ properties:
- qcom,kaanapali-qrd
- const: qcom,kaanapali
+ - items:
+ - enum:
+ - qcom,kalambo-crd
+ - const: qcom,kalambo
+
- items:
- enum:
- qcom,mahua-crd
--
2.34.1
^ permalink raw reply related
* [PATCH 0/5] arm64: dts: qcom: Add Kalambo SoC and CRD
From: Gopikrishna Garmidi @ 2026-07-18 12:06 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Sibi Sankar, Pankaj Patil
Cc: Rajendra Nayak, linux-arm-msm, devicetree, linux-kernel,
Gopikrishna Garmidi
Qualcomm Kalambo is a Mahua derivative with CPU cluster 0 absent,
leaving it with just cluster 1. Everything else should work as-is.
This series documents the board compatibles and adds the SoC and
Compute Reference Device (CRD) device trees. It also adds the Kalambo
compatible to the UBWC configuration table and allowlists the Kalambo
CRD for QSEECOM to enable access to efivars.
---
Gopikrishna Garmidi (5):
dt-bindings: arm: qcom: Document Kalambo SoC and board
arm64: dts: qcom: Add Kalambo SoC
arm64: dts: qcom: Add Kalambo CRD
firmware: qcom: scm: Allow QSEECOM on Kalambo CRD
soc: qcom: ubwc: Add Kalambo UBWC config
Documentation/devicetree/bindings/arm/qcom.yaml | 5 +++++
arch/arm64/boot/dts/qcom/Makefile | 1 +
arch/arm64/boot/dts/qcom/glymur.dtsi | 2 +-
arch/arm64/boot/dts/qcom/kalambo-crd.dts | 21 ++++++++++++++++++
arch/arm64/boot/dts/qcom/kalambo.dtsi | 29 +++++++++++++++++++++++++
drivers/firmware/qcom/qcom_scm.c | 1 +
drivers/soc/qcom/ubwc_config.c | 1 +
7 files changed, 59 insertions(+), 1 deletion(-)
---
base-commit: 1a1757b76427f6201bfe0bf1bea9f7574f332a93
change-id: 20260715-b4-kalambo-crd-86912a03bbd2
Best regards,
--
Gopikrishna Garmidi <gopikrishna.garmidi@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v2 1/2] arm64: dts: qcom: shikra-iqs-evk: Add LT9611UXD HDMI bridge support
From: Mohit Dsor @ 2026-07-18 11:24 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-kernel, linux-arm-msm, devicetree,
venkata.valluru, Jessica Zhang, Mohit Dsor
In-Reply-To: <04a9d8ce-e83a-4307-8b14-4afe739b31e0@oss.qualcomm.com>
On Fri, Jul 17, 2026 at 11:17:10AM +0200, Konrad Dybcio wrote:
> On 7/16/26 9:30 PM, mohit.dsor@oss.qualcomm.com wrote:
> > From: Mohit Dsor <mdsor@oss.qualcomm.com>
> >
> > Enable the Shikra MDSS display subsystem on the Qualcomm Shikra IQS
> > EVK board and add the Lontium LT9611UXD DSI-to-HDMI bridge node.
> >
> > The LT9611UXD is connected via I2C (bus 4, address 0x41), powered by
> > a GPIO-controlled 3.3V regulator (PM8150 GPIO4) and an always-on 1.8V
> > rail. Reset is on GPIO76 and interrupt on GPIO85.
> >
> > The bridge receives DSI output from MDSS and drives an HDMI-A
> > connector, with the link wired as: DPU -> DSI0 -> LT9611UXD -> HDMI.
> >
> > Signed-off-by: Mohit Dsor <mohit.dsor@oss.qualcomm.com>
> > ---
>
> Does the other EVK not have this same hardware?
Yes other variants have this hardware but only IQS variant has
DS-HDMI as default, others have DLC panel as default.
>
> [...]
>
> > +&pm8150_l11 {
> > + /* DSI VDDA - must be at NOM voltage for PHY PLL lock */
>
> This comment is superfluous
This comment will be removed in next revision.
>
> Konrad
^ permalink raw reply
* [RFC PATCH 2/2] drm/meson: add GXLX2 HDMI register support
From: Zinan Zhou @ 2026-07-18 11:15 UTC (permalink / raw)
To: Neil Armstrong
Cc: Zinan Zhou, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
dri-devel, linux-amlogic, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260718111527.119231-1-zinan@mieulab.com>
GXLX2 combines a GXL-like display pipeline and HDMI PHY with directly
mapped DesignWare and TOP registers. Reusing the indirect GX callbacks
returns an invalid HDMI controller ID and prevents the HDMI component from
binding.
Add GXLX2 match data using the existing direct register callbacks, while
retaining the GXL PHY initialization values. Do not enable APB3
fail-on-error through the legacy indirect control-register offsets for a
direct-register device. Add the compatible to the VPU component match list
and use the GXLX2-specific HHI_HDMI_PHY_CNTL0 value for the 297 MHz
pixel-clock bucket.
The register layout and the 297 MHz value were determined by analysis of
the HG680-LC vendor kernel. Public Amlogic-derived source independently
documents the direct access mechanism and the ordinary GXL PHY values; no
vendor code is copied by this change.
An equivalent Linux 6.6 implementation was tested on an HG680-LC with 1080p
HDMI video and two-channel HDMI audio. The Linux 6.12 port boots from eMMC
with working Ethernet, 1080p and native 1440p video, and two-channel HDMI
audio. This port has passed arm64 compilation; 4K30 physical validation of
the 297 MHz branch remains pending.
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Zinan Zhou <zinan@mieulab.com>
---
drivers/gpu/drm/meson/meson_drv.c | 1 +
drivers/gpu/drm/meson/meson_dw_hdmi.c | 33 +++++++++++++++++++++++----
2 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 49ff9f1f16d3..5c136743e60c 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -469,6 +469,7 @@ static void meson_drv_shutdown(struct platform_device *pdev)
static const struct of_device_id components_dev_match[] = {
{ .compatible = "amlogic,meson-gxbb-dw-hdmi" },
{ .compatible = "amlogic,meson-gxl-dw-hdmi" },
+ { .compatible = "amlogic,meson-gxlx2-dw-hdmi" },
{ .compatible = "amlogic,meson-gxm-dw-hdmi" },
{ .compatible = "amlogic,meson-g12a-dw-hdmi" },
{}
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 1004108fb7ca..f02d6a513dd3 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -136,6 +136,8 @@ struct meson_dw_hdmi_data {
unsigned int addr, unsigned int data);
u32 cntl0_init;
u32 cntl1_init;
+ u32 phy_cntl0_3g;
+ bool uses_direct_regs;
};
struct meson_dw_hdmi {
@@ -287,7 +289,9 @@ static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi,
/* For 420, pixel clock is half unlike venc clock */
if (mode_is_420) pixel_clock /= 2;
- if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
+ if (dw_hdmi_is_compatible(dw_hdmi,
+ "amlogic,meson-gxlx2-dw-hdmi") ||
+ dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) {
if (pixel_clock >= 371250) {
/* 5.94Gbps, 3.7125Gbps */
@@ -295,7 +299,8 @@ static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi,
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2136315b);
} else if (pixel_clock >= 297000) {
/* 2.97Gbps */
- regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303382);
+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0,
+ dw_hdmi->data->phy_cntl0_3g);
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2036315b);
} else if (pixel_clock >= 148500) {
/* 1.485Gbps */
@@ -586,6 +591,7 @@ static const struct meson_dw_hdmi_data meson_dw_hdmi_gxl_data = {
.dwc_write = dw_hdmi_dwc_write,
.cntl0_init = 0x0,
.cntl1_init = PHY_CNTL1_INIT,
+ .phy_cntl0_3g = 0x33303382,
};
static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
@@ -595,6 +601,19 @@ static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
.dwc_write = dw_hdmi_g12a_dwc_write,
.cntl0_init = 0x000b4242, /* Bandgap */
.cntl1_init = PHY_CNTL1_INIT,
+ .uses_direct_regs = true,
+};
+
+/* GXLX2 uses the direct register layout with the older GXL PHY setup. */
+static const struct meson_dw_hdmi_data meson_dw_hdmi_gxlx2_data = {
+ .top_read = dw_hdmi_g12a_top_read,
+ .top_write = dw_hdmi_g12a_top_write,
+ .dwc_read = dw_hdmi_g12a_dwc_read,
+ .dwc_write = dw_hdmi_g12a_dwc_write,
+ .cntl0_init = 0x0,
+ .cntl1_init = PHY_CNTL1_INIT,
+ .phy_cntl0_3g = 0x33353382,
+ .uses_direct_regs = true,
};
static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
@@ -612,8 +631,8 @@ static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
reset_control_reset(meson_dw_hdmi->hdmitx_ctrl);
reset_control_reset(meson_dw_hdmi->hdmitx_phy);
- /* Enable APB3 fail on error */
- if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
+ /* The APB3 control registers exist only with the indirect interface. */
+ if (!meson_dw_hdmi->data->uses_direct_regs) {
writel_bits_relaxed(BIT(15), BIT(15),
meson_dw_hdmi->hdmitx + HDMITX_TOP_CTRL_REG);
writel_bits_relaxed(BIT(15), BIT(15),
@@ -769,7 +788,9 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
dw_plat_data->disable_cec = true;
dw_plat_data->output_port = 1;
- if (dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
+ if (dw_hdmi_is_compatible(meson_dw_hdmi,
+ "amlogic,meson-gxlx2-dw-hdmi") ||
+ dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxm-dw-hdmi") ||
dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-g12a-dw-hdmi"))
dw_plat_data->use_drm_infoframe = true;
@@ -854,6 +875,8 @@ static const struct of_device_id meson_dw_hdmi_of_table[] = {
.data = &meson_dw_hdmi_gxl_data },
{ .compatible = "amlogic,meson-gxm-dw-hdmi",
.data = &meson_dw_hdmi_gxl_data },
+ { .compatible = "amlogic,meson-gxlx2-dw-hdmi",
+ .data = &meson_dw_hdmi_gxlx2_data },
{ .compatible = "amlogic,meson-g12a-dw-hdmi",
.data = &meson_dw_hdmi_g12a_data },
{ }
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 1/2] dt-bindings: display: meson-dw-hdmi: add GXLX2 compatible
From: Zinan Zhou @ 2026-07-18 11:15 UTC (permalink / raw)
To: Neil Armstrong
Cc: Zinan Zhou, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
dri-devel, linux-amlogic, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260718111527.119231-1-zinan@mieulab.com>
The GXLX2 HDMI transmitter uses the byte-addressed DesignWare controller
registers and directly mapped TOP window also present on G12A. Its display
pipeline and HDMI PHY programming remain GXL-like, however.
Add a dedicated compatible with no fallback. The generic
meson-gx-dw-hdmi interface uses indirect address/data registers and cannot
operate this hardware, while meson-g12a-dw-hdmi would select incompatible
PHY initialization values.
The one-resource representation is proposed for RFC review; DWC and TOP
occupy one contiguous MMIO range on the tested HG680-LC.
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Zinan Zhou <zinan@mieulab.com>
---
.../devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml
index 416fe263ac92..4a17eccabea9 100644
--- a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml
@@ -29,8 +29,10 @@ description: |
The HDMI TOP block only supports HPD sensing.
The Synopsys HDMI Controller interrupt is routed through the
TOP Block interrupt.
- Communication to the TOP Block and the Synopsys HDMI Controller is done
- via a pair of dedicated addr+read/write registers.
+ Communication with the TOP Block and the Synopsys HDMI Controller uses a pair
+ of dedicated address/data registers on GXBB, GXL and GXM. GXLX2 and G12A
+ instead expose byte-addressed controller registers and a directly mapped TOP
+ window.
The HDMI PHY is configured by registers in the HHI register block.
Pixel data arrives in "4:4:4" format from the VENC block and the VPU HDMI mux
@@ -54,6 +56,7 @@ properties:
- amlogic,meson-gxm-dw-hdmi # GXM (S912)
- const: amlogic,meson-gx-dw-hdmi
- enum:
+ - amlogic,meson-gxlx2-dw-hdmi # GXLX2 (S905L3)
- amlogic,meson-g12a-dw-hdmi # G12A (S905X2, S905Y2, S905D2)
reg:
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 0/2] drm/meson: add HDMI support for GXLX2
From: Zinan Zhou @ 2026-07-18 11:15 UTC (permalink / raw)
To: Neil Armstrong
Cc: Zinan Zhou, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
dri-devel, linux-amlogic, devicetree, linux-arm-kernel,
linux-kernel
This RFC adds HDMI transmitter support for the Amlogic GXLX2 family,
observed as an S905L3 (CPU major ID 0x2a) in a FiberHome HG680-LC set-top
box.
GXLX2 is unusual in that the display pipeline, clocks and HDMI PHY follow
the older GXL path, while the HDMI controller register interface is
directly mapped: DWC registers are byte-addressed from 0xda800000 and TOP
registers are 32-bit registers at 0xda808000 + index * 4. The existing
G12A access callbacks implement this layout, but using all G12A match data
would select the wrong PHY initialization for GXLX2.
Patch 1 proposes a dedicated amlogic,meson-gxlx2-dw-hdmi compatible
without a meson-gx-dw-hdmi fallback. Patch 2 adds dedicated match data
combining direct register callbacks with GXL PHY behavior. It also handles
the GXLX2 value for the 297 MHz PHY bucket and adds the compatible to the
Meson DRM component match list.
This RFC depends on the separately posted common Meson DW-HDMI regmap fix:
drm/meson: constrain the DW-HDMI regmap range
https://lore.kernel.org/all/20260718090710.70534-1-zinan@mieulab.com/
That formal bug-fix patch bounds register iteration below the directly
mapped TOP block and prevents the legacy 16-bit indirect interface from
wrapping. It is intentionally not part of this RFC so it can be reviewed
and merged without waiting for agreement on the GXLX2 DT ABI.
I would particularly appreciate feedback on two DT ABI questions:
1. Is amlogic,meson-gxlx2-dw-hdmi the appropriate block compatible name?
2. Should the DWC and TOP windows be represented as one contiguous MMIO
resource, as in this RFC, or as two named resources?
Evidence and disclosure:
- The GXLX2 addresses and 297 MHz value are factual results of analysis of
the HG680-LC vendor kernel. Firmware SHA-256 and focused behavioral
evidence can be supplied if useful, but no firmware, kallsyms dump or
disassembly is part of this submission.
- Public Amlogic-derived GPL source documents the ordinary GXL 2.97 Gbps
values and public GPL-2.0+/MIT source documents the same direct DWC/TOP
access mechanism used on later SoCs. The implementation here does not
copy a vendor function body.
Testing:
- An equivalent Linux 6.6.18 implementation boots from eMMC on the
HG680-LC.
- 1920x1080 HDMI video was physically verified on an LG 27GL850.
- Two-channel HDMI LPCM through the display and analog stereo audio were
physically verified.
- The downstream 6.12 port boots from eMMC with working Ethernet/SSH and
has physically verified 1920x1080@60 video and HDMI LPCM.
- With the generic Meson non-CEA mode-range change already present in
current mainline, 2560x1440@59.95 video and HDMI LPCM were physically
verified on the display's native timing.
- The RFC port builds on arm64 and its binding passes dt_binding_check.
- 3840x2160 at 30 Hz has not yet been physically tested. That test is
required before a non-RFC PATCH v1 because it exercises the
GXLX2-specific 297 MHz branch. It is not a blocker for the verified
1080p/1440p use case.
- No other GXLX2 board has been tested yet.
The initial RFC intentionally contains no board DTS. A downstream-only
HG680-LC DTS is being kept as DO NOT MERGE until the compatible and resource
model have received initial feedback.
Assisted-by: Codex:gpt-5.6-sol
Zinan Zhou (2):
dt-bindings: display: meson-dw-hdmi: add GXLX2 compatible
drm/meson: add GXLX2 HDMI register support
.../display/amlogic,meson-dw-hdmi.yaml | 7 ++--
drivers/gpu/drm/meson/meson_drv.c | 1 +
drivers/gpu/drm/meson/meson_dw_hdmi.c | 33 ++++++++++++++++---
3 files changed, 34 insertions(+), 7 deletions(-)
base-commit: b0a652436b892eb9a036a031b33099dca036faaa
prerequisite-patch-id: 0a689485bbc3c1d77d52aeee0b81e4943d1e904a
--
2.43.0
^ permalink raw reply
* Re: [PATCH v7 2/2] drm/bridge: Add Lontium LT9609C(EX/UXD) MIPI DSI to HDMI driver
From: Mohit Dsor @ 2026-07-18 11:12 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Sunyun Yang, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Vinod Koul, dri-devel, devicetree, linux-kernel, venkata.valluru,
Jessica Zhang, y
In-Reply-To: <85505d92-ebe3-4ffd-84e1-8fe26994e053@kernel.org>
On Thu, Jul 16, 2026 at 02:56:02PM +0200, Krzysztof Kozlowski wrote:
> On 16/07/2026 13:31, mohit.dsor@oss.qualcomm.com wrote:
> > From: Sunyun Yang <syyang@lontium.com>
> >
> > LT9611C(EX/UXD) is an I2C-controlled chip that Receiver signal/dual port
> > mipi dsi and output hdmi, differences in hardware features:
> > - LT9611C: supports 1-port mipi dsi to hdmi 1.4
> > - LT9611EX: supports 2-port mipi dsi to hdmi 1.4
> > - LT9611UXD: supports 2-port mipi dsi to hdmi 1.4/2.0
> >
> > Signed-off-by: Sunyun Yang <syyang@lontium.com>
> > Co-developed-by: Mohit Dsor <mohit.dsor@oss.qualcomm.com>
> > Signed-off-by: Mohit Dsor <mohit.dsor@oss.qualcomm.com>
> > ---
> > MAINTAINERS | 7 +
> > drivers/gpu/drm/bridge/Kconfig | 18 +
> > drivers/gpu/drm/bridge/Makefile | 1 +
> > drivers/gpu/drm/bridge/lontium-lt9611c.c | 1293 ++++++++++++++++++++++++++++++
> > 4 files changed, 1319 insertions(+)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 6dea93a41962..30be2eaf2bec 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -15184,6 +15184,13 @@ S: Maintained
> > F: Documentation/devicetree/bindings/display/bridge/lontium,lt8912b.yaml
> > F: drivers/gpu/drm/bridge/lontium-lt8912b.c
> >
> > +LONTIUM LT9611C MIPI DSI TO HDMI BRIDGE
> > +M: Sunyun Yang <syyang@lontium.com>
> > +M: Mohit Dsor <mohit.dsor@oss.qualcomm.com>
> > +S: Maintained
> > +F: Documentation/devicetree/bindings/display/bridge/lontium,lt9611.yaml
> > +F: drivers/gpu/drm/bridge/lontium-lt9611c.c
> > +
> > LOONGARCH
> > M: Huacai Chen <chenhuacai@kernel.org>
> > R: WANG Xuerui <kernel@xen0n.name>
> > diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> > index 4a57d49b4c6d..b8959b8e2ad0 100644
> > --- a/drivers/gpu/drm/bridge/Kconfig
> > +++ b/drivers/gpu/drm/bridge/Kconfig
> > @@ -177,6 +177,24 @@ config DRM_LONTIUM_LT9611
> > HDMI signals
> > Please say Y if you have such hardware.
> >
> > +config DRM_LONTIUM_LT9611C
> > + tristate "Lontium LT9611C DSI/HDMI bridge"
> > + select SND_SOC_HDMI_CODEC if SND_SOC
> > + depends on OF
> > + select CRC8
> > + select FW_LOADER
> > + select DRM_PANEL_BRIDGE
> > + select DRM_KMS_HELPER
> > + select DRM_MIPI_DSI
> > + select DRM_DISPLAY_HELPER
> > + select DRM_DISPLAY_HDMI_STATE_HELPER
> > + select REGMAP_I2C
> > + help
> > + Driver for Lontium DSI to HDMI bridge
> > + chip driver that converts dual DSI and I2S to
> > + HDMI signals
> > + Please say Y if you have such hardware.
>
> Please wrap the code to appropriate limits.
I checked the others in Kconfigs they appear to be similar,
still i will try to fix it.
>
> ...
>
> > +
> > +static void lt9611c_reset(struct lt9611c *lt9611c)
> > +{
> > + gpiod_set_value_cansleep(lt9611c->reset_gpio, 1);
> > + usleep_range(10000, 12000);
> > +
> > + gpiod_set_value_cansleep(lt9611c->reset_gpio, 0);
> > + msleep(400);
> > +
> > + dev_dbg(lt9611c->dev, "lt9611c reset");
>
> Same comment as before.
will remove all debug comments.
>
> > +}
> > +
>
> > +static int lt9611c_upgrade_result(struct lt9611c *lt9611c, u8 fw_crc)
> > +{
> > + struct device *dev = lt9611c->dev;
> > + unsigned int crc_result;
> > +
> > + regmap_write(lt9611c->regmap, 0xe0ee, 0x01);
> > + regmap_read(lt9611c->regmap, 0xe021, &crc_result);
> > +
> > + if (crc_result != fw_crc) {
> > + dev_err(dev, "lt9611c fw upgrade failed, expected crc=0x%02x, read crc=0x%02x\n",
> > + fw_crc, crc_result);
> > + return -1;
> > + }
> > +
> > + dev_dbg(dev, "lt9611c firmware upgrade success, crc=0x%02x\n", crc_result);
> > + return 0;
> > +}
>
> ...
>
> > +
> > +static ssize_t lt9611c_firmware_show(struct device *dev, struct device_attribute *attr, char *buf)
> > +{
> > + struct lt9611c *lt9611c = dev_get_drvdata(dev);
> > +
> > + return sysfs_emit(buf, "0x%04x\n", lt9611c->fw_version);
> > +}
> > +
> > +static DEVICE_ATTR_RW(lt9611c_firmware);
>
> Where is this ABI documented?
Will have its ABI documentation.
>
> > +
> > +static struct attribute *lt9611c_attrs[] = {
> > + &dev_attr_lt9611c_firmware.attr,
> > + NULL,
> > +};
> > +
> > +static const struct attribute_group lt9611c_attr_group = {
> > + .attrs = lt9611c_attrs,
> > +};
> > +
> > +static const struct attribute_group *lt9611c_attr_groups[] = {
> > + <9611c_attr_group,
> > + NULL,
> > +};
> > +
> > +static int lt9611c_probe(struct i2c_client *client)
> > +{
> > + struct lt9611c *lt9611c;
> > + struct device *dev = &client->dev;
> > + bool fw_updated = false;
> > + int ret;
> > +
> > + crc8_populate_msb(lt9611c_crc8_table, LT9611C_CRC_POLYNOMIAL);
> > +
> > + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
> > + return dev_err_probe(dev, -ENODEV, "device doesn't support I2C\n");
> > +
> > + lt9611c = devm_drm_bridge_alloc(dev, struct lt9611c, bridge, <9611c_bridge_funcs);
> > + if (IS_ERR(lt9611c))
> > + return dev_err_probe(dev, PTR_ERR(lt9611c), "drm bridge alloc failed.\n");
> > +
> > + lt9611c->dev = dev;
> > + lt9611c->client = client;
> > + lt9611c->chip_type = (uintptr_t)i2c_get_match_data(client);
>
> uintptr_t is not for kernel, use unsigned long.
I will fix this.
>
>
> > +
> > + ret = devm_mutex_init(dev, <9611c->ocm_lock);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "failed to init mutex\n");
> > +
> > + lt9611c->regmap = devm_regmap_init_i2c(client, <9611c_regmap_config);
> > + if (IS_ERR(lt9611c->regmap))
> > + return dev_err_probe(dev, PTR_ERR(lt9611c->regmap), "regmap i2c init failed\n");
> > +
> > + ret = lt9611c_parse_dt(dev, lt9611c);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "failed to parse device tree\n");
> > +
> > + ret = lt9611c_gpio_init(lt9611c);
> > + if (ret < 0)
> > + goto err_of_put;
> > +
> > + ret = lt9611c_regulator_init(lt9611c);
> > + if (ret < 0)
> > + goto err_of_put;
> > +
> > + ret = regulator_bulk_enable(ARRAY_SIZE(lt9611c->supplies), lt9611c->supplies);
> > + if (ret)
> > + goto err_of_put;
> > +
> > + lt9611c_reset(lt9611c);
> > +
> > + lt9611c_lock(lt9611c);
> > +
> > + ret = lt9611c_read_chipid(lt9611c);
> > + if (ret < 0) {
> > + dev_err(dev, "failed to read chip id.\n");
> > + lt9611c_unlock(lt9611c);
> > + goto err_disable_regulators;
> > + }
> > +
> > +retry:
> > + lt9611c->fw_version = lt9611c_read_version(lt9611c);
> > + if (lt9611c->fw_version < 0) {
> > + dev_err(dev, "failed to read fw version\n");
> > + ret = -EOPNOTSUPP;
> > + lt9611c_unlock(lt9611c);
> > + goto err_disable_regulators;
> > +
> > + } else if (lt9611c->fw_version == 0) {
> > + if (!fw_updated) {
> > + fw_updated = true;
> > + ret = lt9611c_firmware_upgrade(lt9611c);
> > + if (ret < 0) {
> > + lt9611c_unlock(lt9611c);
> > + goto err_disable_regulators;
> > + }
> > +
> > + goto retry;
> > +
> > + } else {
> > + dev_err(dev, "fw version 0x%04x, update failed\n", lt9611c->fw_version);
> > + ret = -EOPNOTSUPP;
> > + lt9611c_unlock(lt9611c);
> > + goto err_disable_regulators;
> > + }
> > + }
> > +
> > + lt9611c_unlock(lt9611c);
> > + dev_dbg(dev, "current version:0x%04x", lt9611c->fw_version);
> > +
> > + INIT_WORK(<9611c->work, lt9611c_hpd_work);
> > +
> > + ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
> > + lt9611c_irq_thread_handler,
> > + IRQF_TRIGGER_FALLING |
> > + IRQF_ONESHOT |
> > + IRQF_NO_AUTOEN,
> > + "lt9611c", lt9611c);
> > + if (ret) {
> > + dev_err(dev, "failed to request irq\n");
> > + goto err_disable_regulators;
> > + }
> > +
> > + lt9611c->bridge.of_node = client->dev.of_node;
> > + lt9611c->bridge.ops = DRM_BRIDGE_OP_DETECT |
> > + DRM_BRIDGE_OP_EDID |
> > + DRM_BRIDGE_OP_HPD |
> > + DRM_BRIDGE_OP_HDMI |
> > + DRM_BRIDGE_OP_HDMI_AUDIO;
> > + lt9611c->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
> > +
> > + lt9611c->bridge.vendor = "Lontium";
> > + lt9611c->bridge.product = "LT9611C";
> > +
> > + lt9611c->bridge.hdmi_audio_dev = dev;
> > + lt9611c->bridge.hdmi_audio_max_i2s_playback_channels = 8;
> > + lt9611c->bridge.hdmi_audio_dai_port = 2;
> > +
> > + devm_drm_bridge_add(dev, <9611c->bridge);
> > +
> > + /* Attach primary DSI */
> > + lt9611c->dsi0 = lt9611c_attach_dsi(lt9611c, lt9611c->dsi0_node);
> > + if (IS_ERR(lt9611c->dsi0)) {
> > + ret = PTR_ERR(lt9611c->dsi0);
> > + goto err_remove_bridge;
> > + }
> > +
> > + /* Attach secondary DSI, if specified */
> > + if (lt9611c->dsi1_node) {
> > + lt9611c->dsi1 = lt9611c_attach_dsi(lt9611c, lt9611c->dsi1_node);
> > + if (IS_ERR(lt9611c->dsi1)) {
> > + ret = PTR_ERR(lt9611c->dsi1);
> > + goto err_remove_bridge;
> > + }
> > + }
> > +
> > + lt9611c->hdmi_connected = false;
> > + i2c_set_clientdata(client, lt9611c);
> > + enable_irq(client->irq);
> > +
> > + lt9611c_reset(lt9611c);
> > + return 0;
> > +
> > +err_remove_bridge:
> > + cancel_work_sync(<9611c->work);
> > +
> > +err_disable_regulators:
> > + regulator_bulk_disable(ARRAY_SIZE(lt9611c->supplies), lt9611c->supplies);
> > +
> > +err_of_put:
> > + of_node_put(lt9611c->dsi1_node);
> > + of_node_put(lt9611c->dsi0_node);
> > +
> > + return ret;
> > +}
> > +
> > +static void lt9611c_remove(struct i2c_client *client)
> > +{
> > + struct lt9611c *lt9611c = i2c_get_clientdata(client);
> > +
> > + cancel_work_sync(<9611c->work);
> > + regulator_bulk_disable(ARRAY_SIZE(lt9611c->supplies), lt9611c->supplies);
> > + of_node_put(lt9611c->dsi1_node);
> > + of_node_put(lt9611c->dsi0_node);
> > +}
> > +
> > +static int lt9611c_bridge_suspend(struct device *dev)
> > +{
> > + struct lt9611c *lt9611c = dev_get_drvdata(dev);
> > + int ret;
> > +
> > + dev_dbg(lt9611c->dev, "suspend\n");
>
> Same comments.
Will remove these debug prints.
>
>
> This does not look like useful printk message. Drivers should be silent
> on success:
> https://elixir.bootlin.com/linux/v6.15-rc7/source/Documentation/process/coding-style.rst#L913
> https://elixir.bootlin.com/linux/v6.15-rc7/source/Documentation/process/debugging/driver_development_debugging_guide.rst#L79
>
> Best regards,
> Krzysztof
^ permalink raw reply
* Re: [PATCH v3 3/4] arm64: dts: rockchip: add #sound-dai-cells to the RK3588 HDMI receiver
From: Igor Paunovic @ 2026-07-18 11:12 UTC (permalink / raw)
To: Dmitry Osipenko, Mauro Carvalho Chehab
Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Heiko Stuebner, linux-media, linux-rockchip, linux-arm-kernel,
kernel, devicetree, linux-kernel
In-Reply-To: <20260718085728.6797-4-royalnet026@gmail.com>
A testing note for anyone trying this out, found while exercising
the series today:
after (re)connecting a source, audio capture currently requires the
video capture path to have been started once -- a cold
`arecord -D hw:...` right after plug-in fails with EIO (the I2S
interface gets no bit clock), while the same command succeeds after
one video STREAMON/STREAMOFF cycle, and keeps working from then on
until the source is re-plugged.
Setting DV timings alone is not sufficient; it does take a real
streaming cycle. So for testing audio, either run a video pipeline
first (e.g. v4l2src ! fakesink for a second) or capture both, which
is the normal use case anyway.
I'm investigating which part of the streaming path opens the audio
packet flow, and will either fix it in v4 (if it turns out to be a
missing enable in the audio path) or send it as a follow-up with a
proper analysis.
Igor
On Sat, Jul 18, 2026 at 10:57 AM Igor Paunovic <royalnet026@gmail.com> wrote:
>
> The Synopsys HDMI RX controller exposes two digital audio interfaces,
> one for I2S (0) and one for S/PDIF (1). Add the #sound-dai-cells
> property so audio cards can reference them as a codec, as documented
> by the snps,dw-hdmi-rx binding.
>
> Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
> ---
> New in v3.
>
> arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
> index a264001..fa100e3 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
> @@ -338,6 +338,7 @@
> reset-names = "axi", "apb", "ref", "biu";
> rockchip,grf = <&sys_grf>;
> rockchip,vo1-grf = <&vo1_grf>;
> + #sound-dai-cells = <1>;
> status = "disabled";
> };
>
> --
> 2.53.0
>
^ permalink raw reply
* Re: [PATCH v3 4/4] arm64: dts: rockchip: enable HDMI RX audio capture on Orange Pi 5 Plus
From: Igor Paunovic @ 2026-07-18 11:04 UTC (permalink / raw)
To: sashiko-reviews, Dmitry Osipenko, Mauro Carvalho Chehab,
Sebastian Reichel, Heiko Stübner, linux-media,
linux-rockchip, linux-arm-kernel, kernel, linux-kernel
Cc: media-ci, conor+dt, devicetree, robh
In-Reply-To: <20260718091200.65AE21F000E9@smtp.kernel.org>
> Does exposing this codec to the ALSA subsystem trigger a suspend
> regression in the hdmirx driver?
Good catch -- this one is real. The audio worker missed the pattern
the driver already applies to its hotplug and res_change works,
which hdmirx_disable_irq() cancels on the suspend path. Fixed for
v4: suspend cancels audio_work before the controller clocks are
gated, and resume re-arms it when a capture stream is active; the
worker's FIFO error path then resynchronizes the clock and the FIFO
on its first run after resume.
> Should swab32() be used here instead to ensure the byte swap happens
> unconditionally on all architectures?
Yes -- readl() already abstracts the bus endianness, so what this
code wants is an unconditional byte reversal, not an endian
conversion. Switched to swab32() for v4 (no functional change on
arm64, where this controller lives, but the right primitive
regardless).
Both changes are in my tree, compile-tested, and will be part of v4
together with whatever comes out of human review of the series.
Igor
On Sat, Jul 18, 2026 at 11:12 AM <sashiko-bot@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [High] The audio_work delayed work is not cancelled during system suspend, leading to a fatal bus fault.
> - [Medium] Incorrect use of be32_to_cpu() for unconditional byte swapping breaks audio capture on big-endian architectures.
> --
>
> --- Patch [4]: [PATCH v3 4/4] arm64: dts: rockchip: enable HDMI RX audio capture on Orange Pi 5 Plus ---
> commit 030cd8fd5334b79e1751dec57b1de1f5fa4e3df3
> Author: Igor Paunovic <royalnet026@gmail.com>
>
> arm64: dts: rockchip: enable HDMI RX audio capture on Orange Pi 5 Plus
>
> This patch routes the HDMI receiver audio to the i2s7_8ch interface. It creates
> a simple-audio-card configuration to expose a capture-only ALSA card driven
> by the HDMI input. The setup uses the receiver as the bitclock and frame master.
>
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> > index 145986695720a..2a68610cddbc3 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> > +++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> > @@ -37,6 +37,22 @@ hdmi1_con_in: endpoint {
> > };
> > };
> >
> > + hdmiin-sound {
> > + compatible = "simple-audio-card";
> > + simple-audio-card,name = "rockchip,hdmiin";
> > + simple-audio-card,format = "i2s";
> > + simple-audio-card,bitclock-master = <&hdmiin_codec>;
> > + simple-audio-card,frame-master = <&hdmiin_codec>;
> > +
> > + simple-audio-card,cpu {
> > + sound-dai = <&i2s7_8ch>;
> > + };
> > +
> > + hdmiin_codec: simple-audio-card,codec {
> > + sound-dai = <&hdmi_receiver 0>;
>
> [Severity: High]
> Does exposing this codec to the ALSA subsystem trigger a suspend regression in
> the hdmirx driver?
>
> Looking at the underlying codec driver hdmirx_suspend() in snps_hdmirx.c:
>
> drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c:hdmirx_suspend()
> {
> struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev);
>
> hdmirx_disable_irq(dev);
>
> /* TODO store CEC HW state */
> disable_irq(hdmirx_dev->cec->irq);
>
> return hdmirx_disable(dev);
> }
>
> The audio_work delayed work is queued on system_unbound_wq, which is not
> freezable, but this suspend callback doesn't cancel it.
>
> If system suspend is initiated while audio capture is active, the worker
> could fire after clocks are disabled via hdmirx_disable(), resulting in
> a bus fault when it performs MMIO reads.
>
> [Severity: Medium]
> Will this audio capture work correctly on big-endian architectures?
>
> The underlying hdmirx_audio_fs() driver function uses be32_to_cpu() for an
> unconditional byte swap when calculating the ACR subpacket:
>
> drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c:hdmirx_audio_fs()
> {
> ...
> acr_cts = be32_to_cpu((__force __be32)acr_pb3_0) & 0xfffff;
> acr_n = (be32_to_cpu((__force __be32)acr_pb7_4) & 0x0fffff00) >> 8;
> ...
> }
>
> Since be32_to_cpu() behaves as a no-op on big-endian CPUs, the bytes remain
> unswapped, causing the bitwise masking to extract the wrong bytes for the
> ACR CTS and N fields.
>
> Should swab32() be used here instead to ensure the byte swap happens
> unconditionally on all architectures?
>
> > + };
> > + };
> > +
>
> [ ... ]
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260718085728.6797-1-royalnet026@gmail.com?part=4
^ permalink raw reply
* Re: [PATCH v3 2/4] media: synopsys: hdmirx: add HDMI audio capture support
From: Igor Paunovic @ 2026-07-18 10:53 UTC (permalink / raw)
To: sashiko-reviews, Dmitry Osipenko, Mauro Carvalho Chehab,
Sebastian Reichel, Heiko Stübner, linux-media,
linux-rockchip, linux-arm-kernel, kernel, linux-kernel
Cc: conor+dt, robh, devicetree, media-ci
In-Reply-To: <20260718090955.A79E51F000E9@smtp.kernel.org>
> Does this byte-swapping logic scramble the extraction of the CTS and N
> values on little-endian architectures?
No. This is the same finding as in the v2 review, where it was already
answered, and the comment this v3 adds above the swap documents exactly
this. Two premises in the report don't match the ACR packet layout:
CTS does not live in PB0..PB2 and is not little-endian. Subpacket
byte 0 is reserved, CTS[19:16] sits in PB1[3:0], CTS[15:8] in PB2 and
CTS[7:0] in PB3 (MSB first), with N likewise in PB4..PB6. The packet
decoder stores PB0 in register bits [7:0], so the byte swap is
precisely what lines the bytes up before the 20-bit masks.
It is also the path validated on hardware: with a 44.1 kHz source the
card reports 44.1 kHz rather than falling back to the 48 kHz default,
and sample-rate switches are followed. Neither would work if the
extraction produced garbage.
> Can this lead to a use-after-free if the driver is unbound while an
> audio stream is active?
No -- the synchronization the report treats as missing is provided by
the ALSA core, and relying on it is why the v2 workaround was dropped
on Dmitry's review in the first place.
The worker is only ever armed between hw_params() and
audio_shutdown(). If a capture stream is still open when the codec
platform device is unregistered, teardown does not complete until the
stream is gone: soc_cleanup_card_resources() calls snd_card_free()
(sound/soc/soc-core.c), which blocks in wait_for_completion() until
the last file handle is closed (sound/core/init.c: "wait, until all
devices are ready for the free operation"). A disconnected card still
routes that final close through the original release path
(snd_disconnect_release() -> disconnected_f_op->release()), so
snd_pcm_release() runs soc_pcm_close() -> hdmi_codec shutdown ->
hdmirx_audio_shutdown(), which clears the streaming flag and
cancel_delayed_work_sync()s the worker.
platform_device_unregister() therefore cannot return with the worker
armed, and the devm-allocated state is freed only after remove()
returns. There is no window for the work to fire on freed memory.
Also exercised on the Orange Pi 5 Plus: unbinding the driver through
sysfs while arecord was actively capturing. The ALSA disconnect kicks
the reader out with ENODEV, the file handle is closed -- which is
where audio_shutdown() runs and cancels the worker -- and only then
does the unbind complete. A subsequent bind re-probes cleanly and the
card comes back. The kernel log stays free of warnings throughout.
Igor
On Sat, Jul 18, 2026 at 11:09 AM <sashiko-bot@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [High] Incorrect byte-swapping logic completely scrambles the extraction of Audio Clock Regeneration (ACR) CTS and N values, breaking sample rate recovery on little-endian architectures.
> - [High] The `audio_work` delayed work is not explicitly cancelled in `hdmirx_remove()`, leading to a Use-After-Free if the driver is unbound while an audio stream is active.
> --
>
> --- Patch [2]: [PATCH v3 2/4] media: synopsys: hdmirx: add HDMI audio capture support ---
> commit b04bcd22f40b424aac824100715c46f764531875
> Author: Igor Paunovic <royalnet026@gmail.com>
>
> media: synopsys: hdmirx: add HDMI audio capture support
>
> The Synopsys DesignWare HDMI RX controller extracts the audio stream
> embedded in the incoming HDMI signal and feeds it to an on-SoC I2S
> controller. Expose it as an ALSA capture device by registering the
> generic hdmi-codec as a child of the controller.
>
> > diff --git a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
> > index 25f8ca0d6d946..22f50cbf3fa7a 100644
> > --- a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
> > +++ b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
>
> [ ... ]
>
> > +/* Recover the incoming audio sample rate from the ACR N/CTS + TMDS clock. */
> > +static u32 hdmirx_audio_fs(struct snps_hdmirx_dev *hdmirx_dev)
> > +{
> > + u64 tmds_clk, fs_audio = 0;
> > + u32 acr_cts, acr_n, tmdsqpclk_freq;
> > + u32 acr_pb3_0, acr_pb7_4;
> > +
> > + tmdsqpclk_freq = hdmirx_readl(hdmirx_dev, CMU_TMDSQPCLK_FREQ);
> > + hdmirx_readl(hdmirx_dev, PKTDEC_ACR_PH2_1);
> > + acr_pb3_0 = hdmirx_readl(hdmirx_dev, PKTDEC_ACR_PB3_0);
> > + acr_pb7_4 = hdmirx_readl(hdmirx_dev, PKTDEC_ACR_PB7_4);
> > + /*
> > + * The packet decoder stores the ACR subpacket bytes with packet byte
> > + * 0 in register bits [7:0], so byte-swap each word to line the bytes
> > + * up: CTS is packet bytes 1-3 (PKTDEC_ACR_PB3_0) and N is packet
> > + * bytes 4-6 (PKTDEC_ACR_PB7_4), 20 bits each.
> > + */
> > + acr_cts = be32_to_cpu((__force __be32)acr_pb3_0) & 0xfffff;
> > + acr_n = (be32_to_cpu((__force __be32)acr_pb7_4) & 0x0fffff00) >> 8;
>
> [Severity: High]
> Does this byte-swapping logic scramble the extraction of the CTS and N values
> on little-endian architectures?
>
> Since the HDMI ACR packet transmits the 20-bit CTS value across PB0, PB1, and
> PB2, and because it is little-endian, applying a bitmask like
> acr_pb3_0 & 0xfffff natively yields the correct CTS value without any swaps.
>
> By byte-swapping the 32-bit register, the bytes are completely reversed.
> The subsequent bitmask extracts the lower 20 bits of the swapped word, which
> correspond to the lower nibble of PB1, all of PB2, and all of PB3, discarding
> PB0 entirely.
>
> The same applies to acr_pb7_4 to extract N. Will this regression result in
> garbage values for both acr_cts and acr_n, forcing the driver to blindly
> fall back to the default sample rate?
>
> [ ... ]
>
> > @@ -2784,6 +3052,9 @@ static void hdmirx_remove(struct platform_device *pdev)
> > struct device *dev = &pdev->dev;
> > struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev);
> >
> > + if (hdmirx_dev->audio_pdev)
> > + platform_device_unregister(hdmirx_dev->audio_pdev);
> > +
>
> [Severity: High]
> Can this lead to a use-after-free if the driver is unbound while an audio
> stream is active?
>
> The v3 changelog notes that the synchronous cancel for the audio_work
> delayed work was removed here under the assumption that audio_shutdown()
> handles it.
>
> However, ALSA does not synchronously invoke the PCM .shutdown callback
> when a device is unregistered if a userspace application holds the file
> descriptor open.
>
> Because hdmirx_dev is allocated using devm_kzalloc, it is freed immediately
> after hdmirx_remove() returns. Will the un-cancelled audio_work delayed work
> subsequently fire and access the freed hdmirx_dev memory?
>
> > v4l2_debugfs_if_free(hdmirx_dev->infoframes);
> > debugfs_remove_recursive(hdmirx_dev->debugfs_dir);
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260718085728.6797-1-royalnet026@gmail.com?part=2
^ permalink raw reply
* [PATCH v2 6/6] arm64: dts: qcom: qcs6490-rubikpi3: Add audio support
From: Hongyang Zhao @ 2026-07-18 9:41 UTC (permalink / raw)
To: konrad.dybcio
Cc: andersson, broonie, conor+dt, devicetree, dmitry.baryshkov, drake,
hongyang.zhao, katsuhiro, konradybcio, krzk+dt, lgirdwood,
linux-arm-msm, linux-kernel, linux-sound, matteomartelli3,
mohammad.rafi.shaik, neil.armstrong, perex, robh, rosh, srini,
tiwai, zhoubinbin
In-Reply-To: <43944722-3eeb-4e02-b3a6-6251d5fc78af@oss.qualcomm.com>
On 7/15/26 4:02 PM, Hongyang Zhao wrote:
> > RubikPi 3 uses the AudioReach firmware path for its external audio
> > interfaces. The primary MI2S interface connects to an ES8316 codec for
> > headset playback and capture, while the quaternary MI2S interface feeds
> > the LT9611 HDMI bridge.
>
> [...]
>
> > + vreg_es8316_3v3: regulator-es8316-3v3 {
> > + compatible = "regulator-fixed";
> > +
> > + regulator-name = "vreg_es8316_3v3";
> > + regulator-min-microvolt = <3300000>;
> > + regulator-max-microvolt = <3300000>;
> > +
> > + gpio = <&tlmm 117 GPIO_ACTIVE_HIGH>;
> > + enable-active-high;
> > +
> > + pinctrl-0 = <&es8316_power_on>;
> > + pinctrl-names = "default";
> > +
> > + regulator-always-on;
> > + regulator-boot-on;
>
> Does it need to be always-on? Is it really on at boot time?
I think the regulator-always-on constraint is currently required.
GPIO117 controls the power switch for the ES8316, but the existing
ES8316 binding and driver do not model regulator supplies.
GPIO117 is not kept asserted before Linux takes over,
so I will drop regulator-boot-on.
>
> [...]
>
> > + mi2s-playback-dai-link {
>
> mi2s-'c'apture < mi2s-'p'layback
Got it. I will move mi2s-capture-dai-link before mi2s-playback-dai-link
in the next revision.
>
> Konrad
Best regards,
Hongyang
^ permalink raw reply
* Re: [PATCH v3 4/4] arm64: dts: rockchip: enable HDMI RX audio capture on Orange Pi 5 Plus
From: sashiko-bot @ 2026-07-18 9:11 UTC (permalink / raw)
To: Igor Paunovic; +Cc: media-ci, conor+dt, devicetree, robh
In-Reply-To: <20260718085728.6797-5-royalnet026@gmail.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] The audio_work delayed work is not cancelled during system suspend, leading to a fatal bus fault.
- [Medium] Incorrect use of be32_to_cpu() for unconditional byte swapping breaks audio capture on big-endian architectures.
--
--- Patch [4]: [PATCH v3 4/4] arm64: dts: rockchip: enable HDMI RX audio capture on Orange Pi 5 Plus ---
commit 030cd8fd5334b79e1751dec57b1de1f5fa4e3df3
Author: Igor Paunovic <royalnet026@gmail.com>
arm64: dts: rockchip: enable HDMI RX audio capture on Orange Pi 5 Plus
This patch routes the HDMI receiver audio to the i2s7_8ch interface. It creates
a simple-audio-card configuration to expose a capture-only ALSA card driven
by the HDMI input. The setup uses the receiver as the bitclock and frame master.
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> index 145986695720a..2a68610cddbc3 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> @@ -37,6 +37,22 @@ hdmi1_con_in: endpoint {
> };
> };
>
> + hdmiin-sound {
> + compatible = "simple-audio-card";
> + simple-audio-card,name = "rockchip,hdmiin";
> + simple-audio-card,format = "i2s";
> + simple-audio-card,bitclock-master = <&hdmiin_codec>;
> + simple-audio-card,frame-master = <&hdmiin_codec>;
> +
> + simple-audio-card,cpu {
> + sound-dai = <&i2s7_8ch>;
> + };
> +
> + hdmiin_codec: simple-audio-card,codec {
> + sound-dai = <&hdmi_receiver 0>;
[Severity: High]
Does exposing this codec to the ALSA subsystem trigger a suspend regression in
the hdmirx driver?
Looking at the underlying codec driver hdmirx_suspend() in snps_hdmirx.c:
drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c:hdmirx_suspend()
{
struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev);
hdmirx_disable_irq(dev);
/* TODO store CEC HW state */
disable_irq(hdmirx_dev->cec->irq);
return hdmirx_disable(dev);
}
The audio_work delayed work is queued on system_unbound_wq, which is not
freezable, but this suspend callback doesn't cancel it.
If system suspend is initiated while audio capture is active, the worker
could fire after clocks are disabled via hdmirx_disable(), resulting in
a bus fault when it performs MMIO reads.
[Severity: Medium]
Will this audio capture work correctly on big-endian architectures?
The underlying hdmirx_audio_fs() driver function uses be32_to_cpu() for an
unconditional byte swap when calculating the ACR subpacket:
drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c:hdmirx_audio_fs()
{
...
acr_cts = be32_to_cpu((__force __be32)acr_pb3_0) & 0xfffff;
acr_n = (be32_to_cpu((__force __be32)acr_pb7_4) & 0x0fffff00) >> 8;
...
}
Since be32_to_cpu() behaves as a no-op on big-endian CPUs, the bytes remain
unswapped, causing the bitwise masking to extract the wrong bytes for the
ACR CTS and N fields.
Should swab32() be used here instead to ensure the byte swap happens
unconditionally on all architectures?
> + };
> + };
> +
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260718085728.6797-1-royalnet026@gmail.com?part=4
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox