mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-29 18:19:02 +00:00
36a96a4493
In current state there's huge regression on ipq806x target that causes the device to transmit broken/malformed frames that are not corrected/detected by error control mechanisms and other less severe issues. https://bugs.lede-project.org/index.php?do=details&task_id=1197 This finally had been narrowed down to patch 0071-pcie-qcom-fixes.patch Meanwhile QSDK contains a handful of commits that add support for ipq806x to upstream qcom pcie driver https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-msm/log/drivers/pci/host/pcie-qcom.c?h=eggplant Unfortunately qca developers do not bother to push it upstream. Using those commits instead of lede 0071 patch fixes mentioned issue and probably many others as it seems that corrupted data has been originating within pcie misconfiguration. Fixes: FS#1197 and probably others Signed-off-by: Pavel Kubelun <be.dissent@gmail.com>
96 lines
2.8 KiB
Diff
96 lines
2.8 KiB
Diff
From 86655aa14304ca88a8ce8847276147dbc1a83238 Mon Sep 17 00:00:00 2001
|
|
From: Sham Muthayyan <smuthayy@codeaurora.org>
|
|
Date: Tue, 19 Jul 2016 18:44:49 +0530
|
|
Subject: PCI: qcom: Fixed IPQ806x specific clocks
|
|
|
|
Change-Id: I488e1bc707d6a22b37a338f41935e3922009ba5e
|
|
Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org>
|
|
---
|
|
drivers/pci/host/pcie-qcom.c | 38 +++++++++++++++++++++++++++++++++-----
|
|
1 file changed, 33 insertions(+), 5 deletions(-)
|
|
|
|
--- a/drivers/pci/host/pcie-qcom.c
|
|
+++ b/drivers/pci/host/pcie-qcom.c
|
|
@@ -53,6 +53,8 @@ struct qcom_pcie_resources_v0 {
|
|
struct clk *iface_clk;
|
|
struct clk *core_clk;
|
|
struct clk *phy_clk;
|
|
+ struct clk *aux_clk;
|
|
+ struct clk *ref_clk;
|
|
struct reset_control *pci_reset;
|
|
struct reset_control *axi_reset;
|
|
struct reset_control *ahb_reset;
|
|
@@ -160,6 +162,14 @@ static int qcom_pcie_get_resources_v0(st
|
|
if (IS_ERR(res->phy_clk))
|
|
return PTR_ERR(res->phy_clk);
|
|
|
|
+ res->aux_clk = devm_clk_get(dev, "aux");
|
|
+ if (IS_ERR(res->aux_clk))
|
|
+ return PTR_ERR(res->aux_clk);
|
|
+
|
|
+ res->ref_clk = devm_clk_get(dev, "ref");
|
|
+ if (IS_ERR(res->ref_clk))
|
|
+ return PTR_ERR(res->ref_clk);
|
|
+
|
|
res->pci_reset = devm_reset_control_get(dev, "pci");
|
|
if (IS_ERR(res->pci_reset))
|
|
return PTR_ERR(res->pci_reset);
|
|
@@ -227,6 +237,8 @@ static void qcom_pcie_deinit_v0(struct q
|
|
clk_disable_unprepare(res->iface_clk);
|
|
clk_disable_unprepare(res->core_clk);
|
|
clk_disable_unprepare(res->phy_clk);
|
|
+ clk_disable_unprepare(res->aux_clk);
|
|
+ clk_disable_unprepare(res->ref_clk);
|
|
regulator_disable(res->vdda);
|
|
regulator_disable(res->vdda_phy);
|
|
regulator_disable(res->vdda_refclk);
|
|
@@ -269,16 +281,28 @@ static int qcom_pcie_init_v0(struct qcom
|
|
goto err_assert_ahb;
|
|
}
|
|
|
|
+ ret = clk_prepare_enable(res->core_clk);
|
|
+ if (ret) {
|
|
+ dev_err(dev, "cannot prepare/enable core clock\n");
|
|
+ goto err_clk_core;
|
|
+ }
|
|
+
|
|
ret = clk_prepare_enable(res->phy_clk);
|
|
if (ret) {
|
|
dev_err(dev, "cannot prepare/enable phy clock\n");
|
|
goto err_clk_phy;
|
|
}
|
|
|
|
- ret = clk_prepare_enable(res->core_clk);
|
|
+ ret = clk_prepare_enable(res->aux_clk);
|
|
if (ret) {
|
|
- dev_err(dev, "cannot prepare/enable core clock\n");
|
|
- goto err_clk_core;
|
|
+ dev_err(dev, "cannot prepare/enable aux clock\n");
|
|
+ goto err_clk_aux;
|
|
+ }
|
|
+
|
|
+ ret = clk_prepare_enable(res->ref_clk);
|
|
+ if (ret) {
|
|
+ dev_err(dev, "cannot prepare/enable ref clock\n");
|
|
+ goto err_clk_ref;
|
|
}
|
|
|
|
ret = reset_control_deassert(res->ahb_reset);
|
|
@@ -327,10 +351,14 @@ static int qcom_pcie_init_v0(struct qcom
|
|
return 0;
|
|
|
|
err_deassert_ahb:
|
|
- clk_disable_unprepare(res->core_clk);
|
|
-err_clk_core:
|
|
+ clk_disable_unprepare(res->ref_clk);
|
|
+err_clk_ref:
|
|
+ clk_disable_unprepare(res->aux_clk);
|
|
+err_clk_aux:
|
|
clk_disable_unprepare(res->phy_clk);
|
|
err_clk_phy:
|
|
+ clk_disable_unprepare(res->core_clk);
|
|
+err_clk_core:
|
|
clk_disable_unprepare(res->iface_clk);
|
|
err_assert_ahb:
|
|
regulator_disable(res->vdda_phy);
|