aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq806x/patches-5.4/0071-8-pcie-qcom-Fixed-pcie_phy_clk-branch-issue.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ipq806x/patches-5.4/0071-8-pcie-qcom-Fixed-pcie_phy_clk-branch-issue.patch')
-rw-r--r--target/linux/ipq806x/patches-5.4/0071-8-pcie-qcom-Fixed-pcie_phy_clk-branch-issue.patch91
1 files changed, 91 insertions, 0 deletions
diff --git a/target/linux/ipq806x/patches-5.4/0071-8-pcie-qcom-Fixed-pcie_phy_clk-branch-issue.patch b/target/linux/ipq806x/patches-5.4/0071-8-pcie-qcom-Fixed-pcie_phy_clk-branch-issue.patch
new file mode 100644
index 0000000000..7cbeb3bed7
--- /dev/null
+++ b/target/linux/ipq806x/patches-5.4/0071-8-pcie-qcom-Fixed-pcie_phy_clk-branch-issue.patch
@@ -0,0 +1,91 @@
+From b74bab6186131eea09459eedf5d737645a3559c9 Mon Sep 17 00:00:00 2001
+From: Abhishek Sahu <absahu@codeaurora.org>
+Date: Thu, 22 Dec 2016 11:18:45 +0530
+Subject: pcie: qcom: Fixed pcie_phy_clk branch issue
+
+Following backtraces are observed in PCIe deinit operation.
+
+ Hardware name: Qualcomm (Flattened Device Tree)
+ (unwind_backtrace) from [] (show_stack+0x10/0x14)
+ (show_stack) from [] (dump_stack+0x84/0x98)
+ (dump_stack) from [] (warn_slowpath_common+0x9c/0xb8)
+ (warn_slowpath_common) from [] (warn_slowpath_fmt+0x30/0x40)
+ (warn_slowpath_fmt) from [] (clk_branch_wait+0x114/0x120)
+ (clk_branch_wait) from [] (clk_core_disable+0xd0/0x1f4)
+ (clk_core_disable) from [] (clk_disable+0x24/0x30)
+ (clk_disable) from [] (qcom_pcie_deinit_v0+0x6c/0xb8)
+ (qcom_pcie_deinit_v0) from [] (qcom_pcie_host_init+0xe0/0xe8)
+ (qcom_pcie_host_init) from [] (dw_pcie_host_init+0x3b0/0x538)
+ (dw_pcie_host_init) from [] (qcom_pcie_probe+0x20c/0x2e4)
+
+pcie_phy_clk is generated for PCIe controller itself and the
+GCC controls its branch operation. This error is coming since
+the assert operations turn off the parent clock before branch
+clock. Now this patch moves clk_disable_unprepare before assert
+operations.
+
+Similarly, during probe function, the clock branch operation
+should be done after dessert operation. Currently, it does not
+generate any error since bootloader enables the pcie_phy_clk
+but the same error is coming during probe, if bootloader
+disables pcie_phy_clk.
+
+Change-Id: Ib29c154d10eb64363d9cc982ce5fd8107af5627d
+Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
+---
+ drivers/pci/host/pcie-qcom.c | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -393,6 +393,7 @@ static void qcom_pcie_deinit_2_1_0(struc
+ {
+ struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
+
++ clk_disable_unprepare(res->phy_clk);
+ reset_control_assert(res->pci_reset);
+ reset_control_assert(res->axi_reset);
+ reset_control_assert(res->ahb_reset);
+@@ -401,7 +402,6 @@ static void qcom_pcie_deinit_2_1_0(struc
+ reset_control_assert(res->ext_reset);
+ 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_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
+@@ -444,12 +444,6 @@ static int qcom_pcie_init_2_1_0(struct q
+ 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->aux_clk);
+ if (ret) {
+ dev_err(dev, "cannot prepare/enable aux clock\n");
+@@ -513,6 +507,12 @@ static int qcom_pcie_init_2_1_0(struct q
+ return ret;
+ }
+
++ ret = clk_prepare_enable(res->phy_clk);
++ if (ret) {
++ dev_err(dev, "cannot prepare/enable phy clock\n");
++ goto err_deassert_ahb;
++ }
++
+ /* wait for clock acquisition */
+ usleep_range(1000, 1500);
+ if (pcie->force_gen1) {
+@@ -538,8 +538,6 @@ err_deassert_ahb:
+ 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);