Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 2/2] phy: mediatek: Add support for PCI-Express Gen4 S-PHY
From: AngeloGioacchino Del Regno @ 2026-07-20 13:53 UTC (permalink / raw)
  To: chunfeng.yun
  Cc: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, matthias.bgg,
	angelogioacchino.delregno, linux-arm-kernel, linux-mediatek,
	linux-phy, devicetree, linux-kernel, kernel
In-Reply-To: <20260720135344.84183-1-angelogioacchino.delregno@collabora.com>

Add support for the PCI-Express Gen4 S-PHY found in the latest
MediaTek SoCs, including MT8196, MT8894 and similar.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/phy/mediatek/Kconfig             |   9 +
 drivers/phy/mediatek/Makefile            |   1 +
 drivers/phy/mediatek/phy-mtk-pcie-sphy.c | 561 +++++++++++++++++++++++
 3 files changed, 571 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-pcie-sphy.c

diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
index ba6461350951..77236f3084c8 100644
--- a/drivers/phy/mediatek/Kconfig
+++ b/drivers/phy/mediatek/Kconfig
@@ -13,6 +13,15 @@ config PHY_MTK_PCIE
 	  callback for PCIe GEN3 port, it supports software efuse
 	  initialization.
 
+config PHY_MTK_PCIE_SPHY
+	tristate "MediaTek PCIe S-PHY Driver"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	depends on OF
+	select GENERIC_PHY
+	help
+	  Say 'Y' here to add support for MediaTek PCIe S-PHY driver for
+	  PCI-Express Gen4 controllers as found in MT6991, MT8196 and others.
+
 config PHY_MTK_XFI_TPHY
 	tristate "MediaTek 10GE SerDes XFI T-PHY driver"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index ed0da708759b..7e984c7cfea3 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -5,6 +5,7 @@
 
 obj-$(CONFIG_PHY_MTK_DP)		+= phy-mtk-dp.o
 obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
+obj-$(CONFIG_PHY_MTK_PCIE_SPHY)		+= phy-mtk-pcie-sphy.o
 obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
 obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
 obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
diff --git a/drivers/phy/mediatek/phy-mtk-pcie-sphy.c b/drivers/phy/mediatek/phy-mtk-pcie-sphy.c
new file mode 100644
index 000000000000..6c1362b70fab
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-pcie-sphy.c
@@ -0,0 +1,561 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Copyright (c) 2026 Collabora Ltd.
+ *                    AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+#include "phy-mtk-io.h"
+
+/* PHY System Interface (SIF) registers */
+#define PEXTP_DIG_GLB_TOP				0x20
+#  define RG_XTP_BYPASS_PIPE_RST_RC			BIT(17)
+#define PEXTP_DIG_GLB_CKBG0				0x30
+#  define RG_XTP_CKBG_XTAL_STABLE_TIME_SEL		GENMASK(25, 16)
+#define PEXTP_DIG_GLB_TPLL_CTL0				0x38
+#  define RG_XTP_TPLL_SET_STABLE_TIME_SEL		GENMASK(7, 2)
+#  define RG_XTP_TPLL_PWE_ON_STABLE_TIME_SEL		GENMASK(9, 8)
+#define PEXTP_DIG_GLB_CLKREQ_CTL			0x50
+#  define RG_XTP_CKM_EN_L1S0				BIT(13)
+#  define RG_XTP_CKM_EN_L1S1				BIT(14)
+#define PEXTP_DIG_GLB_TPLL_CTL2				0xf4
+#  define RG_XTP_TPLL_ISO_EN_STABLE_TIME_SEL		GENMASK(13, 12)
+
+/* PHY System Interface Digital registers */
+#define PEXTP_DIG_LN_TRX_PIPE_IF_17			0x30e8
+#  define RG_XTP_LN_RX_LF_CTLE_CSEL_GEN4		GENMASK(14, 12)
+#define PEXTP_DIG_LN_RX_F0				0x50f0
+#  define RG_XTP_LN_RX_GEN1_CTLE1_CSEL			GENMASK(3, 0)
+#  define RG_XTP_LN_RX_GEN2_CTLE1_CSEL			GENMASK(7, 4)
+#  define RG_XTP_LN_RX_GEN3_CTLE1_CSEL			GENMASK(11, 8)
+#  define RG_XTP_LN_RX_GEN4_CTLE1_CSEL			GENMASK(15, 12)
+#define PEXTP_DIG_LN_RX2_AEQ_EDGE_0			0x6004
+#  define RG_XTP_LN_RX_AEQ_EGEQ_RATIO_GEN3		GENMASK(21, 16)
+#  define RG_XTP_LN_RX_AEQ_EGEQ_RATIO_GEN4		GENMASK(29, 24)
+#  define AEQ_EGEQ_RATIO_GEN3_TO_22			0x16
+#  define AEQ_EGEQ_RATIO_GEN4_TO_22			0x16
+
+/* PHY System Interface Analog registers */
+#define PEXTP_ANA_GLB_TPLL1_RSVD			0x902c
+#  define RG_XTP_GLB_TPLL1_P_PATH_GAIN			GENMASK(2, 0)
+#define PEXTP_ANA_GLB_BIAS_0				0x9060
+#  define RG_XTP_GLB_BIAS_INTR_CTRL			GENMASK(5, 0)
+#define PEXTP_ANA_GLB_BIAS_1				0x90c0
+#  define RG_XTP_GLB_BIAS_V2V_VTRIM			GENMASK(9, 6)
+#define PEXTP_ANA_LN_TRX_0C				0xa00c
+#  define RG_XTP_LN_TX_RSWN_IMPSEL			GENMASK(20, 16)
+#define PEXTP_ANA_LN_TRX_34				0xa034
+#  define RG_XTP_LN_RX_FE				BIT(15)
+#define PEXTP_ANA_LN_TRX_6C				0xa06c
+#  define RG_XTP_LN_RX_AEQ_CTLE_ERR_TYPE		GENMASK(14, 13)
+#   define AEQ_CTLE_SEARCH_ERR_TYPE_H1P5		0
+#   define AEQ_CTLE_SEARCH_ERR_TYPE_H1P5_H2P5		1
+#   define AEQ_CTLE_SEARCH_ERR_TYPE_P1P5_H2P5_H3P5	2
+#define PEXTP_ANA_LN_TRX_A0				0xa0a0
+#  define RG_XTP_LN_TX_IMPSEL_PMOS			GENMASK(4, 0)
+#  define RG_XTP_LN_TX_IMPSEL_NMOS			GENMASK(11, 7)
+#  define RG_XTP_LN_RX_IMPSEL				GENMASK(15, 12)
+#define PEXTP_ANA_LN_TRX_A8				0xa0a8
+#  define RG_XTP_LN_RX_LEQ_RL_CTLE_CAL			GENMASK(6, 2)
+#  define RG_XTP_LN_RX_LEQ_RL_VGA_CAL			GENMASK(11, 7)
+#  define RG_XTP_LN_RX_LEQ_RL_DFE_CAL			GENMASK(23, 19)
+#define PEXTP_DIG_LN_TX_LC_TABLE_RSWN_4			0xb004
+#define PEXTP_DIG_LN_TX_LC_TABLE_RSWN_8			0xb008
+#define PEXTP_DIG_LN_TX_LC_TABLE_RSWN_C			0xb00c
+#define PEXTP_DIG_LN_TX_LC_TABLE_RSWN_10		0xb010
+#define PEXTP_DIG_LN_TX_LC_TABLE_RSWN_14		0xb014
+#define PEXTP_DIG_LN_TX_LC_TABLE_RSWN_18		0xb018
+#  define RG_XTP_LN_TX_LC_PRESET_MGx_Px_CM1		GENMASK(5, 0)
+#  define RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0		GENMASK(13, 8)
+#  define RG_XTP_LN_TX_LC_PRESET_MGx_Px_CP1		GENMASK(21, 16)
+#define PEXTP_REG_LANE(x)				((x) * 0x100)
+
+/* PHY Clock Management (CKM) registers */
+#define XTP_CKM_FORCE_6					0x38
+#  define RG_CKM_BIAS_WAIT_PRD_US			GENMASK(21, 16)
+#define XTP_CKM_REG_SPLL_FBKDIV_5			0xd4
+#  define RG_CKM_CKTX_IMPSEL_PMOS			GENMASK(19, 16)
+#  define RG_CKM_CKTX_IMPSEL_NMOS			GENMASK(23, 20)
+#  define RG_CKM_CKTX_IMPSEL_SW				GENMASK(27, 24)
+
+/* Calibration data from eFuses */
+#define MTK_PCIE_SPHY_CALIBRATION_MAX_DATA_LANES	2
+#define MTK_PCIE_SPHY_CALIBRATION_LAST_QUIRK_VER	4
+
+/**
+ * struct mtk_pcie_sphy_imp_sel - Impedance Selection parameters
+ * @pmos: Impedance selection for P-Channel MOSFET
+ * @nmos: Impedance selection for N-Channel MOSFET
+ */
+struct mtk_pcie_sphy_imp_sel {
+	u8 pmos;
+	u8 nmos;
+};
+
+/**
+ * struct mtk_pcie_sphy_efuse - eFuse calibration data for S-PHY
+ * @int_r_ctrl:     Internal resistor selection of TX Bias Current
+ * @xtp_vtrim:      XTP Bias V2V voltage calibration
+ * @cktx_impsel:    SPLL CKTX Impedance Selection (P and N MOSFET)
+ * @cktx_r_mid:     SPLL CKTX Intermediate Transition Impedance (Rmid)
+ * @rx_leq_rl_ctle: RX Front-End Return Loss Continuous Time Linear Equalization value
+ * @rx_leq_rl_vga:  RX Front-End Return Loss Variable Gain Amplifier value
+ * @rx_leq_rl_dfe:  RX Front-End Return Loss Decision Feedback Equalization value
+ * @rx_impsel:      RX Impedance Selection
+ * @tx_impsel:      TX Impedance Selection (P and N MOSFET)
+ * @tx_rswn_impsel: TX RSWn (Switch Resistance) impedance selection
+ * @supported:      eFuse calibration data is supported
+ */
+struct mtk_pcie_sphy_efuse {
+	u8 int_r_ctrl;
+	u8 xtp_vtrim;
+	struct mtk_pcie_sphy_imp_sel cktx_impsel;
+	u8 cktx_r_mid;
+	u8 rx_leq_rl_ctle;
+	u8 rx_leq_rl_vga;
+	u8 rx_leq_rl_dfe;
+	u8 rx_impsel;
+	struct mtk_pcie_sphy_imp_sel tx_impsel;
+	u8 tx_rswn_impsel[MTK_PCIE_SPHY_CALIBRATION_MAX_DATA_LANES];
+	bool supported;
+};
+
+/**
+ * struct mtk_pcie_sphy - PCI-Express S-PHY driver main structure
+ * @dev:         Pointer to device structure
+ * @phy:         Pointer to generic phy structure
+ * @sif_base:    IO mapped register base address of system interface
+ * @ckm_base:    IO mapped register base address of clock management interface
+ * @num_lanes:   Number of lanes
+ * @calibration: eFuse calibration data for S-PHY
+ */
+struct mtk_pcie_sphy {
+	struct device *dev;
+	struct phy *phy;
+	void __iomem *sif_base;
+	void __iomem *ckm_base;
+	u8 num_lanes;
+	struct mtk_pcie_sphy_efuse calibration;
+};
+
+static void mtk_pcie_sphy_apply_calibration(struct mtk_pcie_sphy *pcie_sphy)
+{
+	struct mtk_pcie_sphy_efuse *cal = &pcie_sphy->calibration;
+	int i;
+
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_ANA_GLB_BIAS_0,
+			     RG_XTP_GLB_BIAS_INTR_CTRL, cal->int_r_ctrl);
+
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_ANA_GLB_BIAS_1,
+			     RG_XTP_GLB_BIAS_V2V_VTRIM, cal->xtp_vtrim);
+
+	mtk_phy_update_field(pcie_sphy->ckm_base + XTP_CKM_REG_SPLL_FBKDIV_5,
+			     RG_CKM_CKTX_IMPSEL_PMOS, cal->cktx_impsel.pmos);
+
+	mtk_phy_update_field(pcie_sphy->ckm_base + XTP_CKM_REG_SPLL_FBKDIV_5,
+			     RG_CKM_CKTX_IMPSEL_NMOS, cal->cktx_impsel.nmos);
+
+	mtk_phy_update_field(pcie_sphy->ckm_base + XTP_CKM_REG_SPLL_FBKDIV_5,
+			     RG_CKM_CKTX_IMPSEL_SW, cal->cktx_r_mid);
+
+	for (i = 0; i < pcie_sphy->num_lanes; i++) {
+		void __iomem *sif_lane_base = pcie_sphy->sif_base + PEXTP_REG_LANE(i);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_0C,
+				     RG_XTP_LN_TX_RSWN_IMPSEL, cal->tx_rswn_impsel[i]);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A8,
+				     RG_XTP_LN_RX_LEQ_RL_CTLE_CAL, cal->rx_leq_rl_ctle);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A8,
+				     RG_XTP_LN_RX_LEQ_RL_VGA_CAL, cal->rx_leq_rl_vga);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A8,
+				     RG_XTP_LN_RX_LEQ_RL_DFE_CAL, cal->rx_leq_rl_dfe);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A0,
+				     RG_XTP_LN_RX_IMPSEL, cal->rx_impsel);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A0,
+				     RG_XTP_LN_TX_IMPSEL_PMOS, cal->tx_impsel.pmos);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A0,
+				     RG_XTP_LN_TX_IMPSEL_NMOS, cal->tx_impsel.nmos);
+	}
+}
+
+/**
+ * mtk_pcie_sphy_init() - Initialize the PCI-Express S-PHY
+ * @phy: the phy to be initialized
+ *
+ * The hardware settings will be reset during suspend, it should be
+ * reinitialized when the consumer calls phy_init() again on resume.
+ */
+static int mtk_pcie_sphy_init(struct phy *phy)
+{
+	struct mtk_pcie_sphy *pcie_sphy = phy_get_drvdata(phy);
+	struct mtk_pcie_sphy_imp_sel tx_impsel;
+	int i;
+
+	/* Set CKM Bias wait time to 4 microseconds */
+	mtk_phy_update_field(pcie_sphy->ckm_base + XTP_CKM_FORCE_6,
+			     RG_CKM_BIAS_WAIT_PRD_US, 4);
+
+	/* TPLL needs 63 ref_ck ticks to stabilize when setting frequency */
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_DIG_GLB_TPLL_CTL0,
+			     RG_XTP_TPLL_SET_STABLE_TIME_SEL, 63);
+
+	/* TPLL needs 3 ref_ck ticks to stabilize when powering on... */
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_DIG_GLB_TPLL_CTL0,
+			     RG_XTP_TPLL_PWE_ON_STABLE_TIME_SEL, 3);
+
+	/* ...and the same goes for setting isolation */
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_DIG_GLB_TPLL_CTL2,
+			     RG_XTP_TPLL_ISO_EN_STABLE_TIME_SEL, 3);
+
+	/* XTAL doesn't need any stabilization time */
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_DIG_GLB_CKBG0,
+			     RG_XTP_CKBG_XTAL_STABLE_TIME_SEL, 0);
+
+	/* Keep pextp_ckm enabled when in L1SS_L1S1 state */
+	mtk_phy_clear_bits(pcie_sphy->sif_base + PEXTP_DIG_GLB_CLKREQ_CTL, RG_XTP_CKM_EN_L1S1);
+
+	/* Set PIPE to reset TPLL */
+	mtk_phy_clear_bits(pcie_sphy->sif_base + PEXTP_DIG_GLB_TOP, RG_XTP_BYPASS_PIPE_RST_RC);
+
+	/* Set TPLL P-Path gain compensation to 1 */
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_ANA_GLB_TPLL1_RSVD,
+			     RG_XTP_GLB_TPLL1_P_PATH_GAIN, 1);
+
+	for (i = 0; i < pcie_sphy->num_lanes; i++) {
+		void __iomem *sif_lane_base = pcie_sphy->sif_base + PEXTP_REG_LANE(i);
+
+		/* Set RX Lane AEQ CTRL-E Search Error type to h1.5 + h2.5 */
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_6C,
+				     RG_XTP_LN_RX_AEQ_CTLE_ERR_TYPE,
+				     AEQ_CTLE_SEARCH_ERR_TYPE_H1P5_H2P5);
+
+		mtk_phy_set_bits(sif_lane_base + PEXTP_ANA_LN_TRX_34, RG_XTP_LN_RX_FE);
+
+		/* TRX: Select CTLE1 for RX Lane AutoEQ CTRL-E Setting on Gen4 */
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TRX_PIPE_IF_17,
+				     RG_XTP_LN_RX_LF_CTLE_CSEL_GEN4, 1);
+
+		/* Set RX Lane AutoEQ CTRL-E for PCI-Express Gen1 to Gen 4 */
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_RX_F0,
+				     RG_XTP_LN_RX_GEN1_CTLE1_CSEL, 13);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_RX_F0,
+				     RG_XTP_LN_RX_GEN2_CTLE1_CSEL, 13);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_RX_F0,
+				     RG_XTP_LN_RX_GEN3_CTLE1_CSEL, 13);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_RX_F0,
+				     RG_XTP_LN_RX_GEN4_CTLE1_CSEL, 0);
+
+		/* Set RX Lane AutoEQ's Edge EQ Ratio to 22 * 0.0625 = 1.375 */
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_RX2_AEQ_EDGE_0,
+				     RG_XTP_LN_RX_AEQ_EGEQ_RATIO_GEN3, 22);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_RX2_AEQ_EDGE_0,
+				     RG_XTP_LN_RX_AEQ_EGEQ_RATIO_GEN4, 22);
+
+		/* Setup Digital lane TX Link Characteristics Table */
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_4,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0, 10);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_4,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_CP1, 2);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_8,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0, 11);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_8,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_CP1, 1);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_C,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0, 12);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_10,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0, 13);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_10,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_CM1, 1);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_14,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0, 11);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_14,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_CM1, 1);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_18,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0, 10);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_18,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_CM1, 2);
+	}
+
+	if (pcie_sphy->calibration.supported) {
+		mtk_pcie_sphy_apply_calibration(pcie_sphy);
+
+		tx_impsel.pmos = pcie_sphy->calibration.tx_impsel.pmos;
+		tx_impsel.nmos = pcie_sphy->calibration.tx_impsel.nmos;
+	} else {
+		/* Set P=10, N=9 to prevent EMI if no calibration present */
+		tx_impsel.pmos = 10;
+		tx_impsel.nmos = 9;
+	}
+
+	/* Select TX Impedance on N and P MOSFETs */
+	for (i = 0; i < pcie_sphy->num_lanes; i++) {
+		void __iomem *sif_lane_base = pcie_sphy->sif_base + PEXTP_REG_LANE(i);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A0,
+				     RG_XTP_LN_TX_IMPSEL_PMOS, tx_impsel.pmos);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A0,
+				     RG_XTP_LN_TX_IMPSEL_NMOS, tx_impsel.nmos);
+	}
+
+	return 0;
+}
+
+static const struct phy_ops mtk_pcie_sphy_ops = {
+	.init	= mtk_pcie_sphy_init,
+	.owner	= THIS_MODULE,
+};
+
+static int mtk_pcie_sphy_get_one_cal_para(struct device *dev, const char *name, u8 max_val)
+{
+	u16 buf;
+	u8 tmp;
+	int ret;
+
+	/*
+	 * All of the calibrations are always max 8 bits long, but some may
+	 * be split between two different 8-bits cells: handle this corner
+	 * case by retrying reading as u16.
+	 */
+	ret = nvmem_cell_read_u8(dev, name, &tmp);
+	if (ret == 0)
+		buf = tmp;
+	else
+		ret = nvmem_cell_read_u16(dev, name, &buf);
+
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Cannot get calibration data for %s\n", name);
+
+	if (buf == 0) {
+		dev_info(dev, "No calibration for %s. Using defaults\n", name);
+		return -ENOENT;
+	}
+
+	if (buf > max_val)
+		return dev_err_probe(dev, -ERANGE,
+				     "Bad value %u retrieved for %s.\n", buf, name);
+
+	return buf;
+}
+
+static int mtk_pcie_sphy_get_calibration_data(struct mtk_pcie_sphy *pcie_sphy)
+{
+	struct mtk_pcie_sphy_efuse *cal = &pcie_sphy->calibration;
+	struct device *dev = pcie_sphy->dev;
+	u8 version;
+	int ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "int-r",
+					     FIELD_MAX(RG_XTP_GLB_BIAS_INTR_CTRL));
+	if (ret < 0)
+		goto end;
+	cal->int_r_ctrl = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "xtp-vtrim",
+					     FIELD_MAX(RG_XTP_GLB_BIAS_V2V_VTRIM));
+	if (ret < 0)
+		goto end;
+	cal->xtp_vtrim = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "cktx-pmos",
+					     FIELD_MAX(RG_CKM_CKTX_IMPSEL_PMOS));
+	if (ret < 0)
+		goto end;
+	cal->cktx_impsel.pmos = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "cktx-nmos",
+					     FIELD_MAX(RG_CKM_CKTX_IMPSEL_NMOS));
+	if (ret < 0)
+		goto end;
+	cal->cktx_impsel.nmos = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "cktx-r-mid",
+					     FIELD_MAX(RG_CKM_CKTX_IMPSEL_SW));
+	if (ret < 0)
+		goto end;
+	cal->cktx_r_mid = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "rxfe-lanes-rl-ctle",
+					     FIELD_MAX(RG_XTP_LN_RX_LEQ_RL_CTLE_CAL));
+	if (ret < 0)
+		goto end;
+	cal->rx_leq_rl_ctle = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "rxfe-lanes-rl-vga",
+					     FIELD_MAX(RG_XTP_LN_RX_LEQ_RL_VGA_CAL));
+	if (ret < 0)
+		goto end;
+	cal->rx_leq_rl_vga = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "rxfe-lanes-rl-dfe",
+					     FIELD_MAX(RG_XTP_LN_RX_LEQ_RL_DFE_CAL));
+	if (ret < 0)
+		goto end;
+	cal->rx_leq_rl_dfe = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "rx-lanes-imp",
+					     FIELD_MAX(RG_XTP_LN_RX_IMPSEL));
+	if (ret < 0)
+		goto end;
+	cal->rx_impsel = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "tx-lanes-pmos",
+					     FIELD_MAX(RG_XTP_LN_TX_IMPSEL_PMOS));
+	if (ret < 0)
+		goto end;
+	cal->tx_impsel.pmos = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "tx-lanes-nmos",
+					     FIELD_MAX(RG_XTP_LN_TX_IMPSEL_NMOS));
+	if (ret < 0)
+		goto end;
+	cal->tx_impsel.nmos = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "tx-ln0-rswn",
+					     FIELD_MAX(RG_XTP_LN_TX_RSWN_IMPSEL));
+	if (ret < 0)
+		goto end;
+	cal->tx_rswn_impsel[0] = ret;
+
+	if (pcie_sphy->num_lanes == 2) {
+		ret = mtk_pcie_sphy_get_one_cal_para(dev, "tx-ln1-rswn",
+						     FIELD_MAX(RG_XTP_LN_TX_RSWN_IMPSEL));
+		if (ret < 0)
+			goto end;
+		cal->tx_rswn_impsel[1] = ret;
+	}
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "cal-version", 15);
+	if (ret < 0)
+		goto end;
+	version = ret;
+
+	/* Quirk for eFuse calibration table versions 0 to 4 */
+	if ((version <= MTK_PCIE_SPHY_CALIBRATION_LAST_QUIRK_VER) &&
+	    cal->rx_leq_rl_ctle == 10) {
+		cal->rx_leq_rl_vga = cal->rx_leq_rl_ctle;
+		cal->rx_leq_rl_dfe = cal->rx_leq_rl_ctle;
+	}
+
+end:
+	if (ret < 0) {
+		/*
+		 * If any of the calibration values is missing, or if there is
+		 * no calibration at all in the eFuses, this is not a problem,
+		 * as the PHY doesn't require one to actually work.
+		 */
+		if (ret == -ENOENT) {
+			cal->supported = false;
+			return 0;
+		}
+		return ret;
+	};
+	cal->supported = true;
+
+	return 0;
+}
+
+static int mtk_pcie_sphy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct phy_provider *provider;
+	struct mtk_pcie_sphy *pcie_sphy;
+	u32 num_lanes;
+	int ret;
+
+	pcie_sphy = devm_kzalloc(dev, sizeof(*pcie_sphy), GFP_KERNEL);
+	if (!pcie_sphy)
+		return -ENOMEM;
+
+	pcie_sphy->sif_base = devm_platform_ioremap_resource_byname(pdev, "sif");
+	if (IS_ERR(pcie_sphy->sif_base))
+		return dev_err_probe(dev, PTR_ERR(pcie_sphy->sif_base),
+				     "Failed to map phy-sif base\n");
+
+	pcie_sphy->ckm_base = devm_platform_ioremap_resource_byname(pdev, "ckm");
+	if (IS_ERR(pcie_sphy->ckm_base))
+		return dev_err_probe(dev, PTR_ERR(pcie_sphy->ckm_base),
+				     "Failed to map phy-ckm base\n");
+
+	pcie_sphy->phy = devm_phy_create(dev, dev->of_node, &mtk_pcie_sphy_ops);
+	if (IS_ERR(pcie_sphy->phy))
+		return dev_err_probe(dev, PTR_ERR(pcie_sphy->phy),
+				     "Failed to create PCIe phy\n");
+
+	ret = of_property_read_u32(dev->of_node, "num-lanes", &num_lanes);
+	if (ret)
+		num_lanes = 1;
+	else if (num_lanes > 4)
+		return dev_err_probe(dev, -EINVAL, "Invalid number of lanes.\n");
+
+	pcie_sphy->num_lanes = num_lanes;
+	pcie_sphy->dev = dev;
+
+	if (pcie_sphy->num_lanes <= MTK_PCIE_SPHY_CALIBRATION_MAX_DATA_LANES) {
+		ret = mtk_pcie_sphy_get_calibration_data(pcie_sphy);
+		if (ret)
+			return ret;
+	}
+
+	phy_set_drvdata(pcie_sphy->phy, pcie_sphy);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(provider))
+		return dev_err_probe(dev, PTR_ERR(provider),
+				     "Could not register PCI-Express S-PHY\n");
+
+	return 0;
+}
+
+static const struct of_device_id mtk_pcie_sphy_of_match[] = {
+	{ .compatible = "mediatek,mt8196-pcie-sphy" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mtk_pcie_sphy_of_match);
+
+static struct platform_driver mtk_pcie_sphy_driver = {
+	.probe	= mtk_pcie_sphy_probe,
+	.driver	= {
+		.name = "mtk-pcie-sphy",
+		.of_match_table = mtk_pcie_sphy_of_match,
+	},
+};
+module_platform_driver(mtk_pcie_sphy_driver);
+
+MODULE_DESCRIPTION("MediaTek PCIe SPHY driver");
+MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
+MODULE_LICENSE("GPL");
-- 
2.55.0



^ permalink raw reply related

* Re: [PATCH net v2] net: stmmac: dwmac4: mask interrupts when stopping DMA in suspend
From: Andrew Lunn @ 2026-07-20 13:59 UTC (permalink / raw)
  To: Luis Lang
  Cc: netdev, Maxime Chevallier, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
	Alexandre Torgue, Russell King (Oracle), Oleksij Rempel,
	Ovidiu Panait, Rohan G Thomas,
	moderated list:ARM/STM32 ARCHITECTURE,
	moderated list:ARM/STM32 ARCHITECTURE, open list
In-Reply-To: <20260720111534.163416-1-luis.la@mail.de>

On Mon, Jul 20, 2026 at 01:15:29PM +0200, Luis Lang wrote:
> Since commit 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU
> interrupts"), suspending causes an interrupt storm from the RPS
> interrupt.
> Fix this by adding a deinit_chan() op to stmmac_dma_ops, which
> masks all default dma channel interrupts. This is called from
> stmmac_stop_all_dma(), so interrupts don't trigger while suspending.
> 
> Fixes: 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
> Suggested-by: Andrew Lunn <andrew@lunn.ch>
> Suggested-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
> Signed-off-by: Luis Lang <luis.la@mail.de>

Nice. Thanks for working on this.

These are the sort of patches i like to see. We see a lot of AI driven
patches fixing theoretical issues which nobody really cares about. The
submitter does not appear to understand what they are doing, maybe
compile tests it, but never boot it on real hardware.

You have built and booted lots of kernels, done git bisects, sent a
good bug report, done the work of actually fixing the problem with a
little help from us, and pretty much got the processes correct first
time. You have the basics for being a real kernel hacker. I would be
happy to receive more patches from you.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

Thanks

    Andrew


^ permalink raw reply

* Re: [PATCH RESEND v4 net-next 01/14] net: enetc: extract common helpers for MAC promiscuous mode setting
From: Joe Damato @ 2026-07-20 14:02 UTC (permalink / raw)
  To: wei.fang
  Cc: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy,
	maxime.chevallier, imx, netdev, linux-kernel, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <20260720014317.1059359-2-wei.fang@oss.nxp.com>

On Mon, Jul 20, 2026 at 09:43:03AM +0800, wei.fang@oss.nxp.com wrote:
> From: Wei Fang <wei.fang@nxp.com>
> 
> The PSIPMMR (Port Station Interface Promiscuous MAC Mode Register) in
> ENETC v4 has the same bit layout as the PSIPMR register in ENETC v1: bit
> n controls unicast promiscuous mode for SI n, and bit (n + 16) controls
> multicast promiscuous mode for SI n. The only difference between the two
> hardware generations is the register address offset.
> 
> Since the register functionality is identical, the MAC promiscuous mode
> setting code can be shared between ENETC v1 and v4 drivers.
> 
> Rename ENETC_PSIPMR to ENETC_PSIPMMR in enetc_hw.h to match the actual
> register name used in the reference manual, and extract two new common
> helper functions, enetc_set_si_uc_promisc() and
> enetc_set_si_mc_promisc(), into enetc_pf_common.c. These helpers select
> the correct register offset based on the hardware revision via
> is_enetc_rev1().
> 
> Remove the v4-specific enetc4_pf_set_si_mac_promisc() function from
> enetc4_pf.c and the duplicate PSIPMMR_SI_MAC_UP/MP macro definitions
> from enetc4_hw.h, as they are now superseded by the shared code.
> 
> Signed-off-by: Wei Fang <wei.fang@nxp.com>
> ---
>  .../net/ethernet/freescale/enetc/enetc4_hw.h  |  2 -
>  .../net/ethernet/freescale/enetc/enetc4_pf.c  | 21 +--------
>  .../ethernet/freescale/enetc/enetc_ethtool.c  |  2 +-
>  .../net/ethernet/freescale/enetc/enetc_hw.h   |  7 +--
>  .../net/ethernet/freescale/enetc/enetc_pf.c   | 11 ++---
>  .../freescale/enetc/enetc_pf_common.c         | 44 +++++++++++++++++++
>  .../freescale/enetc/enetc_pf_common.h         |  2 +
>  7 files changed, 56 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
> index f18437556a0e..6a8f2ed56017 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
> +++ b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
> @@ -69,8 +69,6 @@
>  
>  /* Port Station interface promiscuous MAC mode register */
>  #define ENETC4_PSIPMMR			0x200
> -#define  PSIPMMR_SI_MAC_UP(a)		BIT(a) /* a = SI index */
> -#define  PSIPMMR_SI_MAC_MP(a)		BIT((a) + 16)

[...]
  
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> index bf99b65d7598..66bfda60da9c 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
> @@ -180,9 +180,10 @@ enum enetc_bdr_type {TX, RX};
>  #define ENETC_PMR_PSPEED_1000M	BIT(9)
>  #define ENETC_PMR_PSPEED_2500M	BIT(10)
>  #define ENETC_PSR		0x0004 /* RO */
> -#define ENETC_PSIPMR		0x0018
> -#define ENETC_PSIPMR_SET_UP(n)	BIT(n) /* n = SI index */
> -#define ENETC_PSIPMR_SET_MP(n)	BIT((n) + 16)
> +#define ENETC_PSIPMMR		0x0018
> +#define  PSIPMMR_SI_MAC_UP(n)	BIT(n) /* n = SI index */
> +#define  PSIPMMR_SI_MAC_MP(n)	BIT((n) + 16)

I probably would have fixed the leading spaces when copying/pasting the macro,
but that seems like a nit.

I read the rest of the code a few times and it looks right to me.

Reviewed-by: Joe Damato <joe@dama.to>


^ permalink raw reply

* Re: [PATCH 2/3] nvmem: mtk-efuse: add support for 32-bit aligned reads
From: Roman Vivchar @ 2026-07-20 14:02 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, Andrew-CT Chen, Lala Lin,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <c2b85740-4372-4609-a9fa-930010f5296a@collabora.com>

On Monday, July 20th, 2026 at 3:48 PM, AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> wrote:

> On 7/15/26 16:27, Roman Vivchar via B4 Relay wrote:

...
 
> it's easier at this point if you simply do
> 
> 	if (pdata->needs_aligned_read) {
> 		econfig.stride = 4;
> 		econfig.reg_read = mtk_reg_read_aligned;
> 	} else {
> 		econfig.stride = 1;
> 		econfig.reg_read = mtk_reg_read;
> 	}
> 
> and you avoid touching mtk_reg_read entirely.

stride = 4 means we can't do something like reg = <0x1 0x1>;
For example, CPU speedbin is sitting at 0x181, but we can model that as
0x180.
cpu_speedbin: cpu-speedbin@180 {
    /* This is technically reg = <0x181 0x1> and bits = <0 2> */
    reg = <0x180 0x4>;
    bits = <8 2>;
};

I'm not sure what are mediatek preferences in the devicetree since
things change quite frequently... Downstream never triggers this hw bug
because it uses readl everywhere for each efuse.

I would keep the stride = 1 so we don't need workarounds in the DT, but
the reg_read indeed sounds better :)

Let me know if you have any objections.

Best regards,
Roman


^ permalink raw reply

* Re: [PATCH v2 18/18] KVM: arm64: Alloc simple_buffer_page using pKVM hyp allocator
From: Vincent Donnefort @ 2026-07-20 14:04 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, will, linux-arm-kernel, kvmarm, kernel-team,
	qperret
In-Reply-To: <CA+EHjTxRFSW=9fAYvikL2t48ykaiGp7O3Mg6ddXdtFZrmWWaGQ@mail.gmail.com>

On Wed, Jul 15, 2026 at 04:07:05PM +0100, Fuad Tabba wrote:
> On Mon, 6 Jul 2026 at 18:54, Vincent Donnefort <vdonnefort@google.com> wrote:
> 
> ...
> 
> > @@ -193,17 +211,8 @@ static bool hyp_trace_desc_is_valid(struct hyp_trace_desc *desc, size_t desc_siz
> >                 if ((void *)rb_desc + struct_size(rb_desc, page_va, rb_desc->nr_page_va) > desc_end)
> >                         return false;
> >
> > -               /* Overflow bpages backing memory? */
> > -               if (nr_bpages < rb_desc->nr_page_va)
> > -                       return false;
> > -
> > -               if (cpu >= hyp_nr_cpus)
> > -                       return false;
> > -
> >                 if (cpu != rb_desc->cpu)
> >                         return false;
> 
> Sashiko flagged this. Nothing here bounds nr_page_va from below, so
> with nr_page_va == 0 on every CPU the bpage size sums to 0.
> hyp_alloc() still hands back a chunk, but bpages_backing_size is
> stored as 0, so when init_mm() fails on nr_page_va < 3 the free path
> takes its if (!size) return and never frees it. The host can repeat
> it. Would validating nr_page_va >= 3 here work?

simple_ring_buffer_init_mm() already validates nr_page_va. And on error, we do
seem to rollback properly and hyp_free().

So I don't believe there's anything to do here.

> 
> I don't think the rest of Sashiko's note holds: the zero-size path
> succeeds rather than hitting -ENOMEM. And it's only reachable from the
> host kernel, not userspace.
> 
> Cheers,
> /fuad


^ permalink raw reply

* [PATCH v2 0/9] arm64: dts: imx8ulp: Device tree updates for i.MX 8ULP EVK boards
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan,
	Sherry Sun, Wei Fang

A collection of device tree fixes and additions for the i.MX 8ULP SoC
and its EVK boards:

SoC-level (imx8ulp.dtsi):
- Add DMA channel properties to LPI2C, LPUART and LPSPI nodes and
  replace hardcoded eDMA direction flags with FSL_EDMA_RX /
  FSL_EDMA_MULTI_FIFO macros for SAI and SPDIF nodes.
- Add the I3C2 controller node (Silvaco IP).
- Correct the SRAM node base address and size to cover the full 64 KB
  SSRAM P2 partition instead of only the last 4 KB.
- Add assigned-clock properties to LPUART4-7 so the clock framework
  configures the input clock automatically during probe.

Board-level (imx8ulp-evk.dts):
- Add a gpio-keys node for the power-on button (PTF31).
- Enable LPUART6 with flow control for NXP 88W8987 Bluetooth.
- Enable LPUART7 for the FT4232 PortD serial on proto1B boards.
- Reduce ENET pad drive strength and slew rate on PTE14-17/22/23 to
  fix signal overshoot.

Board-level (imx8ulp-9x9-evk.dts):
- Rename the model string from "EVK9" to "9x9 EVK" to follow the
  i.MX die-size naming convention.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Changes in v2:
- I3C2 patch: update commit message to clarify slow_clk uses a dummy clock.
- SRAM patch: update ranges and scmi-sram-section child offset/name to match new base address.
- LPUART6/7 patches: drop redundant "sleep" pinctrl state.
- DMA patch: fix trailing whitespace on lpuart4/5 dmas lines.
- Link to v1: https://patch.msgid.link/20260715-imx8ulp-dts-v1-0-19651358b599@nxp.com

---
Peng Fan (6):
      arm64: dts: imx8ulp: Add DMA channel properties and use eDMA flag macros
      arm64: dts: imx8ulp: Add I3C2 controller node
      arm64: dts: imx8ulp: Correct SRAM node address and size to cover full SSRAM P2
      arm64: dts: imx8ulp: Add assigned clock properties for LPUART nodes
      arm64: dts: imx8ulp-evk: Add gpio-keys node for power button
      arm64: dts: imx8ulp-9x9-evk: Rename model string to reflect die size

Sherry Sun (2):
      arm64: dts: imx8ulp-evk: Enable LPUART6 for Bluetooth
      arm64: dts: imx8ulp-evk: Enable LPUART7

Wei Fang (1):
      arm64: dts: imx8ulp-evk: Change the values of some PCRs of ENET

 arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts | 37 +++++++++++-
 arch/arm64/boot/dts/freescale/imx8ulp-evk.dts     | 65 +++++++++++++++++++--
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi        | 70 +++++++++++++++++++----
 3 files changed, 155 insertions(+), 17 deletions(-)
---
base-commit: cc2b5f627e8ccbae1188ef2d8be3e451d7f933a5
change-id: 20260715-imx8ulp-dts-69f9bf928d2f

Best regards,
--  
Peng Fan <peng.fan@nxp.com>



^ permalink raw reply

* [PATCH v2 1/9] arm64: dts: imx8ulp: Add DMA channel properties and use eDMA flag macros
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

Add DMA channel (dmas/dma-names) properties to peripheral nodes that
were missing them:
- LPI2C: lpi2c4, lpi2c5, lpi2c6, lpi2c7
- LPUART: lpuart4, lpuart5, lpuart6, lpuart7
- LPSPI: lpspi4, lpspi5

Also replace hardcoded numeric DMA direction flags with the proper
FSL_EDMA_RX and FSL_EDMA_MULTI_FIFO macros for SAI (sai4, sai5, sai6,
sai7) and SPDIF nodes.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 32 +++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index c6d1bb9edf388..1ab4ab270dc2d 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/imx8ulp-clock.h>
+#include <dt-bindings/dma/fsl-edma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/power/imx8ulp-power.h>
@@ -370,6 +371,8 @@ lpi2c4: i2c@29370000 {
 				assigned-clocks = <&pcc3 IMX8ULP_CLK_LPI2C4>;
 				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
 				assigned-clock-rates = <48000000>;
+				dmas = <&edma1 46 0 0>, <&edma1 45 0 FSL_EDMA_RX>;
+				dma-names = "tx", "rx";
 				status = "disabled";
 			};
 
@@ -383,6 +386,8 @@ lpi2c5: i2c@29380000 {
 				assigned-clocks = <&pcc3 IMX8ULP_CLK_LPI2C5>;
 				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
 				assigned-clock-rates = <48000000>;
+				dmas = <&edma1 48 0 0>, <&edma1 47 0 FSL_EDMA_RX>;
+				dma-names = "tx", "rx";
 				status = "disabled";
 			};
 
@@ -392,6 +397,8 @@ lpuart4: serial@29390000 {
 				interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc3 IMX8ULP_CLK_LPUART4>;
 				clock-names = "ipg";
+				dmas = <&edma1 55 0 FSL_EDMA_RX>, <&edma1 56 0 0>;
+				dma-names = "rx", "tx";
 				status = "disabled";
 			};
 
@@ -401,6 +408,8 @@ lpuart5: serial@293a0000 {
 				interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc3 IMX8ULP_CLK_LPUART5>;
 				clock-names = "ipg";
+				dmas = <&edma1 57 0 FSL_EDMA_RX>, <&edma1 58 0 0>;
+				dma-names = "rx", "tx";
 				status = "disabled";
 			};
 
@@ -416,6 +425,8 @@ lpspi4: spi@293b0000 {
 				assigned-clocks = <&pcc3 IMX8ULP_CLK_LPSPI4>;
 				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
 				assigned-clock-rates = <48000000>;
+				dmas = <&edma1 64 0 0>, <&edma1 63 0 FSL_EDMA_RX>;
+				dma-names = "tx", "rx";
 				status = "disabled";
 			};
 
@@ -431,6 +442,8 @@ lpspi5: spi@293c0000 {
 				assigned-clocks = <&pcc3 IMX8ULP_CLK_LPSPI5>;
 				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
 				assigned-clock-rates = <48000000>;
+				dmas = <&edma1 66 0 0>, <&edma1 65 0 FSL_EDMA_RX>;
+				dma-names = "tx", "rx";
 				status = "disabled";
 			};
 		};
@@ -474,6 +487,8 @@ lpi2c6: i2c@29840000 {
 				assigned-clocks = <&pcc4 IMX8ULP_CLK_LPI2C6>;
 				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
 				assigned-clock-rates = <48000000>;
+				dmas = <&edma1 50 0 0>, <&edma1 49 0 FSL_EDMA_RX>;
+				dma-names = "tx", "rx";
 				status = "disabled";
 			};
 
@@ -487,6 +502,8 @@ lpi2c7: i2c@29850000 {
 				assigned-clocks = <&pcc4 IMX8ULP_CLK_LPI2C7>;
 				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
 				assigned-clock-rates = <48000000>;
+				dmas = <&edma1 52 0 0>, <&edma1 51 0 FSL_EDMA_RX>;
+				dma-names = "tx", "rx";
 				status = "disabled";
 			};
 
@@ -496,6 +513,8 @@ lpuart6: serial@29860000 {
 				interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc4 IMX8ULP_CLK_LPUART6>;
 				clock-names = "ipg";
+				dmas = <&edma1 59 0 FSL_EDMA_RX>, <&edma1 60 0 0>;
+				dma-names = "rx", "tx";
 				status = "disabled";
 			};
 
@@ -505,6 +524,8 @@ lpuart7: serial@29870000 {
 				interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc4 IMX8ULP_CLK_LPUART7>;
 				clock-names = "ipg";
+				dmas = <&edma1 61 0 FSL_EDMA_RX>, <&edma1 62 0 0>;
+				dma-names = "rx", "tx";
 				status = "disabled";
 			};
 
@@ -516,7 +537,7 @@ sai4: sai@29880000 {
 					 <&cgc1 IMX8ULP_CLK_SAI4_SEL>, <&cgc1 IMX8ULP_CLK_DUMMY>,
 					 <&cgc1 IMX8ULP_CLK_DUMMY>;
 				clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
-				dmas = <&edma1 67 0 1>, <&edma1 68 0 0>;
+				dmas = <&edma1 67 0 FSL_EDMA_RX>, <&edma1 68 0 0>;
 				dma-names = "rx", "tx";
 				#sound-dai-cells = <0>;
 				fsl,dataline = <0 0x03 0x03>;
@@ -531,7 +552,7 @@ sai5: sai@29890000 {
 					 <&cgc1 IMX8ULP_CLK_SAI5_SEL>, <&cgc1 IMX8ULP_CLK_DUMMY>,
 					 <&cgc1 IMX8ULP_CLK_DUMMY>;
 				clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
-				dmas = <&edma1 69 0 1>, <&edma1 70 0 0>;
+				dmas = <&edma1 69 0 FSL_EDMA_RX>, <&edma1 70 0 0>;
 				dma-names = "rx", "tx";
 				#sound-dai-cells = <0>;
 				fsl,dataline = <0 0x0f 0x0f>;
@@ -814,7 +835,7 @@ sai6: sai@2da90000 {
 					 <&cgc2 IMX8ULP_CLK_SAI6_SEL>, <&cgc1 IMX8ULP_CLK_DUMMY>,
 					 <&cgc1 IMX8ULP_CLK_DUMMY>;
 				clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
-				dmas = <&edma2 71 0 1>, <&edma2 72 0 0>;
+				dmas = <&edma2 71 0 FSL_EDMA_RX>, <&edma2 72 0 0>;
 				dma-names = "rx", "tx";
 				#sound-dai-cells = <0>;
 				fsl,dataline = <0 0x0f 0x0f>;
@@ -829,7 +850,7 @@ sai7: sai@2daa0000 {
 					 <&cgc2 IMX8ULP_CLK_SAI7_SEL>, <&cgc1 IMX8ULP_CLK_DUMMY>,
 					 <&cgc1 IMX8ULP_CLK_DUMMY>;
 				clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
-				dmas = <&edma2 73 0 1>, <&edma2 74 0 0>;
+				dmas = <&edma2 73 0 FSL_EDMA_RX>, <&edma2 74 0 0>;
 				dma-names = "rx", "tx";
 				#sound-dai-cells = <0>;
 				fsl,dataline = <0 0x0f 0x0f>;
@@ -855,7 +876,8 @@ spdif: spdif@2dab0000 {
 					      "rxtx3", "rxtx4",
 					      "rxtx5", "rxtx6",
 					      "rxtx7", "spba";
-				dmas = <&edma2 75 0 5>, <&edma2 76 0 4>;
+				dmas = <&edma2 75 0 (FSL_EDMA_RX | FSL_EDMA_MULTI_FIFO)>,
+				       <&edma2 76 0 FSL_EDMA_MULTI_FIFO>;
 				dma-names = "rx", "tx";
 				status = "disabled";
 			};

-- 
2.34.1



^ permalink raw reply related

* [PATCH v2 2/9] arm64: dts: imx8ulp: Add I3C2 controller node
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

Add the I3C2 (i3c-master@29360000) node to the imx8ulp device tree using
the Silvaco I3C master IP. Configure PCC3-gated clock with SOSC DIV2 as
parent at 24 MHz for pclk and fast_clk. slow_clk uses a dummy clock.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index 1ab4ab270dc2d..cb0d73327d86c 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -361,6 +361,22 @@ tpm5: tpm@29340000 {
 				status = "disabled";
 			};
 
+			i3c2: i3c@29360000 {
+				compatible = "silvaco,i3c-master-v1";
+				reg = <0x29360000 0x10000>;
+				interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <3>;
+				#size-cells = <0>;
+				clocks = <&pcc3 IMX8ULP_CLK_I3C2>,
+					 <&pcc3 IMX8ULP_CLK_I3C2>,
+					 <&cgc1 IMX8ULP_CLK_DUMMY>;
+				clock-names = "pclk", "fast_clk", "slow_clk";
+				assigned-clocks = <&pcc3 IMX8ULP_CLK_I3C2>;
+				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_SOSC_DIV2>;
+				assigned-clock-rates = <24000000>;
+				status = "disabled";
+			};
+
 			lpi2c4: i2c@29370000 {
 				compatible = "fsl,imx8ulp-lpi2c", "fsl,imx7ulp-lpi2c";
 				reg = <0x29370000 0x10000>;

-- 
2.34.1



^ permalink raw reply related

* [PATCH v2 3/9] arm64: dts: imx8ulp: Correct SRAM node address and size to cover full SSRAM P2
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

The SSRAM P2 partition starts at 0x22010000 with a size of 64 KB.
The previous node only mapped the last 4 KB (0x2201f000, 0x1000) which
was used for the SCMI shared memory buffer. Update the base address and
size to cover the full P2 region so it can also serve as a general
purpose SRAM pool.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index cb0d73327d86c..7d00fe8360948 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -154,17 +154,17 @@ sosc: clock-sosc {
 		#clock-cells = <0>;
 	};
 
-	sram@2201f000 {
+	sram@22010000 {
 		compatible = "mmio-sram";
-		reg = <0x0 0x2201f000 0x0 0x1000>;
+		reg = <0x0 0x22010000 0x0 0x10000>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
-		ranges = <0 0x0 0x2201f000 0x1000>;
+		ranges = <0 0x0 0x22010000 0x10000>;
 
-		scmi_buf: scmi-sram-section@0 {
+		scmi_buf: scmi-sram-section@f000 {
 			compatible = "arm,scmi-shmem";
-			reg = <0x0 0x400>;
+			reg = <0xf000 0x400>;
 		};
 	};
 

-- 
2.34.1



^ permalink raw reply related

* [PATCH v2 4/9] arm64: dts: imx8ulp: Add assigned clock properties for LPUART nodes
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

Add assigned-clocks, assigned-clock-parents and assigned-clock-rates
properties to lpuart4 through lpuart7, so the LPUART input clock is
configured automatically by the clock framework during probe.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index 7d00fe8360948..777b89ed68490 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -413,6 +413,9 @@ lpuart4: serial@29390000 {
 				interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc3 IMX8ULP_CLK_LPUART4>;
 				clock-names = "ipg";
+				assigned-clocks = <&pcc3 IMX8ULP_CLK_LPUART4>;
+				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
+				assigned-clock-rates = <48000000>;
 				dmas = <&edma1 55 0 FSL_EDMA_RX>, <&edma1 56 0 0>;
 				dma-names = "rx", "tx";
 				status = "disabled";
@@ -424,6 +427,9 @@ lpuart5: serial@293a0000 {
 				interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc3 IMX8ULP_CLK_LPUART5>;
 				clock-names = "ipg";
+				assigned-clocks = <&pcc3 IMX8ULP_CLK_LPUART5>;
+				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_SOSC_DIV2>;
+				assigned-clock-rates = <24000000>;
 				dmas = <&edma1 57 0 FSL_EDMA_RX>, <&edma1 58 0 0>;
 				dma-names = "rx", "tx";
 				status = "disabled";
@@ -529,6 +535,9 @@ lpuart6: serial@29860000 {
 				interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc4 IMX8ULP_CLK_LPUART6>;
 				clock-names = "ipg";
+				assigned-clocks = <&pcc4 IMX8ULP_CLK_LPUART6>;
+				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
+				assigned-clock-rates = <48000000>;
 				dmas = <&edma1 59 0 FSL_EDMA_RX>, <&edma1 60 0 0>;
 				dma-names = "rx", "tx";
 				status = "disabled";
@@ -540,6 +549,9 @@ lpuart7: serial@29870000 {
 				interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc4 IMX8ULP_CLK_LPUART7>;
 				clock-names = "ipg";
+				assigned-clocks = <&pcc4 IMX8ULP_CLK_LPUART7>;
+				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
+				assigned-clock-rates = <48000000>;
 				dmas = <&edma1 61 0 FSL_EDMA_RX>, <&edma1 62 0 0>;
 				dma-names = "rx", "tx";
 				status = "disabled";

-- 
2.34.1



^ permalink raw reply related

* [PATCH v2 5/9] arm64: dts: imx8ulp-evk: Add gpio-keys node for power button
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

Add a gpio-keys node for the power-on button, report it as KEY_POWER to
user space.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts | 18 ++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8ulp-evk.dts     | 19 +++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts
index 5497e3d78136f..af8f0d6087f71 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts
@@ -10,6 +10,18 @@
 / {
 	model = "NXP i.MX8ULP EVK9";
 	compatible = "fsl,imx8ulp-9x9-evk", "fsl,imx8ulp";
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_keys>;
+
+		button-power-on {
+			label = "PowerOn";
+			gpios = <&gpiof 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+		};
+	};
 };
 
 &btcpu {
@@ -43,6 +55,12 @@ MX8ULP_PAD_PTF10__ENET0_1588_CLKIN      0x43
 	>;
 };
 
+&pinctrl_gpio_keys {
+	fsl,pins = <
+		MX8ULP_PAD_PTF11__PTF11		0x3
+	>;
+};
+
 &pinctrl_usb1 {
 	fsl,pins = <
 		MX8ULP_PAD_PTE16__USB0_ID		0x10003
diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
index 5dea66c1e7aa0..6a92c5ca9a412 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/input/input.h>
 #include "imx8ulp.dtsi"
 
 / {
@@ -20,6 +21,18 @@ chosen {
 		stdout-path = &lpuart5;
 	};
 
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_keys>;
+
+		button-power-on {
+			label = "PowerOn";
+			gpios = <&gpiof 31 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+		};
+	};
+
 	memory@80000000 {
 		device_type = "memory";
 		reg = <0x0 0x80000000 0 0x80000000>;
@@ -323,6 +336,12 @@ MX8ULP_PAD_PTD22__FLEXSPI2_A_DATA4	0x42
 		>;
 	};
 
+	pinctrl_gpio_keys: gpiokeysgrp {
+		fsl,pins = <
+			MX8ULP_PAD_PTF31__PTF31		0x3
+		>;
+	};
+
 	pinctrl_lpuart5: lpuart5grp {
 		fsl,pins = <
 			MX8ULP_PAD_PTF14__LPUART5_TX	0x3

-- 
2.34.1



^ permalink raw reply related

* [PATCH v2 6/9] arm64: dts: imx8ulp-evk: Enable LPUART6 for Bluetooth
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan,
	Sherry Sun
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Sherry Sun <sherry.sun@nxp.com>

Enable lpuart6 with RTS/CTS flow control on the i.MX 8ULP EVK board
and add an NXP 88W8987 Bluetooth companion node to pair the UART
transport with the wireless chip.

i.MX8ULP 9X9 EVK use different lpuart6 pins which used for M.2 bluetooth,
also use the sai6 instead of sai5 for PCM interface on M.2, so need to
update the pin setting in dts.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts | 17 +++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8ulp-evk.dts     | 20 ++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts
index af8f0d6087f71..71c66c58edc4d 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts
@@ -75,6 +75,23 @@ MX8ULP_PAD_PTE20__USB1_OC		0x10003
 	>;
 };
 
+&pinctrl_lpuart6 {
+	fsl,pins = <
+		MX8ULP_PAD_PTF18__LPUART6_TX    0x3
+		MX8ULP_PAD_PTF19__LPUART6_RX    0x3
+		MX8ULP_PAD_PTF16__LPUART6_CTS_B 0x3
+		MX8ULP_PAD_PTF17__LPUART6_RTS_B 0x3
+	>;
+};
+
+&lpspi5 { /* conflict with lpuart6 PAD_PTF16-19 */
+	status = "disabled";
+};
+
+&sai5 {
+	status = "disabled";
+};
+
 &sai6 {
 	pinctrl-names = "default", "sleep";
 	pinctrl-0 = <&pinctrl_sai6>;
diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
index 6a92c5ca9a412..84c61656f3f2b 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
@@ -167,6 +167,17 @@ &lpuart5 {
 	status = "okay";
 };
 
+&lpuart6 {
+	/* BT */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lpuart6>;
+	status = "okay";
+
+	bluetooth {
+		compatible = "nxp,88w8987-bt";
+	};
+};
+
 &lpi2c7 {
 	#address-cells = <1>;
 	#size-cells = <0>;
@@ -349,6 +360,15 @@ MX8ULP_PAD_PTF15__LPUART5_RX	0x3
 		>;
 	};
 
+	pinctrl_lpuart6: lpuart6grp {
+		fsl,pins = <
+			MX8ULP_PAD_PTE10__LPUART6_TX	0x3
+			MX8ULP_PAD_PTE11__LPUART6_RX	0x3
+			MX8ULP_PAD_PTE9__LPUART6_RTS_B	0x3
+			MX8ULP_PAD_PTE8__LPUART6_CTS_B	0x3
+		>;
+	};
+
 	pinctrl_lpi2c7: lpi2c7grp {
 		fsl,pins = <
 			MX8ULP_PAD_PTE12__LPI2C7_SCL	0x20

-- 
2.34.1



^ permalink raw reply related

* [PATCH] arm64: archrandom: avoid trapping ID register read in __cpu_has_rng()
From: Aman Priyadarshi @ 2026-07-20 14:06 UTC (permalink / raw)
  To: catalin.marinas, will
  Cc: Jason, linux-arm-kernel, linux-kernel, Aman Priyadarshi,
	Ard Biesheuvel

__cpu_has_rng() has an early-boot fallback, taken before the
ARM64_HAS_RNG alternative is patched, that calls
this_cpu_has_cap(ARM64_HAS_RNG). With SCOPE_LOCAL_CPU that resolves the
capability by reading ID_AA64ISAR0_EL1 directly from hardware via
__read_sysreg_by_encoding(), on every invocation.

Until the CRNG is seeded, crng_make_state() routes every get_random_*()
through extract_entropy(), which drains architectural entropy via
arch_get_random_seed_longs()/arch_get_random_longs() and so calls
__cpu_has_rng() several times per request. On a direct (non-EFI) boot
there is no bootloader seed, so the CRNG stays unseeded for much of
boot and essentially every early randomness consumer takes this path.

Under virtualization this is costly: the hypervisor traps guest
accesses to the ID registers (HCR_EL2.TID3), making each read a vmexit,
producing ~200k trapped ID_AA64ISAR0_EL1 reads during boot.

The register value is invariant, so read the sanitised feature register
instead. read_sanitised_ftr_reg() returns the cached value from
arm64_ftr_regs[] with no sysreg access, and hence no trap. That array
is populated by cpuinfo_store_boot_cpu() in smp_prepare_boot_cpu(),
before the first early RNG use in random_init_early(), so it is always
valid here.

With this change the trapped reads drop from ~200k to handful number of
times, and the boot time drops roughly by 6.3% in the test environment.

Fixes: 2c03e16f4499 ("random: remove early archrandom abstraction")
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Aman Priyadarshi <amanp@apple.com>
---
 arch/arm64/include/asm/archrandom.h | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
index 8babfbe31f95..8067e9a35641 100644
--- a/arch/arm64/include/asm/archrandom.h
+++ b/arch/arm64/include/asm/archrandom.h
@@ -61,8 +61,22 @@ static inline bool __arm64_rndrrs(unsigned long *v)
 
 static __always_inline bool __cpu_has_rng(void)
 {
-	if (unlikely(!system_capabilities_finalized() && !preemptible()))
-		return this_cpu_has_cap(ARM64_HAS_RNG);
+	if (unlikely(!system_capabilities_finalized() && !preemptible())) {
+		/*
+		 * Until the ARM64_HAS_RNG alternative is patched we can't use
+		 * the static-branch form, so consult the feature register
+		 * directly. Don't use this_cpu_has_cap() here: it reads
+		 * ID_AA64ISAR0_EL1 from hardware on every call, under
+		 * virtualization each ID register read traps to the hypervisor
+		 * (HCR_EL2.TID3) -- producing a storm of vmexits during boot.
+		 * The sanitised value is cached in memory.
+		 */
+		u64 isar0 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR0_EL1);
+
+		return cpuid_feature_extract_unsigned_field(isar0,
+				ID_AA64ISAR0_EL1_RNDR_SHIFT) >=
+			ID_AA64ISAR0_EL1_RNDR_IMP;
+	}
 	return alternative_has_cap_unlikely(ARM64_HAS_RNG);
 }
 
-- 
2.54.0 (Apple Git-156)



^ permalink raw reply related

* [PATCH v2 7/9] arm64: dts: imx8ulp-evk: Enable LPUART7
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan,
	Sherry Sun
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Sherry Sun <sherry.sun@nxp.com>

The i.MX 8ULP EVK proto1B revision routes LPUART7 TX/RX to the FT4232
PortD connector (J25/J26 pins 2-3). Enable the port by default so the
additional serial console is available out of the box.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp-evk.dts | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
index 84c61656f3f2b..9da54291c7534 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
@@ -178,6 +178,13 @@ bluetooth {
 	};
 };
 
+&lpuart7 {
+	/* FT4232 PortD: need to connect J25/J26 2-3 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lpuart7>;
+	status = "okay";
+};
+
 &lpi2c7 {
 	#address-cells = <1>;
 	#size-cells = <0>;
@@ -369,6 +376,13 @@ MX8ULP_PAD_PTE8__LPUART6_CTS_B	0x3
 		>;
 	};
 
+	pinctrl_lpuart7: lpuart7grp {
+		fsl,pins = <
+			MX8ULP_PAD_PTF22__LPUART7_TX	0x3
+			MX8ULP_PAD_PTF23__LPUART7_RX	0x3
+		>;
+	};
+
 	pinctrl_lpi2c7: lpi2c7grp {
 		fsl,pins = <
 			MX8ULP_PAD_PTE12__LPI2C7_SCL	0x20

-- 
2.34.1



^ permalink raw reply related

* [PATCH v2 8/9] arm64: dts: imx8ulp-evk: Change the values of some PCRs of ENET
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan,
	Wei Fang
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Wei Fang <wei.fang@nxp.com>

Change to use standard drive strength and slow slew rate on
PTE14-17, 22, 23, otherwise the overshoot of ENET is too high.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp-evk.dts | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
index 9da54291c7534..22c1d542798d5 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
@@ -323,15 +323,15 @@ &mu {
 &iomuxc1 {
 	pinctrl_enet: enetgrp {
 		fsl,pins = <
-			MX8ULP_PAD_PTE15__ENET0_MDC     0x43
-			MX8ULP_PAD_PTE14__ENET0_MDIO    0x43
-			MX8ULP_PAD_PTE17__ENET0_RXER    0x43
+			MX8ULP_PAD_PTE15__ENET0_MDC     0x7
+			MX8ULP_PAD_PTE14__ENET0_MDIO    0x7
+			MX8ULP_PAD_PTE17__ENET0_RXER    0x7
 			MX8ULP_PAD_PTE18__ENET0_CRS_DV  0x43
 			MX8ULP_PAD_PTF1__ENET0_RXD0     0x43
 			MX8ULP_PAD_PTE20__ENET0_RXD1    0x43
-			MX8ULP_PAD_PTE16__ENET0_TXEN    0x43
-			MX8ULP_PAD_PTE23__ENET0_TXD0    0x43
-			MX8ULP_PAD_PTE22__ENET0_TXD1    0x43
+			MX8ULP_PAD_PTE16__ENET0_TXEN    0x7
+			MX8ULP_PAD_PTE23__ENET0_TXD0    0x7
+			MX8ULP_PAD_PTE22__ENET0_TXD1    0x7
 			MX8ULP_PAD_PTE19__ENET0_REFCLK  0x43
 			MX8ULP_PAD_PTF10__ENET0_1588_CLKIN 0x43
 		>;

-- 
2.34.1



^ permalink raw reply related

* [PATCH v2 9/9] arm64: dts: imx8ulp-9x9-evk: Rename model string to reflect die size
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

Rename the board model from "NXP i.MX8ULP EVK9" to "NXP i.MX8ULP 9x9
EVK" to follow the i.MX naming convention where the die size (9x9 mm)
is used instead of an opaque board revision suffix.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts
index 71c66c58edc4d..e6bc6e6555f57 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts
@@ -8,7 +8,7 @@
 #include "imx8ulp-evk.dts"
 
 / {
-	model = "NXP i.MX8ULP EVK9";
+	model = "NXP i.MX8ULP 9x9 EVK";
 	compatible = "fsl,imx8ulp-9x9-evk", "fsl,imx8ulp";
 
 	gpio-keys {

-- 
2.34.1



^ permalink raw reply related

* Re: [PATCH v2 18/18] KVM: arm64: Alloc simple_buffer_page using pKVM hyp allocator
From: Vincent Donnefort @ 2026-07-20 14:10 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, will, linux-arm-kernel, kvmarm, kernel-team,
	qperret
In-Reply-To: <al4q05rBGvJzi3Vl@google.com>

On Mon, Jul 20, 2026 at 03:04:03PM +0100, Vincent Donnefort wrote:
> On Wed, Jul 15, 2026 at 04:07:05PM +0100, Fuad Tabba wrote:
> > On Mon, 6 Jul 2026 at 18:54, Vincent Donnefort <vdonnefort@google.com> wrote:
> > 
> > ...
> > 
> > > @@ -193,17 +211,8 @@ static bool hyp_trace_desc_is_valid(struct hyp_trace_desc *desc, size_t desc_siz
> > >                 if ((void *)rb_desc + struct_size(rb_desc, page_va, rb_desc->nr_page_va) > desc_end)
> > >                         return false;
> > >
> > > -               /* Overflow bpages backing memory? */
> > > -               if (nr_bpages < rb_desc->nr_page_va)
> > > -                       return false;
> > > -
> > > -               if (cpu >= hyp_nr_cpus)
> > > -                       return false;
> > > -
> > >                 if (cpu != rb_desc->cpu)
> > >                         return false;
> > 
> > Sashiko flagged this. Nothing here bounds nr_page_va from below, so
> > with nr_page_va == 0 on every CPU the bpage size sums to 0.
> > hyp_alloc() still hands back a chunk, but bpages_backing_size is
> > stored as 0, so when init_mm() fails on nr_page_va < 3 the free path
> > takes its if (!size) return and never frees it. The host can repeat
> > it. Would validating nr_page_va >= 3 here work?
> 
> simple_ring_buffer_init_mm() already validates nr_page_va. And on error, we do
> seem to rollback properly and hyp_free().
> 
> So I don't believe there's anything to do here.

Ahhh no my bad! Sashiko's right. Because the size is 0... this will appear as
"unloaded" ...

Indeed perhaps the best check here is to make sure we have the minium
nr_page_va...

> 
> > 
> > I don't think the rest of Sashiko's note holds: the zero-size path
> > succeeds rather than hitting -ENOMEM. And it's only reachable from the
> > host kernel, not userspace.
> > 
> > Cheers,
> > /fuad


^ permalink raw reply

* Re: [PATCH v3 1/6] dt-bindings: iommu: arm,smmu: Document interconnects property
From: Bibek Kumar Patro @ 2026-07-20 14:11 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Dmitry Baryshkov, Will Deacon, Robin Murphy, Joerg Roedel,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio,
	Rob Clark, linux-arm-kernel, iommu, devicetree, linux-kernel,
	linux-arm-msm, Krzysztof Kozlowski
In-Reply-To: <ak5pC_meP8KRc3wJ@baldur>



On 7/8/2026 8:48 PM, Bjorn Andersson wrote:
> On Wed, Jul 08, 2026 at 08:22:00PM +0530, Bibek Kumar Patro wrote:
>>
>>
>> On 7/7/2026 10:12 PM, Dmitry Baryshkov wrote:
>>> On Tue, Jul 07, 2026 at 06:06:59PM +0530, Bibek Kumar Patro wrote:
>>>>
>>>>
>>>> On 7/6/2026 11:09 PM, Dmitry Baryshkov wrote:
>>>>> On Mon, Jul 06, 2026 at 10:26:34PM +0530, Bibek Kumar Patro wrote:
>>>>>> Some SoC implementations require a bandwidth vote on an interconnect
>>>>>> path before the SMMU register space is accessible. Add the optional
>>>>>
>>>>> Why is it limited only to those SoCs? Is it also applicable to other
>>>>> Qualcomm SoCs?
>>>>>
>>>>
>>>> I was hoping to keep this series focused on the core infrastructure
>>>> changes: the bindings, base ICC bandwidth-voting support, and DT
>>>> interconnect properties for the platforms currently supported on
>>>> Qualcomm Linux and have been validated so far.
>>>>
>>>> The additional targets have not been tested yet, so I'd prefer
>>>> to add their support in a separate follow-up series once validation
>>>> is complete, rather than growing this series further. WDYT?
>>>
>>> Then it should be a part of the commit message. All SoCs since SDM12345
>>> need to vote on the interconnect (and then, in the cover letter mention
>>> that you convert only a few of the SoCs). We possibly can help with
>>> testing on other platforms.
>>>
>>
>> Ack, sounds reasonable.
>> I'll add the first platform onwards which interconnect voting is required in
>> commit description.
> 
> But to what degree is this related to a specific set of platforms? If we
> look ahead, aren't we expecting the list to grow to include all
> platforms in the end - resulting in a lot of noise and churn.
> 

We have seen this issue consistently on SM8750 and later platforms, 
along with at least one customer-reported instance on SM8550. As a 
result, downstream Android implementations already vote for the required 
interconnect bandwidth explicitly on these platforms.

On Qualcomm Linux targets, we have observed similar issues on Kodiak, 
with a few occurrences on Talos as well.

My understanding is that the interconnects property remains optional, 
but in practice it is needed for Adreno SMMU operation on these platforms.

> Can you give an example of a platform where there is no interconnect
> path to vote for here or where it would be harmful to do so?
> 

I do not anticipate any functional issues or side effects from
explicitly voting for the interconnect on Qualcomm platforms where the 
path exists.


>> And update the cover letter to clarify that this series adds
>> support for the Qualcomm Linux-supported targets available today, and
>> the list will be expanded in follow-up series as additional platforms
>> are enabled.
>>
> 
> The binding should not reflect what has been implemented and verified in
> Linux, it defines the contract between DeviceTree and the OS.
> 

Since the property is optional, would it be necessary to add in AllOf
the list of compatible for which the property hasn't been added yet, or 
for the compatibles where it is added?

Thanks & regards,
Bibek

> Regards,
> Bjorn
> 
>> Thanks & regards,
>> Bibek
>>
>>>>>> 'interconnects' property to the binding to allow platform DT nodes
>>>>>> to describe this path.
>>>>>>
>>>>>> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
>>>>>> Signed-off-by: Bibek Kumar Patro <bibek.patro@oss.qualcomm.com>
>>>>>> ---
>>>>>>     .../devicetree/bindings/iommu/arm,smmu.yaml        | 27 ++++++++++++++++++++++
>>>>>>     1 file changed, 27 insertions(+)
>>>>>>
>>>
>>



^ permalink raw reply

* Re: [PATCH v4 3/8] phy: rockchip: samsung-hdptx: Fix rate recalculation for 3.2GHz FRL
From: Dmitry Baryshkov @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Cristian Ciocaltea
  Cc: Vinod Koul, Neil Armstrong, Heiko Stuebner, Algea Cao,
	Dmitry Baryshkov, kernel, linux-phy, linux-arm-kernel,
	linux-rockchip, linux-kernel, Sashiko
In-Reply-To: <20260612-hdptx-clk-fixes-v4-3-ce5e1d456cda@collabora.com>

On Fri, Jun 12, 2026 at 02:45:22AM +0300, Cristian Ciocaltea wrote:
> rk_hdptx_phy_clk_calc_rate_from_pll_cfg() is currently unable to handle
> cascade mode for the 3.2GHz FRL operating mode, as it relies solely on
> LCPLL_LCVCO_MODE_EN_MASK to determinate the rate from the
> rk_hdptx_frl_lcpll_cfg array.  Since there is no entry for this
> particular rate, the function returns 0.
> 
> This is the only rate which requires LC_REF_CLK_SEL to be set in
> GRF_HDPTX_CON0, hence extend the FRL matching accordingly.
> 
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Closes: https://sashiko.dev/#/patchset/20260611-hdptx-clk-fixes-v3-0-67b1b0c00e16@collabora.com?part=1
> Fixes: de5dba833118 ("phy: rockchip: samsung-hdptx: Add HDMI 2.1 FRL support")
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> ---
>  drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 33 ++++++++++++++++-------
>  1 file changed, 24 insertions(+), 9 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>


-- 
With best wishes
Dmitry


^ permalink raw reply

* Re: [PATCH v4 4/8] phy: rockchip: samsung-hdptx: Handle uncommitted PHY config changes
From: Dmitry Baryshkov @ 2026-07-20 14:17 UTC (permalink / raw)
  To: Cristian Ciocaltea
  Cc: Vinod Koul, Neil Armstrong, Heiko Stuebner, Algea Cao,
	Dmitry Baryshkov, kernel, linux-phy, linux-arm-kernel,
	linux-rockchip, linux-kernel, Thomas Niederprüm,
	Simon Wright
In-Reply-To: <20260612-hdptx-clk-fixes-v4-4-ce5e1d456cda@collabora.com>

On Fri, Jun 12, 2026 at 02:45:23AM +0300, Cristian Ciocaltea wrote:
> Any changes to the PHY link rate and/or color depth done via the HDMI
> PHY configuration API are not immediately programmed into the hardware,
> but are delayed until the PHY usage count gets incremented from 0 to 1,
> that is when it is powered on or when the PLL clock exposed through
> the CCF API is prepared, whichever comes first.

Why do you need either-of here? Can it be just one path?

> 
> Since the clock might remain in prepared state after subsequent PHY
> config changes, the programming can also be triggered via
> clk_ops.set_rate().  However, from the clock consumer perspective (i.e.
> VOP2 display controller), the (pixel) clock rate doesn't vary with bpc,
> as that is handled internally by the PHY and reflected in the TDMS
> character rate only.
> 
> As a consequence, changing the bpc while preserving the modeline may
> lead to out-of-sync issues between CCF and HDMI PHY config state,
> because the .set_rate() callback is not invoked when clock rate remains
> constant.  This may also happen when the PHY PLL has been pre-programmed
> by an external entity, e.g. the bootloader, which is actually a
> regression introduced by the recent FRL patches.
> 
> Introduce a pll_config_dirty flag to keep track of uncommitted PHY
> config changes and use it in clk_ops.determine_rate() to invalidate the
> current clock rate (as known by CCF) and, consequently, ensure those
> changes are programmed into hardware via clk_ops.set_rate().
> 
> Moreover, proceed with a similar fix in phy_ops.power_on() callback, to
> handle the scenario where the CCF API is not used due to operating in
> FRL mode, while the clock is still in a prepared state and thus
> preventing rk_hdptx_phy_consumer_get() to apply the updated PHY
> configuration.
> 
> Fixes: de5dba833118 ("phy: rockchip: samsung-hdptx: Add HDMI 2.1 FRL support")
> Fixes: 9d0ec51d7c22 ("phy: rockchip: samsung-hdptx: Add high color depth management")
> Tested-by: Thomas Niederprüm <dubito@online.de>
> Tested-by: Simon Wright <simon@symple.nz>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> ---
>  drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 84 +++++++++++++----------
>  1 file changed, 48 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> index b210c1a88b25..25bd821cd039 100644
> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> @@ -413,6 +413,7 @@ struct rk_hdptx_phy {
>  
>  	/* clk provider */
>  	struct clk_hw hw;
> +	bool pll_config_dirty;

Which lock protects it?

>  	bool restrict_rate_change;
>  
>  	atomic_t usage_count;

-- 
With best wishes
Dmitry


^ permalink raw reply

* Re: [PATCH 6/7] soc: ti: wkup_m3_ipc: Remove redundant dev_err()
From: Hari Prasath G E @ 2026-07-20 14:17 UTC (permalink / raw)
  To: Pan Chuang, Nishanth Menon, Santosh Shilimkar,
	open list:TI KEYSTONE MULTICORE NAVIGATOR DRIVERS,
	moderated list:TI KEYSTONE MULTICORE NAVIGATOR DRIVERS
In-Reply-To: <20260720095920.542801-7-panchuang@vivo.com>

On 7/20/2026 3:29 PM, Pan Chuang wrote:
> Since commit 55b48e23f5c4 ("genirq/devres: Add error handling in
> devm_request_*_irq()"), devm_request_irq() automatically logs
> detailed error messages on failure. Remove the now-redundant
> driver-specific dev_err() calls.
> 

Thanks for the patch

Reviewed-by: Hari Prasath Gujulan Elango <gehariprasath@ti.com>

> Signed-off-by: Pan Chuang <panchuang@vivo.com>
> ---
>   drivers/soc/ti/wkup_m3_ipc.c | 4 +---
>   1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/soc/ti/wkup_m3_ipc.c b/drivers/soc/ti/wkup_m3_ipc.c
> index 5845fc652adc..f8640cdc2a21 100644
> --- a/drivers/soc/ti/wkup_m3_ipc.c
> +++ b/drivers/soc/ti/wkup_m3_ipc.c
> @@ -630,10 +630,8 @@ static int wkup_m3_ipc_probe(struct platform_device *pdev)
>   
>   	ret = devm_request_irq(dev, irq, wkup_m3_txev_handler,
>   			       0, "wkup_m3_txev", m3_ipc);
> -	if (ret) {
> -		dev_err(dev, "request_irq failed\n");
> +	if (ret)
>   		return ret;
> -	}
>   
>   	m3_ipc->mbox_client.dev = dev;
>   	m3_ipc->mbox_client.tx_done = NULL;



^ permalink raw reply

* Re: [PATCH v4 5/8] phy: rockchip: samsung-hdptx: Drop TMDS rate setup workaround
From: Dmitry Baryshkov @ 2026-07-20 14:19 UTC (permalink / raw)
  To: Cristian Ciocaltea
  Cc: Vinod Koul, Neil Armstrong, Heiko Stuebner, Algea Cao,
	Dmitry Baryshkov, kernel, linux-phy, linux-arm-kernel,
	linux-rockchip, linux-kernel, Thomas Niederprüm,
	Simon Wright
In-Reply-To: <20260612-hdptx-clk-fixes-v4-5-ce5e1d456cda@collabora.com>

On Fri, Jun 12, 2026 at 02:45:24AM +0300, Cristian Ciocaltea wrote:
> Since commit ba9c2fe18c17 ("drm/rockchip: dw_hdmi_qp: Switch to
> phy_configure()") the TMDS rate setup doesn't rely anymore on the
> unconventional usage of the bus width, instead it is managed exclusively
> through the HDMI PHY configuration API.
> 
> Drop the now obsolete workaround to retrieve the TMDS character rate via
> phy_get_bus_width() during power_on().
> 
> While at it, get rid of the extra call to rk_hdptx_phy_consumer_put() by
> moving the statement at the end of the function.
> 
> Tested-by: Thomas Niederprüm <dubito@online.de>
> Tested-by: Simon Wright <simon@symple.nz>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> ---
>  drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 27 +++++------------------
>  1 file changed, 6 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> index 25bd821cd039..35997087d61c 100644
> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> @@ -1660,22 +1660,6 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
>  	enum phy_mode mode = phy_get_mode(phy);
>  	int ret, lane;
>  
> -	if (mode != PHY_MODE_DP) {
> -		if (!hdptx->hdmi_cfg.rate && hdptx->hdmi_cfg.mode != PHY_HDMI_MODE_FRL) {
> -			/*
> -			 * FIXME: Temporary workaround to setup TMDS char rate
> -			 * from the RK DW HDMI QP bridge driver.
> -			 * Will be removed as soon the switch to the HDMI PHY
> -			 * configuration API has been completed on both ends.
> -			 */
> -			hdptx->hdmi_cfg.rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
> -			hdptx->hdmi_cfg.rate *= 100;
> -		}
> -
> -		dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__,
> -			hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc);
> -	}
> -
>  	ret = rk_hdptx_phy_consumer_get(hdptx);
>  	if (ret)
>  		return ret;
> @@ -1701,9 +1685,10 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
>  		rk_hdptx_dp_pll_init(hdptx);
>  
>  		ret = rk_hdptx_dp_aux_init(hdptx);
> -		if (ret)
> -			rk_hdptx_phy_consumer_put(hdptx, true);
>  	} else {
> +		dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__,
> +			hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc);
> +
>  		if (hdptx->pll_config_dirty)
>  			ret = rk_hdptx_pll_cmn_config(hdptx);
>  
> @@ -1716,11 +1701,11 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
>  			else
>  				ret = rk_hdptx_tmds_ropll_mode_config(hdptx);
>  		}
> -
> -		if (ret)
> -			rk_hdptx_phy_consumer_put(hdptx, true);
>  	}
>  
> +	if (ret)
> +		rk_hdptx_phy_consumer_put(hdptx, true);

This looks likes an unrelated change. Could you please split it to a
separate commit?

> +
>  	return ret;
>  }
>  
> 
> -- 
> 2.54.0
> 

-- 
With best wishes
Dmitry


^ permalink raw reply

* Re: [PATCH v4 6/8] phy: rockchip: samsung-hdptx: Drop restrict_rate_change handling
From: Dmitry Baryshkov @ 2026-07-20 14:26 UTC (permalink / raw)
  To: Cristian Ciocaltea
  Cc: Vinod Koul, Neil Armstrong, Heiko Stuebner, Algea Cao,
	Dmitry Baryshkov, kernel, linux-phy, linux-arm-kernel,
	linux-rockchip, linux-kernel, Thomas Niederprüm,
	Simon Wright
In-Reply-To: <20260612-hdptx-clk-fixes-v4-6-ce5e1d456cda@collabora.com>

On Fri, Jun 12, 2026 at 02:45:25AM +0300, Cristian Ciocaltea wrote:
> Since commit 6efbd0f46dd8 ("phy: rockchip: samsung-hdptx: Restrict
> altering TMDS char rate via CCF"), adjusting the rate via the Common
> Clock Framework API has been disallowed.
> 
> To avoid breaking existing users until switching to the PHY config API,
> it introduced a temporary exception to the rule, controlled via the
> 'restrict_rate_change' flag.
> 
> As the API transition completed, remove the now deprecated exception
> logic.
> 
> Tested-by: Thomas Niederprüm <dubito@online.de>
> Tested-by: Simon Wright <simon@symple.nz>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> ---
>  drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 42 +++++------------------
>  1 file changed, 8 insertions(+), 34 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>


-- 
With best wishes
Dmitry


^ permalink raw reply

* Re: [PATCH 1/4] dt-bindings: sound: fsl,imx-asrc: update port binding to support multiple pairs
From: Mark Brown @ 2026-07-20 14:28 UTC (permalink / raw)
  To: shengjiu.wang
  Cc: lgirdwood, robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel,
	festevam, shawnguo, linux-sound, devicetree, imx,
	linux-arm-kernel, linux-kernel, shengjiu.wang, Xiubo.Lee,
	nicoleotsuka, perex, tiwai, linuxppc-dev, Shengjiu Wang
In-Reply-To: <20260720095450.1618747-2-shengjiu.wang@oss.nxp.com>

[-- Attachment #1: Type: text/plain, Size: 668 bytes --]

On Mon, Jul 20, 2026 at 05:54:47PM +0800, shengjiu.wang@oss.nxp.com wrote:
> From: Shengjiu Wang <shengjiu.wang@nxp.com>
> 
> The i.MX ASRC hardware supports up to three conversion pairs (A, B, C).
> The existing binding exposed only a single generic audio-graph port,
> which cannot represent the individual pair endpoints.

Please submit patches using subject lines reflecting the style for the
subsystem, this makes it easier for people to identify relevant patches.
Look at what existing commits in the area you're changing are doing and
make sure your subject lines visually resemble what they're doing.
There's no need to resubmit to fix this alone.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH 05/37] drm/display: bridge-connector: split code creating the connector to a subfunction
From: Maxime Ripard @ 2026-07-20 14:28 UTC (permalink / raw)
  To: Luca Ceresoli
  Cc: Laurent Pinchart, Maarten Lankhorst, Thomas Zimmermann,
	David Airlie, Simona Vetter, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Jonas Karlman, Jernej Skrabec, Inki Dae, Jagan Teki,
	Marek Szyprowski, Marek Vasut, Stefan Agner, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Hui Pu,
	Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel, imx,
	linux-arm-kernel
In-Reply-To: <DK0QXI6KF7PC.3DJW38KB8MJED@bootlin.com>

[-- Attachment #1: Type: text/plain, Size: 5552 bytes --]

On Fri, Jul 17, 2026 at 11:41:33AM +0200, Luca Ceresoli wrote:
> Hi Maxime,
> 
> On Thu Jul 16, 2026 at 3:22 PM CEST, Maxime Ripard wrote:
> > On Thu, Jul 16, 2026 at 10:37:24AM +0200, Luca Ceresoli wrote:
> >> >> > Now if the bridges start doing it themselves we should go back to
> >> >> > those encoder drivers and ditch all the drm_bridge_connector from
> >> >> > there?
> >> >> >
> >> >> > I must be missing something. Can you elaborate on this?
> >> >>
> >> >> drm_bridge_connectors bring together a (complete) bridge chain and a
> >> >> connector. If you don't have either anymore, then we shouldn't keep it
> >> >> around.
> >> >>
> >> >> What I was suggesting before was only a suggestion. I guess we could
> >> >> also make the encoder own the hotplug handling code and create the
> >> >> drm_bridge_connector when the chain is complete, and remove it when it's
> >> >> no longer the case.
> >> >
> >> > That's an interesting option. We don't have to keep drm_bridge_connector
> >> > in its current form, but I don't think we should go back to individual
> >> > bridge driver creating connectors, especially now that we have bridge
> >> > chains where the connector ops are implemented collectively by multiple
> >> > bridges.
> >>
> >> I definitely agree we don't want to add burden back on the encoder.
> >
> > I don't think Laurent mentioned the encoder anywhere.
> 
> Ah, indeed, sorry! However, I think both the bridges and the encoder
> drivers should equally have the minimum burden on them.
> 
> Right now the recommended practice is:
> 
>  - bridges do not create connectors (thanks to DRM_BRIDGE_ATTACH_NO_CONNECTOR)
>  - encoders just call drm_bridge_connector_init(), which does all the
>    common operations to populate a suitable drm_connector
> 
> So all common operations involved in connector creation and bridge chain
> analysis are implemented in common code, not per-bridge or
> per-encoder. That's good.

I agree, but another way to phrase it is: bridges aren't aware of how
the chain is setup, the encoder ties it all together.

> >> >> We can discuss alternatives too. But either way, we shouldn't have it
> >> >> stick around.
> >>
> >> Bottom line, I roughly see three ideas mentioned:
> >>
> >>  1. (this series) extend the drm_bridge_connector to create the
> >>     drm_connector based on bridge hotplug events [+rename it]
> >>  2. - keep the drm_bridge_connector (mostly) as is
> >>     - let each encoder driver add/remove it based on bridge hotplug events
> >>     => more burden on encoder drivers -> no
> >
> > Can you motivate that with *any* reason? Because I really feel like it's
> > the best solution going forward.
> 
> My understanding of your idea (maybe a bit overstressed just to ensure it's
> clear) is that:
> 
>  - the drm_bridge_connector should stay (almost) unmodified

Yes, and bridges should ideally remain as lightly affected as possible.
We have probably around 100 bridge drivers at the moment, having some
kind of opt-in to enable hotplug would mean that we can't expect hotplug
to work on a new platform, which should be a last resort.

>  - there should be no new "manager" component (not sure this is actually
>    your opinion, can you comment on this specifically?)
>  - every encoder driver would have to:
>    - register to receive hotplug events
>    - when receiving one such event, find out whether the hardware is
>      complete or not (by calling drm_bridge_connector_pipeline_is_complete()
>      or so)
>    - create/destroy a drm_bridge_connector based on hotplug events
> 
> Is this somewhat close to what you have in mind?

Yes. To make things a bit more precise, we need two things: the encoder
to put the chain together, and "something" (that you used to call
manager) to react to hotplug events and handle the bridge
detach/destruction, connector creation/destruction, etc and should stick
around when we enable hotplug.

What I'm suggesting is that, since the encoder already owns and creates
the chain in the first place, and is there forever, it's only natural
for the encoder to be that "something", and we don't necessarily mean
creating a new entity or piece of code. A bunch of helpers and hooks a
probably going to be enough.

This is where the opt-in part should be, and I'd like, if possible, for
hotplug-enabled encoders to work with any bridge.

> To me the best solution to add hotplug support is that encoder drivers
> replace the single drm_bridge_connector_init() call with a single call to
> something new (let's call it a hotplug manager), which takes care of all
> the common aspects: registering to receive bridge hotplug events, finding
> out whether the hardware pipeline is complete or not, and add/remove the
> drm_connector based on that.
> 
> In other words, the changes on encoder drivers would be similar to patch
> 37. In a nutshell:
> 
>   -	connector = drm_bridge_connector_init(lcdif->drm, encoder);
>   +	drm_hotplug_manager = drm_hotplug_manager_init(lcdif->drm, encoder);
> 
> All the hotplug logic would be in common code, and any maintenance and
> future improvements to it would stay in a single place, benefitting all
> encoders at once.
> 
> What do you think about this?

From a high level point-of-view, I think we mostly agree. We can argue
on the name, and if we should merge it with something else
(drm_encoder_init, drm_bridge_attach, something else?) but that's the
path forward I think.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox