summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>2026-04-28 14:07:17 +0530
committerManivannan Sadhasivam <mani@kernel.org>2026-05-26 16:44:47 +0200
commite9769bb172696b7e924eb30fc94909e0c30786cf (patch)
tree0917430c1731071a390702e910cb374a53ce296c
parentd697e90672484186e2676426bf810ad6fe269579 (diff)
PCI: qcom: Program T_POWER_ON
Some platforms have incorrect T_POWER_ON value programmed in hardware. Generally these will be corrected by bootloaders, but not all targets support bootloaders to program correct values. That means the LTR_L1.2_THRESHOLD value calculated by aspm.c can be wrong, which can result in improper L1.2 exit behavior. If AER happens to be supported and enabled, the error may be *reported* via AER. Parse the 't-power-on-us' property from each Root Port node and program it as part of host initialization using dw_pcie_program_t_power_on() before link training. This property in added to the dtschema here [1]. Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com> [mani: reworded comment] Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Link[1]: https://lore.kernel.org/all/20260205093346.667898-1-krishna.chundru@oss.qualcomm.com/ Link: https://patch.msgid.link/20260428-t_power_on_fux-v5-3-f1ef926a91ff@oss.qualcomm.com
-rw-r--r--drivers/pci/controller/dwc/pcie-qcom.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 9173369cca87..65688e28f10d 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -276,6 +276,7 @@ struct qcom_pcie_perst {
struct qcom_pcie_port {
struct list_head list;
struct phy *phy;
+ u32 l1ss_t_power_on;
struct list_head perst;
};
@@ -1349,6 +1350,14 @@ static int qcom_pcie_phy_power_on(struct qcom_pcie *pcie)
return 0;
}
+static void qcom_pcie_configure_ports(struct qcom_pcie *pcie)
+{
+ struct qcom_pcie_port *port;
+
+ list_for_each_entry(port, &pcie->ports, list)
+ dw_pcie_program_t_power_on(pcie->pci, port->l1ss_t_power_on);
+}
+
static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -1387,6 +1396,8 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
dw_pcie_remove_capability(pcie->pci, PCI_CAP_ID_MSIX);
dw_pcie_remove_ext_capability(pcie->pci, PCI_EXT_CAP_ID_DPC);
+ qcom_pcie_configure_ports(pcie);
+
qcom_pcie_perst_deassert(pcie);
if (pcie->cfg->ops->config_sid) {
@@ -1868,6 +1879,9 @@ static int qcom_pcie_parse_port(struct qcom_pcie *pcie, struct device_node *node
if (ret)
return ret;
+ /* TODO: Move to DWC core after multi Root Port support is added */
+ of_property_read_u32(node, "t-power-on-us", &port->l1ss_t_power_on);
+
port->phy = phy;
INIT_LIST_HEAD(&port->list);
list_add_tail(&port->list, &pcie->ports);