summaryrefslogtreecommitdiffstats
path: root/target/linux/ath79/patches-6.6/315-MIPS-pci-ar724x-add-QCA9550-reset-sequence.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ath79/patches-6.6/315-MIPS-pci-ar724x-add-QCA9550-reset-sequence.patch')
-rw-r--r--target/linux/ath79/patches-6.6/315-MIPS-pci-ar724x-add-QCA9550-reset-sequence.patch130
1 files changed, 130 insertions, 0 deletions
diff --git a/target/linux/ath79/patches-6.6/315-MIPS-pci-ar724x-add-QCA9550-reset-sequence.patch b/target/linux/ath79/patches-6.6/315-MIPS-pci-ar724x-add-QCA9550-reset-sequence.patch
new file mode 100644
index 0000000000..375dec8ba2
--- /dev/null
+++ b/target/linux/ath79/patches-6.6/315-MIPS-pci-ar724x-add-QCA9550-reset-sequence.patch
@@ -0,0 +1,130 @@
+From: David Bauer <mail@david-bauer.net>
+Date: Sat, 11 Apr 2020 14:03:12 +0200
+Subject: MIPS: pci-ar724x: add QCA9550 reset sequence
+
+The QCA9550 family of SoCs have a slightly different reset
+sequence compared to older chips.
+
+Normally the bootloader performs this sequence, however
+some bootloader implementation expect the operating system
+to clear the reset.
+
+Also get the resets from OF to support handling of the second
+PCIe root-complex on the QCA9558.
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+
+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+@@ -390,6 +390,7 @@
+ #define QCA955X_PLL_CPU_CONFIG_REG 0x00
+ #define QCA955X_PLL_DDR_CONFIG_REG 0x04
+ #define QCA955X_PLL_CLK_CTRL_REG 0x08
++#define QCA955X_PLL_PCIE_CONFIG_REG 0x0c
+ #define QCA955X_PLL_ETH_XMII_CONTROL_REG 0x28
+ #define QCA955X_PLL_ETH_SGMII_CONTROL_REG 0x48
+ #define QCA955X_PLL_ETH_SGMII_SERDES_REG 0x4c
+@@ -475,6 +476,9 @@
+ #define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL BIT(21)
+ #define QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+
++#define QCA955X_PLL_PCIE_CONFIG_PLL_PWD BIT(30)
++#define QCA955X_PLL_PCIE_CONFIG_PLL_BYPASS BIT(16)
++
+ #define QCA956X_PLL_SWITCH_CLOCK_SPARE_I2C_CLK_SELB BIT(5)
+ #define QCA956X_PLL_SWITCH_CLOCK_SPARE_MDIO_CLK_SEL0_1 BIT(6)
+ #define QCA956X_PLL_SWITCH_CLOCK_SPARE_UART1_CLK_SEL BIT(7)
+--- a/arch/mips/pci/pci-ar724x.c
++++ b/arch/mips/pci/pci-ar724x.c
+@@ -8,6 +8,7 @@
+
+ #include <linux/irq.h>
+ #include <linux/pci.h>
++#include <linux/reset.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+ #include <linux/platform_device.h>
+@@ -55,6 +56,9 @@ struct ar724x_pci_controller {
+ struct irq_domain *domain;
+ struct resource io_res;
+ struct resource mem_res;
++
++ struct reset_control *hc_reset;
++ struct reset_control *phy_reset;
+ };
+
+ static struct irq_chip ar724x_pci_irq_chip;
+@@ -340,18 +344,30 @@ static void ar724x_pci_hw_init(struct ar
+ int wait = 0;
+
+ /* deassert PCIe host controller and PCIe PHY reset */
+- ath79_device_reset_clear(AR724X_RESET_PCIE);
+- ath79_device_reset_clear(AR724X_RESET_PCIE_PHY);
++ reset_control_deassert(apc->hc_reset);
++ reset_control_deassert(apc->phy_reset);
+
+- /* remove the reset of the PCIE PLL */
+- ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
+- ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET;
+- ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
+-
+- /* deassert bypass for the PCIE PLL */
+- ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
+- ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS;
+- ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
++ if (of_device_is_compatible(apc->np, "qcom,qca9550-pci")) {
++ /* remove the reset of the PCIE PLL */
++ ppl = ath79_pll_rr(QCA955X_PLL_PCIE_CONFIG_REG);
++ ppl &= ~QCA955X_PLL_PCIE_CONFIG_PLL_PWD;
++ ath79_pll_wr(QCA955X_PLL_PCIE_CONFIG_REG, ppl);
++
++ /* deassert bypass for the PCIE PLL */
++ ppl = ath79_pll_rr(QCA955X_PLL_PCIE_CONFIG_REG);
++ ppl &= ~QCA955X_PLL_PCIE_CONFIG_PLL_BYPASS;
++ ath79_pll_wr(QCA955X_PLL_PCIE_CONFIG_REG, ppl);
++ } else {
++ /* remove the reset of the PCIE PLL */
++ ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
++ ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET;
++ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
++
++ /* deassert bypass for the PCIE PLL */
++ ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
++ ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS;
++ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
++ }
+
+ /* set PCIE Application Control to ready */
+ app = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_APP);
+@@ -395,6 +411,14 @@ static int ar724x_pci_probe(struct platf
+ if (apc->irq < 0)
+ return -EINVAL;
+
++ apc->hc_reset = devm_reset_control_get_exclusive(&pdev->dev, "hc");
++ if (IS_ERR(apc->hc_reset))
++ return PTR_ERR(apc->hc_reset);
++
++ apc->phy_reset = devm_reset_control_get_exclusive(&pdev->dev, "phy");
++ if (IS_ERR(apc->phy_reset))
++ return PTR_ERR(apc->phy_reset);
++
+ apc->np = pdev->dev.of_node;
+ apc->pci_controller.pci_ops = &ar724x_pci_ops;
+ apc->pci_controller.io_resource = &apc->io_res;
+@@ -405,7 +429,7 @@ static int ar724x_pci_probe(struct platf
+ * Do the full PCIE Root Complex Initialization Sequence if the PCIe
+ * host controller is in reset.
+ */
+- if (ath79_reset_rr(AR724X_RESET_REG_RESET_MODULE) & AR724X_RESET_PCIE)
++ if (reset_control_status(apc->hc_reset))
+ ar724x_pci_hw_init(apc);
+
+ apc->link_up = ar724x_pci_check_link(apc);
+@@ -423,6 +447,7 @@ static int ar724x_pci_probe(struct platf
+
+ static const struct of_device_id ar724x_pci_ids[] = {
+ { .compatible = "qcom,ar7240-pci" },
++ { .compatible = "qcom,qca9550-pci" },
+ {},
+ };
+