PCI: tegra264: Add interconnect support

Add interconnect support to set PCIe bandwidth.

Bug 4775460
Bug 5407169

Change-Id: I7e0cbe6a391eb1d25795e39d9711f12ab1d8535e
Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3420338
(cherry picked from commit 5b004c01f21a7f16613a29ee977471f970265577)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3444597
Reviewed-by: svcacv <svcacv@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
This commit is contained in:
Manikanta Maddireddy
2025-07-30 14:05:35 +00:00
committed by mobile promotions
parent c6da597514
commit 8e2a32d25d

View File

@@ -10,6 +10,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/interconnect.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/iopoll.h> #include <linux/iopoll.h>
#include <linux/of_address.h> #include <linux/of_address.h>
@@ -37,6 +38,8 @@ extern int of_get_pci_domain_nr(struct device_node *node);
#define XTL_RC_PCIE_CFG_LINK_CONTROL_STATUS 0x58 #define XTL_RC_PCIE_CFG_LINK_CONTROL_STATUS 0x58
#define XTL_RC_PCIE_CFG_LINK_CONTROL_STATUS_DLL_ACTIVE BIT(29) #define XTL_RC_PCIE_CFG_LINK_CONTROL_STATUS_DLL_ACTIVE BIT(29)
#define XTL_RC_PCIE_CFG_LINK_STATUS 0x5a
#define XTL_RC_MGMT_PERST_CONTROL 0x218 #define XTL_RC_MGMT_PERST_CONTROL 0x218
#define XTL_RC_MGMT_PERST_CONTROL_PERST_O_N BIT(0) #define XTL_RC_MGMT_PERST_CONTROL_PERST_O_N BIT(0)
@@ -48,6 +51,7 @@ struct tegra264_pcie {
struct pci_config_window *cfg; struct pci_config_window *cfg;
struct pci_host_bridge *bridge; struct pci_host_bridge *bridge;
struct gpio_desc *pex_wake_gpiod; struct gpio_desc *pex_wake_gpiod;
struct icc_path *icc_path;
unsigned int pex_wake_irq; unsigned int pex_wake_irq;
void __iomem *xtl_pri_base; void __iomem *xtl_pri_base;
void __iomem *ecam_base; void __iomem *ecam_base;
@@ -123,6 +127,28 @@ static void tegra264_pcie_bpmp_set_rp_state(struct tegra264_pcie *pcie)
#endif #endif
} }
#define PCIE_SPEED2MBS(speed) \
((speed) == 5 ? 32000*128/130 : \
(speed) == 4 ? 16000*128/130 : \
(speed) == 3 ? 8000*128/130 : \
(speed) == 2 ? 5000*8/10 : \
(speed) == 1 ? 2500*8/10 : \
0)
static void tegra264_pcie_icc_set(struct tegra264_pcie *pcie)
{
u32 val, speed, width;
val = readw(pcie->ecam_base + XTL_RC_PCIE_CFG_LINK_STATUS);
speed = FIELD_GET(PCI_EXP_LNKSTA_CLS, val);
width = FIELD_GET(PCI_EXP_LNKSTA_NLW, val);
val = width * (PCIE_SPEED2MBS(speed) / BITS_PER_BYTE);
if (icc_set_bw(pcie->icc_path, MBps_to_icc(val), MBps_to_icc(val)))
dev_err(pcie->dev, "can't set bw[%u]\n", val);
}
static void tegra264_pcie_init(struct tegra264_pcie *pcie) static void tegra264_pcie_init(struct tegra264_pcie *pcie)
{ {
u32 val; u32 val;
@@ -161,6 +187,7 @@ static void tegra264_pcie_init(struct tegra264_pcie *pcie)
dev_info(pcie->dev, "PCIe Controller-%d Link is UP (Speed: %d)\n", dev_info(pcie->dev, "PCIe Controller-%d Link is UP (Speed: %d)\n",
pcie->ctl_id, (val & 0xf0000) >> 16); pcie->ctl_id, (val & 0xf0000) >> 16);
pcie->link_state = true; pcie->link_state = true;
tegra264_pcie_icc_set(pcie);
} else { } else {
dev_info(pcie->dev, "PCIe Controller-%d Link is DOWN\r\n", pcie->ctl_id); dev_info(pcie->dev, "PCIe Controller-%d Link is DOWN\r\n", pcie->ctl_id);
val = readl(pcie->xtl_pri_base + XTL_RC_MGMT_CLOCK_CONTROL); val = readl(pcie->xtl_pri_base + XTL_RC_MGMT_CLOCK_CONTROL);
@@ -255,6 +282,13 @@ static int tegra264_pcie_probe(struct platform_device *pdev)
return -ENXIO; return -ENXIO;
} }
pcie->icc_path = devm_of_icc_get(&pdev->dev, "write");
ret = PTR_ERR_OR_ZERO(pcie->icc_path);
if (ret) {
dev_err_probe(&pdev->dev, ret, "failed to get write interconnect\n");
return ret;
}
/* Parse BPMP property only for non VDK, as interaction with BPMP not needed for VDK */ /* Parse BPMP property only for non VDK, as interaction with BPMP not needed for VDK */
if (tegra_sku_info.platform != TEGRA_PLATFORM_VDK) { if (tegra_sku_info.platform != TEGRA_PLATFORM_VDK) {
ret = of_property_read_u32_index(dev->of_node, "nvidia,bpmp", 1, &pcie->ctl_id); ret = of_property_read_u32_index(dev->of_node, "nvidia,bpmp", 1, &pcie->ctl_id);