From nobody Sat Jul 25 00:44:13 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2542364EB7 for ; Tue, 21 Jul 2026 14:28:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784644092; cv=none; b=Xf+Cmk8jJBTNRq5nkchnymzygQg+TQ6Bpbx/g2PA4c1TEVH6IByyP6aBwCgO2LzzxTuQSQ3f2Pmug6M3TVIyBz+F0dHw4wFDHOFCLzqEWds8yzo1NBfVOIDao+2PQ5kAM8uNHDrnii3OiLJH+KtvGtqeY7hajt6Nk+T1Jgf3U4g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784644092; c=relaxed/simple; bh=kbwyU9cBNmm9WhMYvQnmwfdACGEnIi/6+1yBtoNp+P0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=uu9lYe4wI6SYERNlUz8f8EKlOaXX8Vx4KaLiNFbDiCSLo2VopRIHJo/fClt2AzTRWrjMVyZ9CsfwQkyehNDNizgIgHZj/HQ2so1JpFOMFwpuJTIUYLtDyejvuqgBHNfHZKiS8uKAds1+8MH/sa2yzf7fxFC7WwN6QZJuR8Ejr0Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=mk0E+OyE; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=YDS9zkcx; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="mk0E+OyE"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="YDS9zkcx" Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66LDfqjp1687322 for ; Tue, 21 Jul 2026 14:28:10 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:message-id :mime-version:subject:to; s=qcppdkim1; bh=VfRHGzv5LZrjsMqHcjUMBQ TNxpKbC+Fo/KrOiwV/OcQ=; b=mk0E+OyE0bGCNHGUqqPOdSsBdIjafgpy25wVzV nWrD2fF7m6lhYBQCtbR3GOByizoHS1Vyo2+svtP2oBAnZ5qt77uSw+NbWoptn7Mr UjAyvlvV8guHyuNoucwCTxTnmCx7+0mB2FDsc686elH7izsogS6qrIiRti0JmJ1A T1BSp5ggVOddXpojSFxxnxs5FPMpYB6kqJGVtP43ryZ78M2M3LBtbdh/lEGC13GG Kn20L2OfJbpTerKZV3K+7ML5rQ/Xhnr9qvp+SUrCSzTo3IFij1VmTOthxQ3Fha8Q SLXGYYFxl0MCggBv8cSwRQXoxLU0ex62Mg0f9KniQRoPmshQ== Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fj9c40bvw-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Tue, 21 Jul 2026 14:28:09 +0000 (GMT) Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-2cc7e86e7c5so203079645ad.3 for ; Tue, 21 Jul 2026 07:28:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1784644089; x=1785248889; darn=vger.kernel.org; h=cc:to:message-id:content-transfer-encoding:content-type :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=VfRHGzv5LZrjsMqHcjUMBQTNxpKbC+Fo/KrOiwV/OcQ=; b=YDS9zkcxBO6C4pA8KIDNVzoUofwU/h751/Iz6Py8tcceeG2rWJnjm2ojCXoXZqRKAD OkFCfc5zZ4yeOUD9osnD9ZkI+paVGL3pfYgfAicDpnE9rluEWw5pwoRlGzK3ABV0PXlv hjc0/ei8CONAUHDsyUa59q6j1HFzIjzPVyAZNvpWkhmxHoKgYEg+8Oz0UgZ92janSzOd ujvoUu+Gss0/qYe0kLlgqmMrRMhPZeJ4QghtaJHfXrbKlL4tASWGQbdOKlyPYb4mFdKA 7QM4HSVpZxR8++e8M8wGwGQVy6FX45+rYG8PDGfU9vVI5waU8sopjJuxpgD4EtDqUJoG E7Og== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784644089; x=1785248889; h=cc:to:message-id:content-transfer-encoding:content-type :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=VfRHGzv5LZrjsMqHcjUMBQTNxpKbC+Fo/KrOiwV/OcQ=; b=SWFPGepz7CHqW0QjlkzGgg7W/otue1Sz0lP1PKqUmSZJEqBrpO7Egot4NYhVdeI61s MCyyB8Tdi5fUyRoCUf2PpYCRatWBT4YRzafdaYBTNC0fGdBJkgp49nsPaydJQ0KjIa9E jeL55AbsDqKMuAP6Y7rKOjVs8bUNat6H9V/Hfk5l2KJL9mVbgG7eITRc/XvkQMKp2K2Q j77OxRa6ouVYI2nPr90cS3k0ItnUeqPTXihYm+8XI83SnbHeG43fMYJo75UFgITWVkdi hWqmnXXhkhBv/z818yhbAxIE0Ak2JSIPXMJKwOhP08JZm7cYYc3gRq7MA/TSsb7aqUSW lhFg== X-Forwarded-Encrypted: i=1; AHgh+RojQA2+MeGHBhJnrAzzk/9cJY/3E9rnnpDwbs4QIczBbSS26NqPgy0JAnh9j9mAYe47POj+xEzpOId6lJ0=@vger.kernel.org X-Gm-Message-State: AOJu0Yy86unA+78z8/bi/CC+BkeX/M8Iu0Vg+cH3BMn6QyRYSyOZ4fHs j1Gx33R/XWnGL1Dwq7fUm2uWCHIQ89ZUC7vV7+W6kTG4HsOjgmK1NTQHHsXipuRHgmJ/qTVzjns CUVF0z90jqdTTE/LPei3raCCaKhvj/n4k89RT9PV4Tq/+75fA86ego06qLxfuE/+XRaw= X-Gm-Gg: AR+sD10d2kSfuCQ/Bf4yxcHAv2j3fwQnfMJxXLi/1t0ndAXh9i6Xn8L1Wl0CS4MFR4F 9scHxgg4NNyYmyh0t4YOdQqoAaL6VP5n0rJXJcL2vyRBVFpQOqPzaaBgD/EKw74EgRl/Whp2tpl UVb3cT7DGU4q88ceEG4kmyWhj9VHSsTl2ksoTN+eCzCFtFsbjoHulGlRsLMNx3xxvi2WOYiTZQa 7wWqoOdAJehNGvALZ7MNmNtvp2/DbgjSxFLGQ1oKV9LZ1MulKqVEn6JPuCgEYu8b36YP4IXpJAP mwWC1DFMYlqQiCmJDSPL3w1fw36675YF0XShnEocyOs/hSDHMq5jIDedex1o0bXCy2sza7ml27M /knf41697+yAFeqzfQ9eTCwehmj/JQ/y3rQ4= X-Received: by 2002:a17:902:d987:b0:2cc:a977:4260 with SMTP id d9443c01a7336-2cf3489c64amr214777545ad.21.1784644087888; Tue, 21 Jul 2026 07:28:07 -0700 (PDT) X-Received: by 2002:a17:902:d987:b0:2cc:a977:4260 with SMTP id d9443c01a7336-2cf3489c64amr214777025ad.21.1784644087344; Tue, 21 Jul 2026 07:28:07 -0700 (PDT) Received: from hu-krichai-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3142a1bbaf6sm43581095eec.17.2026.07.21.07.28.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Jul 2026 07:28:06 -0700 (PDT) From: Krishna Chaitanya Chundru Date: Tue, 21 Jul 2026 19:58:01 +0530 Subject: [PATCH v5] PCI/ASPM: Mask ASPM states based on Devicetree properties Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-aspm-v5-1-58860c48d0c7@oss.qualcomm.com> X-B4-Tracking: v=1; b=H4sIAPCBX2oC/3XNQW7CMBAF0Ksgr2vkmXjsmFXvUXUxTuxi1BAaQ 9QK5e44BEQXsBnpS//9OYschhSy2KzOYghjyqnfl0BvK9Fsef8VZGpLFqjQKI1Ocj50smUiJo3 WBS1K9TCEmH6vMx+fS84nvwvNcbZzY5vysR/+rn9GmHvLJAEskyNIkF6zi8ERNdG99zmvf0783 fRdty5HzMsjPqxBfbNYbK0UayDwXPELWz2sVXdbFQtkESzHaE18YfV/a29WF9saE2vyFmuvnth pmi6DKJcVZQEAAA== X-Change-ID: 20260429-aspm-da55a54279e4 To: Bjorn Helgaas Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, mani@kernel.org, Krishna Chaitanya Chundru X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784644084; l=11532; i=krishna.chundru@oss.qualcomm.com; s=20230907; h=from:subject:message-id; bh=kbwyU9cBNmm9WhMYvQnmwfdACGEnIi/6+1yBtoNp+P0=; b=DiHRySyAXQ7wo13X+hhU8D2sVkvZ+N5uXcTuCHOKbfvLy86M4vU7WoiozogH4uqasn17X5v7O abUMTOuajtzB/eiVDPvbhr1UvGDWXbhG62AvR8q/QZSAqU0FREFlyEv X-Developer-Key: i=krishna.chundru@oss.qualcomm.com; a=ed25519; pk=10CL2pdAKFyzyOHbfSWHCD0X0my7CXxj8gJScmn1FAg= X-Authority-Analysis: v=2.4 cv=I4JVgtgg c=1 sm=1 tr=0 ts=6a5f81f9 cx=c_pps a=cmESyDAEBpBGqyK7t0alAg==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_K5XuSEh1TEqbUxoQ0s3:22 a=NEAV23lmAAAA:8 a=bC-a23v3AAAA:8 a=EUspDBNiAAAA:8 a=3BgslpDsQ43E56dAdxgA:9 a=QEXdDO2ut3YA:10 a=1OuFwYUASf3TG4hYMiVC:22 a=FO4_E8m0qiDe52t0p3_H:22 X-Proofpoint-ORIG-GUID: nrpJ6R37jMNlpledQqoxfD9lB8C3n-dQ X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzIxMDE1MyBTYWx0ZWRfX+4kuLuSIGRHs 80WThbyCjW5wBx4MOWNTztKBDCWHFF3XxM7aaHmtzXzR/DnZxM40EeWnjFOmEA5kKJG4TVhu3uh 2e+XFQw0IKUn6Y5qapdc/xAGC5us8HbB4NjlguEX94OXjnTZWIy2eu2ABN3unuHa+hUQgY6dKal VM+Hbk0T8msjAq6/wRj5cPimJpg/pYGwJwHOiip8ULL3azOWIC/198OJNZEDZ6mLLpWNM1YWOUP 2qYiEE2eq+rL8zD99LUEzlDLOo6oPWBKXwgCUkGMeNO/7+/5xi1qgUyLr8i4zImnFY/biTcWcFi R5GcL3M6oT7l4o3tINzeElgjwy7qA+rrXCk9yAbWYFANFLlcw4v4hc4/R+rQbVx0oNyQ6H4BsU3 doS7J8WR8/XxyixBD1PpLrH9t6++rkd7REjl4VWoIF2R3EjsuxDQRfLeNS7Hkam2k6iSOmmAlvo 0NW4j3VV67Lp0zveTZQ== X-Proofpoint-Spam-Info: AW1haW4tMjYwNzIxMDE1MyBTYWx0ZWRfX+dUU7xqrqNW7 GYXZsacQ8Lh2qJ5Hi9P/tj0T5tt59VYDzVpzOyD4BXCVzzvT7JJ2UphU+b9dSfcdMN+xR3IBJPF nHdye4l93+0caJD11Mh3SliHexpYRKo= X-Proofpoint-GUID: nrpJ6R37jMNlpledQqoxfD9lB8C3n-dQ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-21_03,2026-07-20_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 spamscore=0 lowpriorityscore=0 malwarescore=0 adultscore=0 priorityscore=1501 phishscore=0 bulkscore=0 suspectscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607210153 Some platforms require selectively disabling specific ASPM states on a given PCIe link to avoid link instability or functional failures caused by board-level connectivity constraints such as PCB routing, connectors, slots, or external cabling. Devicetree supports disabling ASPM L0s, L1, and L1 PM Substates via the 'aspm-no-l0s', 'aspm-no-l1' [1], and 'aspm-no-l1ss' [2] properties. However, the ASPM driver does not currently honor these properties when initializing the default link state. When firmware enables L1 PM Substates before the kernel takes over, masking aspm_support alone is insufficient to disable them in hardware. pcie_config_aspm_link() guards L1SS configuration behind a check on aspm_capable, which is derived from aspm_support. Once aspm_support is masked, pcie_config_aspm_l1ss() is never called, leaving firmware-enabled L1SS substates active in hardware. Fix this by introducing pcie_link_has_aspm_override() to check for DT override properties on either endpoint of the link. In pcie_aspm_override_default_link_state(), use it to: - Mask aspm_support, aspm_default, and aspm_enabled for any disabled state, so software's view of the link stays in sync with what is actually programmed in hardware. Leaving aspm_enabled stale would make pcie_aspm_enabled() and the aspm sysfs attributes report a state as active even after it has been masked, and could cause pcie_config_aspm_link()'s "already in requested state" check to skip reprogramming hardware to match. - Explicitly call pcie_config_aspm_l1ss(link, 0) before masking aspm_support when firmware has L1SS active and DT requests disabling L1 or L1SS, since pcie_config_aspm_link() will no longer do so once aspm_capable is derived from the masked aspm_support. Move the aspm_default initialization and pcie_aspm_override_default_link_state() call in pcie_aspm_cap_init() to before the "Restore L0s/L1" block. pcie_aspm_cap_init() disables L1 in hardware prior to aspm_l1ss_init() and re-enables it only in the restore block. Calling pcie_config_aspm_l1ss() while L1 is already disabled satisfies its precondition ("Caller must disable L1 first"), whereas the previous placement after the restore violated it. Since the restore block writes back the parent_lnkctl/child_lnkctl snapshot taken from hardware before the DT override ran, mask the L0s and L1 enable bits out of that snapshot for any state the override has just disabled in aspm_support. Otherwise the restore step would unconditionally reprogram the link back to firmware's original L0s/L1 configuration, defeating the Devicetree override it is meant to enforce. Move pcie_config_aspm_l1ss() earlier in the file so it can be called from pcie_aspm_override_default_link_state(). Link [1]: https://github.com/devicetree-org/dt-schema/pull/188 Link [2]: https://github.com/devicetree-org/dt-schema/pull/190 Signed-off-by: Krishna Chaitanya Chundru --- Changes in v5: - update all the child devices when enabling the ASPM back (sashiko). - Link to v4: https://patch.msgid.link/20260707-aspm-v4-1-d66f85b728b0@oss.= qualcomm.com Changes in v4: - Clear link->aspm_enabled alongside aspm_support/aspm_default when an ASPM state is masked, so it no longer goes stale relative to hardware (sa= shiko). - Mask the LNKCTL restore snapshot against the post-override=20 aspm_support so the restore step can no longer re-enable a state the Devicetree override just disabled. (sashiko) - Link to v3: https://patch.msgid.link/20260704-aspm-v3-1-157217aff76f@oss.= qualcomm.com Changes in v3: - Move pcie_aspm_override_default_link_state() call in pcie_aspm_cap_init()= to before the "Restore L0s/L1" block. pcie_aspm_cap_init() disables L1 in hardware prior to aspm_l1ss_init() and re-enables it only in the restore block. Calling pcie_config_aspm_l1ss() while L1 is already disabled satisfies its precondition ("Caller must disable L1 first"), whereas the previous placement after the restore violated it (sashiko). - Link to v2: https://patch.msgid.link/20260624-aspm-v2-1-800a4151ba3a@oss.= qualcomm.com Changes in v2: - Disable L1ss when L1 is disabled as pointed by sashiko. - Disable L1ss if bootloader enables them but we are disabling via devicetree pointed by sashiko. - Link to v1: https://patch.msgid.link/20260511-aspm-v1-1-b4a9fe955cf9@oss.= qualcomm.com --- drivers/pci/pcie/aspm.c | 135 +++++++++++++++++++++++++++++++++-----------= ---- 1 file changed, 92 insertions(+), 43 deletions(-) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 172783e7f519..82041052747f 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -839,6 +839,49 @@ static void aspm_l1ss_init(struct pcie_link_state *lin= k) =20 #define FLAG(x, y, d) (((x) & (PCIE_LINK_STATE_##y)) ? d : "") =20 +/* Configure the ASPM L1 substates. Caller must disable L1 first. */ +static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state) +{ + u32 val =3D 0; + struct pci_dev *child =3D link->downstream, *parent =3D link->pdev; + + if (state & PCIE_LINK_STATE_L1_1) + val |=3D PCI_L1SS_CTL1_ASPM_L1_1; + if (state & PCIE_LINK_STATE_L1_2) + val |=3D PCI_L1SS_CTL1_ASPM_L1_2; + if (state & PCIE_LINK_STATE_L1_1_PCIPM) + val |=3D PCI_L1SS_CTL1_PCIPM_L1_1; + if (state & PCIE_LINK_STATE_L1_2_PCIPM) + val |=3D PCI_L1SS_CTL1_PCIPM_L1_2; + + /* + * PCIe r6.2, sec 5.5.4, rules for enabling L1 PM Substates: + * - Clear L1.x enable bits at child first, then at parent + * - Set L1.x enable bits at parent first, then at child + * - ASPM/PCIPM L1.2 must be disabled while programming timing + * parameters + */ + + /* Disable all L1 substates */ + pci_clear_and_set_config_dword(child, child->l1ss + PCI_L1SS_CTL1, + PCI_L1SS_CTL1_L1SS_MASK, 0); + pci_clear_and_set_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1, + PCI_L1SS_CTL1_L1SS_MASK, 0); + + /* Enable what we need to enable */ + pci_clear_and_set_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1, + PCI_L1SS_CTL1_L1SS_MASK, val); + pci_clear_and_set_config_dword(child, child->l1ss + PCI_L1SS_CTL1, + PCI_L1SS_CTL1_L1SS_MASK, val); +} + +static bool pcie_link_has_aspm_override(const struct pcie_link_state *link, + const char *aspm) +{ + return (device_property_present(&link->pdev->dev, aspm) || + device_property_present(&link->downstream->dev, aspm)); +} + static void pcie_aspm_override_default_link_state(struct pcie_link_state *= link) { struct pci_dev *pdev =3D link->downstream; @@ -846,6 +889,36 @@ static void pcie_aspm_override_default_link_state(stru= ct pcie_link_state *link) =20 /* For devicetree platforms, enable L0s and L1 by default */ if (of_have_populated_dt()) { + bool no_l0s =3D pcie_link_has_aspm_override(link, "aspm-no-l0s"); + bool no_l1 =3D pcie_link_has_aspm_override(link, "aspm-no-l1"); + bool no_l1ss =3D pcie_link_has_aspm_override(link, "aspm-no-l1ss"); + + if (no_l0s) { + link->aspm_support &=3D ~PCIE_LINK_STATE_L0S; + link->aspm_default &=3D ~PCIE_LINK_STATE_L0S; + link->aspm_enabled &=3D ~PCIE_LINK_STATE_L0S; + } + + /* + * Clear L1SS in hardware before updating aspm_support. Once + * aspm_capable is derived from aspm_support, pcie_config_aspm_link() + * skips pcie_config_aspm_l1ss() entirely via the aspm_capable guard, + * leaving firmware-enabled L1SS substates active in hardware. + * This applies equally when disabling L1 (which implies L1SS). + */ + if ((no_l1 || no_l1ss) && (link->aspm_enabled & PCIE_LINK_STATE_L1SS)) + pcie_config_aspm_l1ss(link, 0); + + if (no_l1) { + link->aspm_support &=3D ~(PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_L1SS); + link->aspm_default &=3D ~(PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_L1SS); + link->aspm_enabled &=3D ~(PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_L1SS); + } else if (no_l1ss) { + link->aspm_support &=3D ~PCIE_LINK_STATE_L1SS; + link->aspm_default &=3D ~PCIE_LINK_STATE_L1SS; + link->aspm_enabled &=3D ~PCIE_LINK_STATE_L1SS; + } + if (link->aspm_support & PCIE_LINK_STATE_L0S) link->aspm_default |=3D PCIE_LINK_STATE_L0S; if (link->aspm_support & PCIE_LINK_STATE_L1) @@ -924,18 +997,30 @@ static void pcie_aspm_cap_init(struct pcie_link_state= *link, int blacklist) =20 aspm_l1ss_init(link); =20 - /* Restore L0s/L1 if they were enabled */ - if (FIELD_GET(PCI_EXP_LNKCTL_ASPMC, child_lnkctl) || - FIELD_GET(PCI_EXP_LNKCTL_ASPMC, parent_lnkctl)) { - pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_lnkctl); - pcie_capability_write_word(child, PCI_EXP_LNKCTL, child_lnkctl); - } - /* Save default state */ link->aspm_default =3D link->aspm_enabled; =20 pcie_aspm_override_default_link_state(link); =20 + /* + * Restore L0s/L1 if they were enabled, but don't restore any + * state a Devicetree override just disabled in aspm_support above. + */ + if (FIELD_GET(PCI_EXP_LNKCTL_ASPMC, child_lnkctl) || + FIELD_GET(PCI_EXP_LNKCTL_ASPMC, parent_lnkctl)) { + if (!(link->aspm_support & PCIE_LINK_STATE_L0S)) { + child_lnkctl &=3D ~PCI_EXP_LNKCTL_ASPM_L0S; + parent_lnkctl &=3D ~PCI_EXP_LNKCTL_ASPM_L0S; + } + if (!(link->aspm_support & PCIE_LINK_STATE_L1)) { + child_lnkctl &=3D ~PCI_EXP_LNKCTL_ASPM_L1; + parent_lnkctl &=3D ~PCI_EXP_LNKCTL_ASPM_L1; + } + pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_lnkctl); + list_for_each_entry(child, &linkbus->devices, bus_list) + pcie_capability_write_word(child, PCI_EXP_LNKCTL, child_lnkctl); + } + /* Setup initial capable state. Will be updated later */ link->aspm_capable =3D link->aspm_support; =20 @@ -949,42 +1034,6 @@ static void pcie_aspm_cap_init(struct pcie_link_state= *link, int blacklist) } } =20 -/* Configure the ASPM L1 substates. Caller must disable L1 first. */ -static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state) -{ - u32 val =3D 0; - struct pci_dev *child =3D link->downstream, *parent =3D link->pdev; - - if (state & PCIE_LINK_STATE_L1_1) - val |=3D PCI_L1SS_CTL1_ASPM_L1_1; - if (state & PCIE_LINK_STATE_L1_2) - val |=3D PCI_L1SS_CTL1_ASPM_L1_2; - if (state & PCIE_LINK_STATE_L1_1_PCIPM) - val |=3D PCI_L1SS_CTL1_PCIPM_L1_1; - if (state & PCIE_LINK_STATE_L1_2_PCIPM) - val |=3D PCI_L1SS_CTL1_PCIPM_L1_2; - - /* - * PCIe r6.2, sec 5.5.4, rules for enabling L1 PM Substates: - * - Clear L1.x enable bits at child first, then at parent - * - Set L1.x enable bits at parent first, then at child - * - ASPM/PCIPM L1.2 must be disabled while programming timing - * parameters - */ - - /* Disable all L1 substates */ - pci_clear_and_set_config_dword(child, child->l1ss + PCI_L1SS_CTL1, - PCI_L1SS_CTL1_L1SS_MASK, 0); - pci_clear_and_set_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1, - PCI_L1SS_CTL1_L1SS_MASK, 0); - - /* Enable what we need to enable */ - pci_clear_and_set_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1, - PCI_L1SS_CTL1_L1SS_MASK, val); - pci_clear_and_set_config_dword(child, child->l1ss + PCI_L1SS_CTL1, - PCI_L1SS_CTL1_L1SS_MASK, val); -} - static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val) { pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL, --- base-commit: b95f03f04d475aa6719d15a636ddf32222d55657 change-id: 20260429-aspm-da55a54279e4 Best regards, -- =20 Krishna Chaitanya Chundru