From 3473583f56d5e0e8054878d1f6f7afb949f7156d Mon Sep 17 00:00:00 2001 From: Monish Chunara Date: Thu, 11 Jun 2026 16:57:19 +0530 Subject: [PATCH 1/9] FROMLIST: arm64: dts: qcom: monaco-evk-emmc: Remove explicit UFS disablement The eMMC overlay currently explicitly disables the UFS host controller and overrides the vreg_l8a voltage. This causes unnecessary UFS disablement in scenarios where UFS is the boot medium and eMMC is used as secondary storage. Since UFS and eMMC share a common VDD rail, their mutual exclusivity is now managed dynamically via DT-fixup logic. Remove these static entries from the overlay to allow flexible storage configurations. Link: https://lore.kernel.org/all/20260616130347.3096034-1-monish.chunara@oss.qualcomm.com/ Signed-off-by: Monish Chunara --- arch/arm64/boot/dts/qcom/monaco-evk-emmc.dtso | 9 --------- 1 file changed, 9 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/monaco-evk-emmc.dtso b/arch/arm64/boot/dts/qcom/monaco-evk-emmc.dtso index 70edbb1248a5a..ef4477e1e9f36 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk-emmc.dtso +++ b/arch/arm64/boot/dts/qcom/monaco-evk-emmc.dtso @@ -35,12 +35,3 @@ status = "okay"; }; - -&ufs_mem_hc { - status = "disabled"; -}; - -&vreg_l8a { - regulator-min-microvolt = <2960000>; - regulator-max-microvolt = <2960000>; -}; From 6d417131485c19cf9e72bf54cf8c6a72e9959349 Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Wed, 3 Jun 2026 16:54:23 +0800 Subject: [PATCH 2/9] FROMLIST: PCI: qcom: Set max OPP before DBI access during resume During resume, qcom_pcie_icc_opp_update() may access DBI registers before the OPP votes are restored, which can trigger NoC errors. Set the PCIe controller to the maximum OPP first in resume_noirq(), then proceed with link/DBI accesses. The OPP is later updated again based on the actual link bandwidth requirements. Also introduce a small helper to reuse the max-OPP setup path shared with probe. Fixes: 5b6272e0efd5 ("PCI: qcom: Add OPP support to scale performance") Link: https://lore.kernel.org/all/20260416-setmaxopp-v1-1-6a74e2d945a0@oss.qualcomm.com/ Signed-off-by: Qiang Yu Signed-off-by: Ziyue Zhang --- drivers/pci/controller/dwc/pcie-qcom.c | 42 ++++++++++++++++---------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 5d812003da4f7..712c14e18a676 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1666,6 +1666,22 @@ static void qcom_pcie_icc_opp_update(struct qcom_pcie *pcie) } } +static int qcom_pcie_set_max_opp(struct device *dev) +{ + unsigned long max_freq = ULONG_MAX; + struct dev_pm_opp *opp; + int ret; + + opp = dev_pm_opp_find_freq_floor(dev, &max_freq); + if (IS_ERR(opp)) + return PTR_ERR(opp); + + ret = dev_pm_opp_set_opp(dev, opp); + dev_pm_opp_put(opp); + + return ret; +} + static int qcom_pcie_link_transition_count(struct seq_file *s, void *data) { struct qcom_pcie *pcie = (struct qcom_pcie *)dev_get_drvdata(s->private); @@ -1839,10 +1855,8 @@ static int qcom_pcie_parse_legacy_binding(struct qcom_pcie *pcie) static int qcom_pcie_probe(struct platform_device *pdev) { const struct qcom_pcie_cfg *pcie_cfg; - unsigned long max_freq = ULONG_MAX; struct qcom_pcie_port *port, *tmp; struct device *dev = &pdev->dev; - struct dev_pm_opp *opp; struct qcom_pcie *pcie; struct dw_pcie_rp *pp; struct resource *res; @@ -1946,21 +1960,9 @@ static int qcom_pcie_probe(struct platform_device *pdev) * probe(), OPP will be updated using qcom_pcie_icc_opp_update(). */ if (!ret) { - opp = dev_pm_opp_find_freq_floor(dev, &max_freq); - if (IS_ERR(opp)) { - ret = PTR_ERR(opp); - dev_err_probe(pci->dev, ret, - "Unable to find max freq OPP\n"); - goto err_pm_runtime_put; - } else { - ret = dev_pm_opp_set_opp(dev, opp); - } - - dev_pm_opp_put(opp); + ret = qcom_pcie_set_max_opp(dev); if (ret) { - dev_err_probe(pci->dev, ret, - "Failed to set OPP for freq %lu\n", - max_freq); + dev_err_probe(dev, ret, "Failed to set max OPP in probe\n"); goto err_pm_runtime_put; } @@ -2112,6 +2114,14 @@ static int qcom_pcie_resume_noirq(struct device *dev) goto disable_icc_mem; } else { if (pm_suspend_target_state != PM_SUSPEND_MEM) { + if (pcie->use_pm_opp) { + ret = qcom_pcie_set_max_opp(dev); + if (ret) { + dev_err(dev, "Failed to set max OPP in resume: %d\n", ret); + return ret; + } + } + ret = icc_enable(pcie->icc_cpu); if (ret) { dev_err(dev, "Failed to enable CPU-PCIe interconnect path: %d\n", From 88a474ebf0ec788c629fe2daf849e5926834a5df Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Wed, 3 Jun 2026 17:12:57 +0800 Subject: [PATCH 3/9] WORKAROUND: phy: qcom: qmp-pcie: add x1e80100 qref supplies All PCIe PHYs on the X1E80100 SOC require the vdda-qref, which feeds QREF clocks provided by the TCSR device. Hence, restore the vdda-qref request for the 6th and the 3th PCIe instance by reverting commit 031b46b ("phy: qcom: qmp-pcie: drop bogus x1e80100 qref supplies") and commit eb7a22f("phy: qcom: qmp-pcie: drop bogus x1e80100 qref supply"). For the 4th PCIe instance (Gen3 x2), add a new driver data entry, namely x1e80100_qmp_gen3x2_pciephy_cfg, which is a copy of sm8550_qmp_gen3x2_pciephy_cfg but uses sm8550_qmp_phy_vreg_l instead. Workaround will be reverted once the vote qref regulator for PCIe available in upstream. Fixes: eb7a22f ("phy: qcom: qmp-pcie: drop bogus x1e80100 qref supplies") Fixes: 031b46b ("phy: qcom: qmp-pcie: drop bogus x1e80100 qref supplies") Fixes: 606060c ("phy: qcom-qmp-pcie: Add support for X1E80100 g3x2 and g4x2 PCIE") Cc: Johan Hovold Cc: Abel Vesa Signed-off-by: Wenbin Yao Signed-off-by: Qiang Yu Signed-off-by: Ziyue Zhang --- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 41 ++++++++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index d9571af517061..edd02dbc451a5 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -4331,6 +4331,33 @@ static const struct qmp_phy_cfg sa8775p_qmp_gen4x4_pciephy_cfg = { .phy_status = PHYSTATUS_4_20, }; +static const struct qmp_phy_cfg x1e80100_qmp_gen3x2_pciephy_cfg = { + .lanes = 2, + + .offsets = &qmp_pcie_offsets_v5, + + .tbls = { + .serdes = sm8550_qmp_gen3x2_pcie_serdes_tbl, + .serdes_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_serdes_tbl), + .tx = sm8550_qmp_gen3x2_pcie_tx_tbl, + .tx_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_tx_tbl), + .rx = sm8550_qmp_gen3x2_pcie_rx_tbl, + .rx_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_rx_tbl), + .pcs = sm8550_qmp_gen3x2_pcie_pcs_tbl, + .pcs_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_pcs_tbl), + .pcs_misc = sm8550_qmp_gen3x2_pcie_pcs_misc_tbl, + .pcs_misc_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_pcs_misc_tbl), + }, + .reset_list = sdm845_pciephy_reset_l, + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), + .vreg_list = sm8550_qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(sm8550_qmp_phy_vreg_l), + .regs = pciephy_v5_regs_layout, + + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, + .phy_status = PHYSTATUS, +}; + static const struct qmp_phy_cfg x1e80100_qmp_gen4x2_pciephy_cfg = { .lanes = 2, @@ -4353,8 +4380,8 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x2_pciephy_cfg = { .reset_list = sdm845_pciephy_reset_l, .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sm8550_qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(sm8550_qmp_phy_vreg_l), .regs = pciephy_v6_regs_layout, .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, @@ -4386,8 +4413,8 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x4_pciephy_cfg = { .reset_list = sdm845_pciephy_reset_l, .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sm8550_qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(sm8550_qmp_phy_vreg_l), .regs = pciephy_v6_regs_layout, .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, @@ -4417,8 +4444,8 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x8_pciephy_cfg = { .reset_list = sdm845_pciephy_reset_l, .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sm8550_qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(sm8550_qmp_phy_vreg_l), .regs = pciephy_v6_regs_layout, .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, @@ -5329,7 +5356,7 @@ static const struct of_device_id qmp_pcie_of_match_table[] = { .data = &sm8750_qmp_gen3x2_pciephy_cfg, }, { .compatible = "qcom,x1e80100-qmp-gen3x2-pcie-phy", - .data = &sm8550_qmp_gen3x2_pciephy_cfg, + .data = &x1e80100_qmp_gen3x2_pciephy_cfg, }, { .compatible = "qcom,x1e80100-qmp-gen4x2-pcie-phy", .data = &x1e80100_qmp_gen4x2_pciephy_cfg, From 66a12553986cbb31a53ab16f85684f9e9e3576dc Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Wed, 3 Jun 2026 17:09:36 +0800 Subject: [PATCH 4/9] WORKAROUND: arm64: dts: qcom: Add qref supply for PCIe PHYs All PCIe PHYs on X1E80100 require vdda-qref power supplies, but this is missing in the current PHY device tree node. The PCIe port can still function because the regulator L3J, which vdda-qref consumes, is voted by other components. Since the device tree should accurately describe the hardware, add the vdda-qref power supply explicitly in all PCIe PHY device nodes. Workaround will be reverted once the vote qref regulator for PCIe available in upstream. Signed-off-by: Qiang Yu Signed-off-by: Ziyue Zhang --- arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi b/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi index 5d9af325c931e..974edc6758f1f 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi @@ -415,6 +415,7 @@ &pcie3_phy { vdda-phy-supply = <&vreg_l3c_0p8>; vdda-pll-supply = <&vreg_l3e_1p2>; + vdda-qref-supply = <&vreg_l3j_0p8>; status = "okay"; }; @@ -429,6 +430,7 @@ &pcie4_phy { vdda-phy-supply = <&vreg_l3i_0p8>; vdda-pll-supply = <&vreg_l3e_1p2>; + vdda-qref-supply = <&vreg_l3j_0p8>; status = "okay"; }; @@ -443,6 +445,7 @@ &pcie5_phy { vdda-phy-supply = <&vreg_l3i_0p8>; vdda-pll-supply = <&vreg_l3e_1p2>; + vdda-qref-supply = <&vreg_l3j_0p8>; status = "okay"; }; @@ -457,6 +460,7 @@ &pcie6a_phy { vdda-phy-supply = <&vreg_l1d_0p8>; vdda-pll-supply = <&vreg_l2j_1p2>; + vdda-qref-supply = <&vreg_l3j_0p8>; status = "okay"; }; From 79ffe29cb7cb9638ada8f4963ad41834360fd594 Mon Sep 17 00:00:00 2001 From: Jie Gan Date: Mon, 15 Jun 2026 18:16:26 +0800 Subject: [PATCH 5/9] Revert "FROMLIST: arm64: dts: qcom: monaco: fix wrong connection for the replicator" This reverts commit 99beb1dbcb3dee954e5d1c3984ee373fe95140ea. This is a corrective patch for a mistake that causes an ETR connection issue; it needs to be reverted. This patch aims to fix a mistake issue made by maintainer on upstream, but the issue does not exist on qli2.0. Signed-off-by: Jie Gan --- arch/arm64/boot/dts/qcom/monaco.dtsi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index 87b83c3fe2d35..4eedf210fe0e9 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -2935,14 +2935,6 @@ #address-cells = <1>; #size-cells = <0>; - port@0 { - reg = <0>; - - swao_rep_out0: endpoint { - remote-endpoint = <&qdss_rep_in>; - }; - }; - port@1 { reg = <1>; @@ -3652,6 +3644,14 @@ #address-cells = <1>; #size-cells = <0>; + port@0 { + reg = <0>; + + swao_rep_out0: endpoint { + remote-endpoint = <&qdss_rep_in>; + }; + }; + port@1 { reg = <1>; From d2fa884ed61a208fb1d6929ea3ddeef62a53901d Mon Sep 17 00:00:00 2001 From: Kiran Patchala Date: Thu, 11 Jun 2026 12:24:31 +0530 Subject: [PATCH 6/9] Revert "net: stmmac: dwmac-qcom-ethqos: Use max frequency for clk_ptp_ref" This reverts commit db845b9b2040f4ed5f8bce6cd30103e3b8557566. Reason: this change causes the PTP clock to always be in Turbo mode which can cause power KPI regression. Signed-off-by: Kiran Patchala --- .../stmicro/stmmac/dwmac-qcom-ethqos.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c index 594e7ff82f2f1..986e5ce7aab96 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c @@ -740,23 +740,6 @@ static void ethqos_clks_disable(void *data) ethqos_clks_config(data, false); } -static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv) -{ - struct plat_stmmacenet_data *plat_dat = priv->plat; - int err; - - if (!plat_dat->clk_ptp_ref) - return; - - /* Max the PTP ref clock out to get the best resolution possible */ - err = clk_set_rate(plat_dat->clk_ptp_ref, ULONG_MAX); - if (err) - netdev_err(priv->dev, "Failed to max out clk_ptp_ref: %d\n", err); - plat_dat->clk_ptp_rate = clk_get_rate(plat_dat->clk_ptp_ref); - - netdev_dbg(priv->dev, "PTP rate %lu\n", plat_dat->clk_ptp_rate); -} - static int qcom_ethqos_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -849,7 +832,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev) plat_dat->bsp_priv = ethqos; plat_dat->fix_mac_speed = ethqos_fix_mac_speed; plat_dat->dump_debug_regs = rgmii_dump; - plat_dat->ptp_clk_freq_config = ethqos_ptp_clk_freq_config; plat_dat->core_type = DWMAC_CORE_GMAC4; if (ethqos->has_emac_ge_3) plat_dat->dwmac4_addrs = &data->dwmac4_addrs; From 6a2be8c8ef2d53a59d5166ffcbefa5e6337893da Mon Sep 17 00:00:00 2001 From: Hariprasad kelam Date: Wed, 17 Jun 2026 14:15:45 +0530 Subject: [PATCH 7/9] QCLINUX: qcom.config: Enable Intel IXGBE driver Enable the IXGBE and IXGBEVF drivers to support the Intel X550 T2 NIC on QLI boards with SR-IOV support. Signed-off-by: Hariprasad kelam --- arch/arm64/configs/qcom.config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 9466461272165..8f9d6340067cc 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -33,6 +33,8 @@ CONFIG_GUNYAH_WATCHDOG=y CONFIG_I6300ESB_WDT=y CONFIG_IDLE_INJECT=y CONFIG_INPUT_UINPUT=y +CONFIG_IXGBE=m +CONFIG_IXGBEVF=m CONFIG_KPROBES=y CONFIG_MACVLAN=y CONFIG_MACVTAP=y From 76a58539c8c2cdef0fefc57371d38b60107b7e39 Mon Sep 17 00:00:00 2001 From: Anandu Krishnan E Date: Wed, 17 Jun 2026 21:21:11 +0530 Subject: [PATCH 8/9] FROMLIST: misc: fastrpc: map ADSP remote heap into remoteproc IOMMU domain When the remoteproc has an IOMMU (kernel running at EL2 without a separate hypervisor), memory carveouts must be explicitly mapped into the remoteproc's IOMMU domain so the DSP can access them. Without this mapping the DSP triggers an SMMU translation fault when accessing the remote heap carveout used for audio PD static process creation. Add has_iommu to fastrpc_channel_ctx, set from the "iommus" property of the remoteproc DT node. When set, map the ADSP remote heap carveout into the remoteproc's IOMMU domain using an identity mapping (IOVA == PA) via iommu_map(), and skip qcom_scm_assign_mem() which is only needed when a separate hypervisor manages inter-VM memory access control. Introduce fastrpc_remote_heap_map() and fastrpc_remote_heap_unmap() helpers to encapsulate the IOMMU domain lookup and map/unmap. Link: https://lore.kernel.org/all/20260618-audio_fix_clean_v3-v1-1-ec1ee66fe455@oss.qualcomm.com/ Signed-off-by: Anandu Krishnan E --- drivers/misc/fastrpc.c | 136 ++++++++++++++++++++++++++++++++++------- 1 file changed, 114 insertions(+), 22 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 60f4df2e4fc78..67c2ad7046215 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -300,6 +301,8 @@ struct fastrpc_channel_ctx { struct fastrpc_buf *remote_heap; bool secure; bool unsigned_support; + /* set when remoteproc has an IOMMU; use iommu_map instead of hyp_assign */ + bool has_iommu; bool poll_mode_supported; u64 dma_mask; }; @@ -2538,10 +2541,65 @@ static const char *const fastrpc_poll_supported_machines[] = { "qcom,x1e80100", "qcom,x1p42100", NULL, }; +static int fastrpc_remote_heap_map(struct device *rdev, + struct device_node *rproc_node, + struct fastrpc_buf *heap) +{ + struct platform_device *rproc_pdev; + struct iommu_domain *domain; + int ret; + + rproc_pdev = of_find_device_by_node(rproc_node); + if (!rproc_pdev) { + dev_err(rdev, "failed to find remoteproc platform device\n"); + return -ENODEV; + } + + domain = iommu_get_domain_for_dev(&rproc_pdev->dev); + if (!domain) { + put_device(&rproc_pdev->dev); + dev_err(rdev, "no IOMMU domain for remoteproc\n"); + return -ENODEV; + } + + ret = iommu_map(domain, heap->phys, heap->phys, heap->size, + IOMMU_READ | IOMMU_WRITE, GFP_KERNEL); + if (ret) + dev_err(rdev, "failed to map remote heap phys=0x%llx size=0x%llx err=%d\n", + heap->phys, heap->size, ret); + + put_device(&rproc_pdev->dev); + return ret; +} + +static void fastrpc_remote_heap_unmap(struct rpmsg_device *rpdev, + struct fastrpc_buf *heap) +{ + struct device_node *rproc_node; + struct platform_device *rproc_pdev; + struct iommu_domain *domain; + + rproc_node = of_get_parent(of_get_parent(rpdev->dev.of_node)); + if (!rproc_node) + return; + + rproc_pdev = of_find_device_by_node(rproc_node); + of_node_put(rproc_node); + if (!rproc_pdev) + return; + + domain = iommu_get_domain_for_dev(&rproc_pdev->dev); + if (domain) + iommu_unmap(domain, heap->phys, heap->size); + + put_device(&rproc_pdev->dev); +} + static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) { struct device *rdev = &rpdev->dev; struct fastrpc_channel_ctx *data; + struct device_node *rproc_node; int i, err, domain_id = -1, vmcount; const char *domain; bool secure_dsp; @@ -2582,30 +2640,55 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) } } + rproc_node = of_get_parent(of_get_parent(rdev->of_node)); + if (rproc_node) + data->has_iommu = of_property_present(rproc_node, "iommus"); + if (domain_id == SDSP_DOMAIN_ID || domain_id == ADSP_DOMAIN_ID) { struct resource res; - u64 src_perms; err = of_reserved_mem_region_to_resource(rdev->of_node, 0, &res); if (!err) { if (domain_id == ADSP_DOMAIN_ID) { data->remote_heap = kzalloc(sizeof(*data->remote_heap), GFP_KERNEL); - if (!data->remote_heap) - return -ENOMEM; + if (!data->remote_heap) { + err = -ENOMEM; + goto err_put_node; + } data->remote_heap->phys = res.start; data->remote_heap->size = resource_size(&res); + + if (data->has_iommu) { + err = fastrpc_remote_heap_map(rdev, + rproc_node, + data->remote_heap); + if (err) { + kfree(data->remote_heap); + data->remote_heap = NULL; + goto err_put_node; + } + } } - src_perms = BIT(QCOM_SCM_VMID_HLOS); - err = qcom_scm_assign_mem(res.start, resource_size(&res), &src_perms, - data->vmperms, data->vmcount); - if (err) - goto err_free_data; + if (!data->has_iommu) { + u64 src_perms = BIT(QCOM_SCM_VMID_HLOS); + + err = qcom_scm_assign_mem(res.start, + resource_size(&res), + &src_perms, + data->vmperms, + data->vmcount); + if (err) + goto err_put_node; + } } } + of_node_put(rproc_node); + rproc_node = NULL; + secure_dsp = !(of_property_read_bool(rdev->of_node, "qcom,non-secure-domain")); data->secure = secure_dsp; @@ -2662,6 +2745,9 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) if (data->secure_fdevice) misc_deregister(&data->secure_fdevice->miscdev); +err_put_node: + of_node_put(rproc_node); + err_free_data: kfree(data); return err; @@ -2703,21 +2789,27 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) if (cctx->secure_fdevice) misc_deregister(&cctx->secure_fdevice->miscdev); - if (cctx->remote_heap && cctx->vmcount) { - u64 src_perms = 0; - struct qcom_scm_vmperm dst_perms; - - for (u32 i = 0; i < cctx->vmcount; i++) - src_perms |= BIT(cctx->vmperms[i].vmid); - - dst_perms.vmid = QCOM_SCM_VMID_HLOS; - dst_perms.perm = QCOM_SCM_PERM_RWX; - - err = qcom_scm_assign_mem(cctx->remote_heap->phys, - cctx->remote_heap->size, &src_perms, - &dst_perms, 1); - if (!err) + if (cctx->remote_heap) { + if (cctx->has_iommu) { + fastrpc_remote_heap_unmap(rpdev, cctx->remote_heap); kfree(cctx->remote_heap); + cctx->remote_heap = NULL; + } else if (cctx->vmcount) { + u64 src_perms = 0; + struct qcom_scm_vmperm dst_perms; + + for (u32 i = 0; i < cctx->vmcount; i++) + src_perms |= BIT(cctx->vmperms[i].vmid); + + dst_perms.vmid = QCOM_SCM_VMID_HLOS; + dst_perms.perm = QCOM_SCM_PERM_RWX; + + err = qcom_scm_assign_mem(cctx->remote_heap->phys, + cctx->remote_heap->size, + &src_perms, &dst_perms, 1); + if (!err) + kfree(cctx->remote_heap); + } } of_platform_depopulate(&rpdev->dev); From 5086fd78561b5f1a8824806decd2e9bf2cfe3d6f Mon Sep 17 00:00:00 2001 From: Milen Mitkov Date: Mon, 1 Jun 2026 13:51:01 +0300 Subject: [PATCH 9/9] QCLINUX: arm64: dts: qcom: talos: Add GMSL deserializer and sensor Adds deserializer and camera sensor nodes to the Talos device tree. Talos features a single GMSL deserializer and exposes a single GMSL camera. Signed-off-by: Milen Mitkov --- .../boot/dts/qcom/talos-camera-sensor.dtsi | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/talos-camera-sensor.dtsi b/arch/arm64/boot/dts/qcom/talos-camera-sensor.dtsi index 006b345cc0023..5ab6738927033 100644 --- a/arch/arm64/boot/dts/qcom/talos-camera-sensor.dtsi +++ b/arch/arm64/boot/dts/qcom/talos-camera-sensor.dtsi @@ -6,6 +6,63 @@ #include &cam_cci { + /* GMSL deserializer 0 - max9296a */ + qcom,cam-gmsl-deserializer0 { + cell-index = <2>; + csiphy-sd-index = <1>; + sensor-position-roll = <0>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + cam_vio-supply = <&vreg_s4a>; + regulator-names = "cam_vio"; + power-domains = <&camcc TITAN_TOP_GDSC>; + rgltr-cntrl-support; + pwm-switch; + rgltr-min-voltage = <1800000>; + rgltr-max-voltage = <1800000>; + rgltr-load-current = <120000>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend>; + gpios = <&tlmm 29 0>; + gpio-reset = <0>; + gpio-req-tbl-num = <0>; + gpio-req-tbl-flags = <0>; + gpio-req-tbl-label = "CAM_RESET0"; + cci-master = <1>; + clocks = <&camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "nominal"; + clock-rates = <24000000>; + status = "ok"; + + ranges; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + deser0_port0: endpoint { + remote-endpoint = <&gmsl_sensor0_ep>; + }; + }; + }; + + /* GMSL deserializer 0 sensor 0 */ + qcom,cam-gmsl-sensor0 { + cell-index = <3>; + compatible = "qcom,cam-gmsl-sensor"; + + csiphy-sd-index = <1>; + status = "ok"; + + ranges; + port { + gmsl_sensor0_ep: endpoint { + remote-endpoint = <&deser0_port0>; + }; + }; + }; /*cam0-imx577*/ tl_slot0: qcom,cam-sensor0 { compatible = "qcom,cam-sensor";