diff options
Diffstat (limited to 'drivers/pci/host/pci-tegra.c')
| -rw-r--r-- | drivers/pci/host/pci-tegra.c | 78 | 
1 files changed, 53 insertions, 25 deletions
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 2e9888a0635..083cf37ca04 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -25,7 +25,6 @@   */  #include <linux/clk.h> -#include <linux/clk/tegra.h>  #include <linux/delay.h>  #include <linux/export.h>  #include <linux/interrupt.h> @@ -39,6 +38,7 @@  #include <linux/of_platform.h>  #include <linux/pci.h>  #include <linux/platform_device.h> +#include <linux/reset.h>  #include <linux/sizes.h>  #include <linux/slab.h>  #include <linux/tegra-cpuidle.h> @@ -249,7 +249,7 @@ struct tegra_pcie {  	void __iomem *afi;  	int irq; -	struct list_head busses; +	struct list_head buses;  	struct resource *cs;  	struct resource io; @@ -259,10 +259,13 @@ struct tegra_pcie {  	struct clk *pex_clk;  	struct clk *afi_clk; -	struct clk *pcie_xclk;  	struct clk *pll_e;  	struct clk *cml_clk; +	struct reset_control *pex_rst; +	struct reset_control *afi_rst; +	struct reset_control *pcie_xrst; +  	struct tegra_msi msi;  	struct list_head ports; @@ -399,24 +402,24 @@ free:  /*   * Look up a virtual address mapping for the specified bus number. If no such - * mapping existis, try to create one. + * mapping exists, try to create one.   */  static void __iomem *tegra_pcie_bus_map(struct tegra_pcie *pcie,  					unsigned int busnr)  {  	struct tegra_pcie_bus *bus; -	list_for_each_entry(bus, &pcie->busses, list) +	list_for_each_entry(bus, &pcie->buses, list)  		if (bus->nr == busnr) -			return bus->area->addr; +			return (void __iomem *)bus->area->addr;  	bus = tegra_pcie_bus_alloc(pcie, busnr);  	if (IS_ERR(bus))  		return NULL; -	list_add_tail(&bus->list, &pcie->busses); +	list_add_tail(&bus->list, &pcie->buses); -	return bus->area->addr; +	return (void __iomem *)bus->area->addr;  }  static void __iomem *tegra_pcie_conf_address(struct pci_bus *bus, @@ -636,10 +639,15 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)  static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)  {  	struct tegra_pcie *pcie = sys_to_pcie(pdev->bus->sysdata); +	int irq;  	tegra_cpuidle_pcie_irqs_in_use(); -	return pcie->irq; +	irq = of_irq_parse_and_map_pci(pdev, slot, pin); +	if (!irq) +		irq = pcie->irq; + +	return irq;  }  static void tegra_pcie_add_bus(struct pci_bus *bus) @@ -805,10 +813,10 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)  	afi_writel(pcie, value, AFI_PCIE_CONFIG);  	value = afi_readl(pcie, AFI_FUSE); -	value &= ~AFI_FUSE_PCIE_T0_GEN2_DIS; +	value |= AFI_FUSE_PCIE_T0_GEN2_DIS;  	afi_writel(pcie, value, AFI_FUSE); -	/* initialze internal PHY, enable up to 16 PCIE lanes */ +	/* initialize internal PHY, enable up to 16 PCIE lanes */  	pads_writel(pcie, 0x0, PADS_CTL_SEL);  	/* override IDDQ to 1 on all 4 lanes */ @@ -858,7 +866,7 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)  	pads_writel(pcie, value, PADS_CTL);  	/* take the PCIe interface module out of reset */ -	tegra_periph_reset_deassert(pcie->pcie_xclk); +	reset_control_deassert(pcie->pcie_xrst);  	/* finally enable PCIe */  	value = afi_readl(pcie, AFI_CONFIGURATION); @@ -891,9 +899,9 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie)  	/* TODO: disable and unprepare clocks? */ -	tegra_periph_reset_assert(pcie->pcie_xclk); -	tegra_periph_reset_assert(pcie->afi_clk); -	tegra_periph_reset_assert(pcie->pex_clk); +	reset_control_assert(pcie->pcie_xrst); +	reset_control_assert(pcie->afi_rst); +	reset_control_assert(pcie->pex_rst);  	tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); @@ -921,9 +929,9 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)  	const struct tegra_pcie_soc_data *soc = pcie->soc_data;  	int err; -	tegra_periph_reset_assert(pcie->pcie_xclk); -	tegra_periph_reset_assert(pcie->afi_clk); -	tegra_periph_reset_assert(pcie->pex_clk); +	reset_control_assert(pcie->pcie_xrst); +	reset_control_assert(pcie->afi_rst); +	reset_control_assert(pcie->pex_rst);  	tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); @@ -952,13 +960,14 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)  	}  	err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE, -						pcie->pex_clk); +						pcie->pex_clk, +						pcie->pex_rst);  	if (err) {  		dev_err(pcie->dev, "powerup sequence failed: %d\n", err);  		return err;  	} -	tegra_periph_reset_deassert(pcie->afi_clk); +	reset_control_deassert(pcie->afi_rst);  	err = clk_prepare_enable(pcie->afi_clk);  	if (err < 0) { @@ -996,10 +1005,6 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)  	if (IS_ERR(pcie->afi_clk))  		return PTR_ERR(pcie->afi_clk); -	pcie->pcie_xclk = devm_clk_get(pcie->dev, "pcie_xclk"); -	if (IS_ERR(pcie->pcie_xclk)) -		return PTR_ERR(pcie->pcie_xclk); -  	pcie->pll_e = devm_clk_get(pcie->dev, "pll_e");  	if (IS_ERR(pcie->pll_e))  		return PTR_ERR(pcie->pll_e); @@ -1013,6 +1018,23 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)  	return 0;  } +static int tegra_pcie_resets_get(struct tegra_pcie *pcie) +{ +	pcie->pex_rst = devm_reset_control_get(pcie->dev, "pex"); +	if (IS_ERR(pcie->pex_rst)) +		return PTR_ERR(pcie->pex_rst); + +	pcie->afi_rst = devm_reset_control_get(pcie->dev, "afi"); +	if (IS_ERR(pcie->afi_rst)) +		return PTR_ERR(pcie->afi_rst); + +	pcie->pcie_xrst = devm_reset_control_get(pcie->dev, "pcie_x"); +	if (IS_ERR(pcie->pcie_xrst)) +		return PTR_ERR(pcie->pcie_xrst); + +	return 0; +} +  static int tegra_pcie_get_resources(struct tegra_pcie *pcie)  {  	struct platform_device *pdev = to_platform_device(pcie->dev); @@ -1025,6 +1047,12 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)  		return err;  	} +	err = tegra_pcie_resets_get(pcie); +	if (err) { +		dev_err(&pdev->dev, "failed to get resets: %d\n", err); +		return err; +	} +  	err = tegra_pcie_power_on(pcie);  	if (err) {  		dev_err(&pdev->dev, "failed to power up: %d\n", err); @@ -1624,7 +1652,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)  	if (!pcie)  		return -ENOMEM; -	INIT_LIST_HEAD(&pcie->busses); +	INIT_LIST_HEAD(&pcie->buses);  	INIT_LIST_HEAD(&pcie->ports);  	pcie->soc_data = match->data;  	pcie->dev = &pdev->dev;  | 
