qualcommbe: syncing with upstream

This commit is contained in:
coolsnowwolf 2025-10-06 18:08:36 +08:00
parent 3b83d61ddb
commit 389a26dc6a
9 changed files with 131 additions and 284 deletions

View File

@ -65,7 +65,6 @@ CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_MQ_VIRTIO=y
CONFIG_BLK_PM=y
CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
CONFIG_CAVIUM_TX2_ERRATUM_219=y
CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
# CONFIG_CLK_QCM2290_GPUCC is not set
@ -79,7 +78,6 @@ CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_QCOM=y
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
# CONFIG_COMPAT_32BIT_TIME is not set
# CONFIG_COMPRESSED_INSTALL is not set
CONFIG_CONTEXT_TRACKING=y
CONFIG_CONTEXT_TRACKING_IDLE=y
CONFIG_COREDUMP=y
@ -155,7 +153,6 @@ CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FRAME_POINTER=y
CONFIG_FS_IOMAP=y
CONFIG_FUJITSU_ERRATUM_010001=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
@ -199,6 +196,7 @@ CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HWMON=y
CONFIG_HWSPINLOCK=y
CONFIG_HWSPINLOCK_QCOM=y
CONFIG_HW_RANDOM=y
@ -296,7 +294,6 @@ CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=4
# CONFIG_NSM is not set
CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y
CONFIG_NVMEM=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_NVMEM_LAYOUT_U_BOOT_ENV=y
@ -590,6 +587,7 @@ CONFIG_THERMAL=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_HWMON=y
CONFIG_THERMAL_OF=y
CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y

View File

@ -3,6 +3,10 @@ PART_NAME=firmware
RAMFS_COPY_BIN='fw_printenv fw_setenv head'
RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
platform_check_image() {
return 0;
}
platform_do_upgrade() {
case "$(board_name)" in
*)

View File

@ -1,6 +1,7 @@
CONFIG_AQUANTIA_PHY=y
CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y
CONFIG_DT_IDLE_GENPD=y
CONFIG_F2FS_FS=y
CONFIG_GRO_CELLS=y
CONFIG_INTERCONNECT_QCOM=y
# CONFIG_INTERCONNECT_QCOM_MSM8909 is not set

View File

@ -1,118 +0,0 @@
From 7b0f0f00a301906cc78d3c8974ea14ad8db29f0c Mon Sep 17 00:00:00 2001
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
Date: Tue, 3 Dec 2024 15:31:02 +0000
Subject: [PATCH 10/22] v6.14: net: phy: add phy_inband_caps()
Add a method to query the PHY's in-band capabilities for a PHY
interface mode.
Where the interface mode does not have in-band capability, or the PHY
driver has not been updated to return this information, then
phy_inband_caps() should return zero. Otherwise, PHY drivers will
return a value consisting of the following flags:
LINK_INBAND_DISABLE indicates that the hardware does not support
in-band signalling, or can have in-band signalling configured via
software to be disabled.
LINK_INBAND_ENABLE indicates that the hardware will use in-band
signalling, or can have in-band signalling configured via software
to be enabled.
LINK_INBAND_BYPASS indicates that the hardware has the ability to
bypass in-band signalling when enabled after a timeout if the link
partner does not respond to its in-band signalling.
This reports the PHY capabilities for the particular interface mode,
not the current configuration.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Link: https://patch.msgid.link/E1tIUre-006ITz-KF@rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/phy/phy.c | 21 +++++++++++++++++++++
include/linux/phy.h | 28 ++++++++++++++++++++++++++++
2 files changed, 49 insertions(+)
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1049,6 +1049,27 @@ static int phy_check_link_status(struct
}
/**
+ * phy_inband_caps - query which in-band signalling modes are supported
+ * @phydev: a pointer to a &struct phy_device
+ * @interface: the interface mode for the PHY
+ *
+ * Returns zero if it is unknown what in-band signalling is supported by the
+ * PHY (e.g. because the PHY driver doesn't implement the method.) Otherwise,
+ * returns a bit mask of the LINK_INBAND_* values from
+ * &enum link_inband_signalling to describe which inband modes are supported
+ * by the PHY for this interface mode.
+ */
+unsigned int phy_inband_caps(struct phy_device *phydev,
+ phy_interface_t interface)
+{
+ if (phydev->drv && phydev->drv->inband_caps)
+ return phydev->drv->inband_caps(phydev, interface);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(phy_inband_caps);
+
+/**
* _phy_start_aneg - start auto-negotiation for this PHY device
* @phydev: the phy_device struct
*
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -816,6 +816,24 @@ struct phy_tdr_config {
#define PHY_PAIR_ALL -1
/**
+ * enum link_inband_signalling - in-band signalling modes that are supported
+ *
+ * @LINK_INBAND_DISABLE: in-band signalling can be disabled
+ * @LINK_INBAND_ENABLE: in-band signalling can be enabled without bypass
+ * @LINK_INBAND_BYPASS: in-band signalling can be enabled with bypass
+ *
+ * The possible and required bits can only be used if the valid bit is set.
+ * If possible is clear, that means inband signalling can not be used.
+ * Required is only valid when possible is set, and means that inband
+ * signalling must be used.
+ */
+enum link_inband_signalling {
+ LINK_INBAND_DISABLE = BIT(0),
+ LINK_INBAND_ENABLE = BIT(1),
+ LINK_INBAND_BYPASS = BIT(2),
+};
+
+/**
* struct phy_plca_cfg - Configuration of the PLCA (Physical Layer Collision
* Avoidance) Reconciliation Sublayer.
*
@@ -955,6 +973,14 @@ struct phy_driver {
int (*get_features)(struct phy_device *phydev);
/**
+ * @inband_caps: query whether in-band is supported for the given PHY
+ * interface mode. Returns a bitmask of bits defined by enum
+ * link_inband_signalling.
+ */
+ unsigned int (*inband_caps)(struct phy_device *phydev,
+ phy_interface_t interface);
+
+ /**
* @get_rate_matching: Get the supported type of rate matching for a
* particular phy interface. This is used by phy consumers to determine
* whether to advertise lower-speed modes for that interface. It is
@@ -1840,6 +1866,8 @@ int phy_config_aneg(struct phy_device *p
int _phy_start_aneg(struct phy_device *phydev);
int phy_start_aneg(struct phy_device *phydev);
int phy_aneg_done(struct phy_device *phydev);
+unsigned int phy_inband_caps(struct phy_device *phydev,
+ phy_interface_t interface);
int phy_speed_down(struct phy_device *phydev, bool sync);
int phy_speed_up(struct phy_device *phydev);
bool phy_check_valid(int speed, int duplex, unsigned long *features);

View File

@ -1,159 +0,0 @@
From 2d530b1085104f6aa0dfa35c908ac7c531941bf6 Mon Sep 17 00:00:00 2001
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
Date: Tue, 3 Dec 2024 15:31:28 +0000
Subject: [PATCH 11/22] v6.14: net: phylink: add pcs_inband_caps() method
Add a pcs_inband_caps() method to query the PCS for its inband link
capabilities, and use this to determine whether link modes used with
optical SFPs can be supported.
When a PCS does not provide a method, we allow inband negotiation to
be either on or off, making this a no-op until the pcs_inband_caps()
method is implemented by a PCS driver.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Link: https://patch.msgid.link/E1tIUs4-006IUU-7K@rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/phy/phylink.c | 60 +++++++++++++++++++++++++++++++++++++++
include/linux/phylink.h | 17 +++++++++++
2 files changed, 77 insertions(+)
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -988,6 +988,15 @@ static void phylink_resolve_an_pause(str
}
}
+static unsigned int phylink_pcs_inband_caps(struct phylink_pcs *pcs,
+ phy_interface_t interface)
+{
+ if (pcs && pcs->ops->pcs_inband_caps)
+ return pcs->ops->pcs_inband_caps(pcs, interface);
+
+ return 0;
+}
+
static void phylink_pcs_pre_config(struct phylink_pcs *pcs,
phy_interface_t interface)
{
@@ -1041,6 +1050,24 @@ static void phylink_pcs_link_up(struct p
pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex);
}
+/* Query inband for a specific interface mode, asking the MAC for the
+ * PCS which will be used to handle the interface mode.
+ */
+static unsigned int phylink_inband_caps(struct phylink *pl,
+ phy_interface_t interface)
+{
+ struct phylink_pcs *pcs;
+
+ if (!pl->mac_ops->mac_select_pcs)
+ return 0;
+
+ pcs = pl->mac_ops->mac_select_pcs(pl->config, interface);
+ if (!pcs)
+ return 0;
+
+ return phylink_pcs_inband_caps(pcs, interface);
+}
+
static void phylink_pcs_poll_stop(struct phylink *pl)
{
if (pl->cfg_link_an_mode == MLO_AN_INBAND)
@@ -2532,6 +2559,26 @@ int phylink_ethtool_ksettings_get(struct
}
EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_get);
+static bool phylink_validate_pcs_inband_autoneg(struct phylink *pl,
+ phy_interface_t interface,
+ unsigned long *adv)
+{
+ unsigned int inband = phylink_inband_caps(pl, interface);
+ unsigned int mask;
+
+ /* If the PCS doesn't implement inband support, be permissive. */
+ if (!inband)
+ return true;
+
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, adv))
+ mask = LINK_INBAND_ENABLE;
+ else
+ mask = LINK_INBAND_DISABLE;
+
+ /* Check whether the PCS implements the required mode */
+ return !!(inband & mask);
+}
+
/**
* phylink_ethtool_ksettings_set() - set the link settings
* @pl: a pointer to a &struct phylink returned from phylink_create()
@@ -2667,6 +2714,13 @@ int phylink_ethtool_ksettings_set(struct
phylink_is_empty_linkmode(config.advertising))
return -EINVAL;
+ /* Validate the autonegotiation state. We don't have a PHY in this
+ * situation, so the PCS is the media-facing entity.
+ */
+ if (!phylink_validate_pcs_inband_autoneg(pl, config.interface,
+ config.advertising))
+ return -EINVAL;
+
mutex_lock(&pl->state_mutex);
pl->link_config.speed = config.speed;
pl->link_config.duplex = config.duplex;
@@ -3351,6 +3405,12 @@ static int phylink_sfp_config_optical(st
phylink_dbg(pl, "optical SFP: chosen %s interface\n",
phy_modes(interface));
+ if (!phylink_validate_pcs_inband_autoneg(pl, interface,
+ config.advertising)) {
+ phylink_err(pl, "autoneg setting not compatible with PCS");
+ return -EINVAL;
+ }
+
config.interface = interface;
/* Ignore errors if we're expecting a PHY to attach later */
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -419,6 +419,7 @@ struct phylink_pcs {
/**
* struct phylink_pcs_ops - MAC PCS operations structure.
* @pcs_validate: validate the link configuration.
+ * @pcs_inband_caps: query inband support for interface mode.
* @pcs_enable: enable the PCS.
* @pcs_disable: disable the PCS.
* @pcs_pre_config: pre-mac_config method (for errata)
@@ -434,6 +435,8 @@ struct phylink_pcs {
struct phylink_pcs_ops {
int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
const struct phylink_link_state *state);
+ unsigned int (*pcs_inband_caps)(struct phylink_pcs *pcs,
+ phy_interface_t interface);
int (*pcs_enable)(struct phylink_pcs *pcs);
void (*pcs_disable)(struct phylink_pcs *pcs);
void (*pcs_pre_config)(struct phylink_pcs *pcs,
@@ -471,6 +474,20 @@ int pcs_validate(struct phylink_pcs *pcs
const struct phylink_link_state *state);
/**
+ * pcs_inband_caps - query PCS in-band capabilities for interface mode.
+ * @pcs: a pointer to a &struct phylink_pcs.
+ * @interface: interface mode to be queried
+ *
+ * Returns zero if it is unknown what in-band signalling is supported by the
+ * PHY (e.g. because the PHY driver doesn't implement the method.) Otherwise,
+ * returns a bit mask of the LINK_INBAND_* values from
+ * &enum link_inband_signalling to describe which inband modes are supported
+ * for this interface mode.
+ */
+unsigned int pcs_inband_caps(struct phylink_pcs *pcs,
+ phy_interface_t interface);
+
+/**
* pcs_enable() - enable the PCS.
* @pcs: a pointer to a &struct phylink_pcs.
*/

View File

@ -99,10 +99,10 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
+ };
+ };
+
+ pcs_uniphy1: ethernet-uniphy@7a10000 {
+ pcs_uniphy1: ethernet-pcs@7a10000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "qcom,ipq9574-uniphy";
+ compatible = "qcom,ipq9574-pcs";
+ reg = <0x7a10000 0x10000>;
+ clocks = <&gcc GCC_UNIPHY1_SYS_CLK>,
+ <&gcc GCC_UNIPHY1_AHB_CLK>;
@ -116,7 +116,7 @@ Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
+ "xpcs";
+ #clock-cells = <1>;
+
+ pcsuniphy1_ch0: uniphy-ch@0 {
+ pcsuniphy1_ch0: pcs-mii@0 {
+ reg = <0>;
+ clocks = <&nsscc NSS_CC_UNIPHY_PORT5_RX_CLK>,
+ <&nsscc NSS_CC_UNIPHY_PORT5_TX_CLK>;

View File

@ -0,0 +1,72 @@
From 930203b9bb94dc4ea9342f1ce176851918758ed7 Mon Sep 17 00:00:00 2001
From: Mantas Pucka <mantas@8devices.com>
Date: Mon, 2 Jun 2025 17:18:13 +0300
Subject: [PATCH] net: pcs: ipq-uniphy: control MISC2 register for 2.5G
support
When 2500base-x mode is enabled MISC2 regsister needs to have different
value than for other 1G modes.
Signed-off-by: Mantas Pucka <mantas@8devices.com>
---
drivers/net/pcs/pcs-qcom-ipq9574.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
--- a/drivers/net/pcs/pcs-qcom-ipq9574.c
+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
@@ -24,6 +24,11 @@
#define PCS_CALIBRATION 0x1e0
#define PCS_CALIBRATION_DONE BIT(7)
+#define PCS_MISC2 0x218
+#define PCS_MISC2_MODE_MASK GENMASK(6, 5)
+#define PCS_MISC2_MODE_SGMII FIELD_PREP(PCS_MISC2_MODE_MASK, 0x1)
+#define PCS_MISC2_MODE_SGMII_PLUS FIELD_PREP(PCS_MISC2_MODE_MASK, 0x2)
+
#define PCS_MODE_CTRL 0x46c
#define PCS_MODE_SEL_MASK GENMASK(12, 8)
#define PCS_MODE_SGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
@@ -311,7 +316,7 @@ static int ipq_pcs_config_mode(struct ip
phy_interface_t interface)
{
unsigned long rate = 125000000;
- unsigned int val, mask = PCS_MODE_SEL_MASK;
+ unsigned int val, misc2 = 0, mask = PCS_MODE_SEL_MASK;
int ret;
/* Assert XPCS reset */
@@ -321,6 +326,7 @@ static int ipq_pcs_config_mode(struct ip
switch (interface) {
case PHY_INTERFACE_MODE_SGMII:
val = PCS_MODE_SGMII;
+ misc2 = PCS_MISC2_MODE_SGMII;
break;
case PHY_INTERFACE_MODE_QSGMII:
val = PCS_MODE_QSGMII;
@@ -328,10 +334,12 @@ static int ipq_pcs_config_mode(struct ip
case PHY_INTERFACE_MODE_1000BASEX:
mask |= PCS_MODE_SGMII_CTRL_MASK;
val = PCS_MODE_SGMII | PCS_MODE_SGMII_CTRL_1000BASEX;
+ misc2 = PCS_MISC2_MODE_SGMII;
break;
case PHY_INTERFACE_MODE_2500BASEX:
val = PCS_MODE_SGMII_PLUS;
rate = 312500000;
+ misc2 = PCS_MISC2_MODE_SGMII_PLUS;
break;
case PHY_INTERFACE_MODE_PSGMII:
val = PCS_MODE_PSGMII;
@@ -360,6 +368,13 @@ static int ipq_pcs_config_mode(struct ip
if (ret)
return ret;
+ if (misc2) {
+ ret = regmap_update_bits(qpcs->regmap, PCS_MISC2,
+ PCS_MISC2_MODE_MASK, misc2);
+ if (ret)
+ return ret;
+ }
+
/* PCS PLL reset */
ret = regmap_clear_bits(qpcs->regmap, PCS_PLL_RESET, PCS_ANA_SW_RESET);
if (ret)

View File

@ -0,0 +1,25 @@
From ccdfd293f9e948f0f62ac4e9924d72539a4e81ee Mon Sep 17 00:00:00 2001
From: Mantas Pucka <mantas@8devices.com>
Date: Mon, 2 Jun 2025 17:19:45 +0300
Subject: [PATCH] net: pcs: ipq-uniphy: keep autoneg enabled in SGMII mode
For PHYs that don't use in-band-status (e.g. 2.5G PHY swiching between
SGMII and 2500base-x), SGMII autoneg still must be enabled. Only mode
that should use forced speed is 1000base-x
Signed-off-by: Mantas Pucka <mantas@8devices.com>
---
drivers/net/pcs/pcs-qcom-ipq9574.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/pcs/pcs-qcom-ipq9574.c
+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
@@ -431,7 +431,7 @@ static int ipq_pcs_config_sgmii(struct i
/* Nothing to do here as in-band autoneg mode is enabled
* by default for each PCS MII port.
*/
- if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
+ if (interface != PHY_INTERFACE_MODE_1000BASEX)
return 0;
/* Set force speed mode */

View File

@ -0,0 +1,24 @@
From 0cff1d9bb695bdc0ad7bad234b92eddf849ce88f Mon Sep 17 00:00:00 2001
From: Mantas Pucka <mantas@8devices.com>
Date: Mon, 2 Jun 2025 17:20:58 +0300
Subject: [PATCH] net: pcs: ipq-uniphy: fix USXGMII link-up failure
USXGMII link-up may fail due to too short delay after PLL reset.
Increase the delay to fix this.
Signed-off-by: Mantas Pucka <mantas@8devices.com>
---
drivers/net/pcs/pcs-qcom-ipq9574.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/pcs/pcs-qcom-ipq9574.c
+++ b/drivers/net/pcs/pcs-qcom-ipq9574.c
@@ -380,7 +380,7 @@ static int ipq_pcs_config_mode(struct ip
if (ret)
return ret;
- fsleep(1000);
+ fsleep(20000);
ret = regmap_set_bits(qpcs->regmap, PCS_PLL_RESET, PCS_ANA_SW_RESET);
if (ret)
return ret;