On Tue, Nov 12, 2024 at 08:31:37PM +0530, Krishna chaitanya chundru wrote:Instead of exporting this API, I will try to read config space and see if the link is up or not. if it is not up then will call these.
For the switches like QPS615 which needs to configure it before
the PCIe link is established.
If the link is up, the boatloader might powered and configured the
endpoint/switch already. In that case don't touch PCIe link else
assert the PERST# and disable LTSSM bit so that PCIe controller
will not participate in the link training as part of host_stop_link().
De-assert the PERST# and enable LTSSM bit back in host_start_link().
Introduce ltssm_disable function op to stop the link training.
Signed-off-by: Krishna chaitanya chundru <quic_krichai@xxxxxxxxxxx>
---
drivers/pci/controller/dwc/pcie-qcom.c | 39 ++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index ef44a82be058..048aea94e319 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -246,6 +246,7 @@ struct qcom_pcie_ops {
void (*host_post_init)(struct qcom_pcie *pcie);
void (*deinit)(struct qcom_pcie *pcie);
void (*ltssm_enable)(struct qcom_pcie *pcie);
+ void (*ltssm_disable)(struct qcom_pcie *pcie);
int (*config_sid)(struct qcom_pcie *pcie);
};
@@ -617,6 +618,41 @@ static int qcom_pcie_post_init_1_0_0(struct qcom_pcie *pcie)
return 0;
}
+static int qcom_pcie_host_start_link(struct dw_pcie *pci)
+{
+ struct qcom_pcie *pcie = to_qcom_pcie(pci);
+
+ if (!dw_pcie_link_up(pcie->pci)) {
I don't think the controller driver should worry about the bootloader
initialization. You should export dw_pcie_link_up() as a callback and call
start/stop link if only required (link not up) from the pwrctl driver.
- Mani
+ qcom_ep_reset_deassert(pcie);
+
+ if (pcie->cfg->ops->ltssm_enable)
+ pcie->cfg->ops->ltssm_enable(pcie);
+ }
+
+ return 0;
+}
+
+static void qcom_pcie_host_stop_link(struct dw_pcie *pci)
+{
+ struct qcom_pcie *pcie = to_qcom_pcie(pci);
+
+ if (!dw_pcie_link_up(pcie->pci)) {
+ qcom_ep_reset_assert(pcie);
+
+ if (pcie->cfg->ops->ltssm_disable)
+ pcie->cfg->ops->ltssm_disable(pcie);
+ }
+}
+
+static void qcom_pcie_2_3_2_ltssm_disable(struct qcom_pcie *pcie)
+{
+ u32 val;
+
+ val = readl(pcie->parf + PARF_LTSSM);
+ val &= ~LTSSM_EN;
+ writel(val, pcie->parf + PARF_LTSSM);
+}
+
static void qcom_pcie_2_3_2_ltssm_enable(struct qcom_pcie *pcie)
{
u32 val;
@@ -1361,6 +1397,7 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
.host_post_init = qcom_pcie_host_post_init_2_7_0,
.deinit = qcom_pcie_deinit_2_7_0,
.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
+ .ltssm_disable = qcom_pcie_2_3_2_ltssm_disable,
.config_sid = qcom_pcie_config_sid_1_9_0,
};
@@ -1418,6 +1455,8 @@ static const struct qcom_pcie_cfg cfg_sc8280xp = {
static const struct dw_pcie_ops dw_pcie_ops = {
.link_up = qcom_pcie_link_up,
.start_link = qcom_pcie_start_link,
+ .host_start_link = qcom_pcie_host_start_link,
+ .host_stop_link = qcom_pcie_host_stop_link,
};
static int qcom_pcie_icc_init(struct qcom_pcie *pcie)
--
2.34.1