123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- From: David Bauer <[email protected]>
- 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 <[email protected]>
- --- 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" },
- {},
- };
-
|