msm: pcie: provide client the ability to control PCIe target_link_speed

There are usecases where clients want to change the maximum GEN
speed that PCIe can link up with. Provide clients the ability to
control the maximum PCIe GEN speed to for such usecases.

Change-Id: I834bee2063133546c9b0ebac2d5328ffbc5ceac6
Signed-off-by: Tony Truong <truong@codeaurora.org>
This commit is contained in:
Tony Truong 2020-09-03 14:34:56 -07:00 committed by Hemant Kumar
parent 7141e265d8
commit d0cb56ec45
2 changed files with 79 additions and 3 deletions

View File

@ -700,6 +700,7 @@ struct msm_pcie_dev_t {
uint32_t smmu_sid_base; uint32_t smmu_sid_base;
uint32_t link_check_max_count; uint32_t link_check_max_count;
uint32_t target_link_speed; uint32_t target_link_speed;
uint32_t dt_target_link_speed;
uint32_t current_link_speed; uint32_t current_link_speed;
uint32_t n_fts; uint32_t n_fts;
uint32_t ep_latency; uint32_t ep_latency;
@ -5740,9 +5741,11 @@ static int msm_pcie_probe(struct platform_device *pdev)
pcie_dev->rc_idx, pcie_dev->link_check_max_count); pcie_dev->rc_idx, pcie_dev->link_check_max_count);
of_property_read_u32(of_node, "qcom,target-link-speed", of_property_read_u32(of_node, "qcom,target-link-speed",
&pcie_dev->target_link_speed); &pcie_dev->dt_target_link_speed);
PCIE_DBG(pcie_dev, "PCIe: RC%d: target-link-speed: 0x%x.\n", PCIE_DBG(pcie_dev, "PCIe: RC%d: target-link-speed: 0x%x.\n",
pcie_dev->rc_idx, pcie_dev->target_link_speed); pcie_dev->rc_idx, pcie_dev->dt_target_link_speed);
pcie_dev->target_link_speed = pcie_dev->dt_target_link_speed;
of_property_read_u32(of_node, "qcom,n-fts", &pcie_dev->n_fts); of_property_read_u32(of_node, "qcom,n-fts", &pcie_dev->n_fts);
PCIE_DBG(pcie_dev, "n-fts: 0x%x.\n", pcie_dev->n_fts); PCIE_DBG(pcie_dev, "n-fts: 0x%x.\n", pcie_dev->n_fts);
@ -6192,6 +6195,55 @@ static void msm_pcie_poll_for_l0_from_l0s(struct msm_pcie_dev_t *dev)
pci_walk_bus(dev->dev->bus, msm_pcie_read_devid_all, dev); pci_walk_bus(dev->dev->bus, msm_pcie_read_devid_all, dev);
} }
int msm_pcie_set_target_link_speed(u32 rc_idx, u32 target_link_speed)
{
struct msm_pcie_dev_t *pcie_dev;
if (rc_idx >= MAX_RC_NUM) {
pr_err("PCIe: invalid rc index %u\n", rc_idx);
return -EINVAL;
}
pcie_dev = &msm_pcie_dev[rc_idx];
if (!pcie_dev->drv_ready) {
PCIE_DBG(pcie_dev,
"PCIe: RC%d: has not been successfully probed yet\n",
pcie_dev->rc_idx);
return -EPROBE_DEFER;
}
/*
* Reject the request if it exceeds what PCIe RC is capable or if
* it's greater than what was specified in DT (if present)
*/
if (target_link_speed > pcie_dev->bw_gen_max ||
(pcie_dev->dt_target_link_speed &&
target_link_speed > pcie_dev->dt_target_link_speed)) {
PCIE_DBG(pcie_dev,
"PCIe: RC%d: invalid target link speed: %d\n",
pcie_dev->rc_idx, target_link_speed);
return -EINVAL;
}
pcie_dev->target_link_speed = target_link_speed;
/*
* The request 0 will reset maximum GEN speed to default. Default will
* be devicetree specified GEN speed if present else it will be whatever
* the PCIe root complex is capable of.
*/
if (!target_link_speed)
pcie_dev->target_link_speed = pcie_dev->dt_target_link_speed ?
pcie_dev->dt_target_link_speed : pcie_dev->bw_gen_max;
PCIE_DBG(pcie_dev, "PCIe: RC%d: target_link_speed is now: 0x%x.\n",
pcie_dev->rc_idx, pcie_dev->target_link_speed);
return 0;
}
EXPORT_SYMBOL(msm_pcie_set_target_link_speed);
int msm_pcie_set_link_bandwidth(struct pci_dev *pci_dev, u16 target_link_speed, int msm_pcie_set_link_bandwidth(struct pci_dev *pci_dev, u16 target_link_speed,
u16 target_link_width) u16 target_link_width)
{ {

View File

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.*/ /* Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.*/
#ifndef __MSM_PCIE_H #ifndef __MSM_PCIE_H
#define __MSM_PCIE_H #define __MSM_PCIE_H
@ -64,6 +64,24 @@ int msm_msi_init(struct device *dev);
#if IS_ENABLED(CONFIG_PCI_MSM) #if IS_ENABLED(CONFIG_PCI_MSM)
/**
* msm_pcie_set_target_link_speed - sets the upper bound of GEN speed PCIe can
* link up with
* @rc_idx: root complex port number that endpoint is connected to
* @target_link_speed: new target link speed PCIe can link up with
*
* Provide PCIe clients the option to control upper bound of GEN speed PCIe
* can link up with. Clients may choose only GEN speed within root complex's
* controller capability or up to what is defined in devicetree,
* qcom,target-link-speed.
*
* Client may also pass 0 for target_link_speed to have PCIe root complex
* reset and use the default TLS.
*
* Return 0 on success, negative value on error
*/
int msm_pcie_set_target_link_speed(u32 rc_idx, u32 target_link_speed);
/** /**
* msm_pcie_allow_l1 - allow PCIe link to re-enter L1 * msm_pcie_allow_l1 - allow PCIe link to re-enter L1
* @pci_dev: client's pci device structure * @pci_dev: client's pci device structure
@ -221,6 +239,12 @@ static inline int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr,
return -ENODEV; return -ENODEV;
} }
static inline int msm_pcie_set_target_link_speed(u32 rc_idx,
u32 target_link_speed)
{
return -ENODEV;
}
static inline void msm_pcie_allow_l1(struct pci_dev *pci_dev) static inline void msm_pcie_allow_l1(struct pci_dev *pci_dev)
{ {
} }