Initial commit
This commit is contained in:
		| @@ -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 | ||||
| @@ -391,6 +391,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 | ||||
| @@ -476,6 +477,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); | ||||
| @@ -396,6 +412,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; | ||||
| @@ -406,7 +430,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); | ||||
| @@ -424,6 +448,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" }, | ||||
|  	{}, | ||||
|  }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 domenico
					domenico