Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 95773672 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/host-rockchip' into next

* pci/host-rockchip:
  PCI: rockchip: Modularize
  PCI: Export pci_remap_iospace() and pci_unmap_iospace()
  PCI: rockchip: Add remove() support
  PCI: rockchip: Set PCI_EXP_LNKSTA_SLC in the Root Port
  PCI: rockchip: Advertise 128-byte Read Completion Boundary support
  PCI: rockchip: Make 'return 0' more obvious in probe()
  PCI: rockchip: Unindent rockchip_pcie_set_power_limit()
  PCI: rockchip: Handle regulator_get_current_limit() failure correctly
parents 443b1b06 b0308c54
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -170,7 +170,7 @@ config PCI_HOST_THUNDER_ECAM
	  Say Y here if you want ECAM support for CN88XX-Pass-1.x Cavium Thunder SoCs.

config PCIE_ROCKCHIP
	bool "Rockchip PCIe controller"
	tristate "Rockchip PCIe controller"
	depends on ARCH_ROCKCHIP || COMPILE_TEST
	depends on OF
	depends on PCI_MSI_IRQ_DOMAIN
+67 −22
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/irqdomain.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_pci.h>
@@ -223,9 +224,11 @@ struct rockchip_pcie {
	int	link_gen;
	struct	device *dev;
	struct	irq_domain *irq_domain;
	u32     io_size;
	int     offset;
	struct pci_bus *root_bus;
	struct resource *io;
	phys_addr_t io_bus_addr;
	u32     io_size;
	void    __iomem *msg_region;
	u32     mem_size;
	phys_addr_t msg_bus_addr;
@@ -425,7 +428,8 @@ static struct pci_ops rockchip_pcie_ops = {

static void rockchip_pcie_set_power_limit(struct rockchip_pcie *rockchip)
{
	u32 status, curr, scale, power;
	int curr;
	u32 status, scale, power;

	if (IS_ERR(rockchip->vpcie3v3))
		return;
@@ -437,7 +441,9 @@ static void rockchip_pcie_set_power_limit(struct rockchip_pcie *rockchip)
	 * to the actual power supply.
	 */
	curr = regulator_get_current_limit(rockchip->vpcie3v3);
	if (curr > 0) {
	if (curr <= 0)
		return;

	scale = 3; /* 0.001x */
	curr = curr / 1000; /* convert to mA */
	power = (curr * 3300) / 1000; /* milliwatt */
@@ -455,7 +461,6 @@ static void rockchip_pcie_set_power_limit(struct rockchip_pcie *rockchip)
		  (scale << PCIE_RC_CONFIG_DCR_CPLS_SHIFT);
	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DCR);
}
}

/**
 * rockchip_pcie_init_port - Initialize hardware
@@ -596,7 +601,12 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)

	/* Set RC's clock architecture as common clock */
	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS);
	status |= PCI_EXP_LNKCTL_CCC;
	status |= PCI_EXP_LNKSTA_SLC << 16;
	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS);

	/* Set RC's RCB to 128 */
	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS);
	status |= PCI_EXP_LNKCTL_RCB;
	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS);

	/* Enable Gen1 training */
@@ -1359,6 +1369,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
					 err, io);
				continue;
			}
			rockchip->io = io;
			break;
		case IORESOURCE_MEM:
			mem = win->res;
@@ -1390,6 +1401,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
		err = -ENOMEM;
		goto err_free_res;
	}
	rockchip->root_bus = bus;

	pci_bus_size_bridges(bus);
	pci_bus_assign_resources(bus);
@@ -1397,7 +1409,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
		pcie_bus_configure_settings(child);

	pci_bus_add_devices(bus);
	return err;
	return 0;

err_free_res:
	pci_free_resource_list(&res);
@@ -1420,6 +1432,34 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
	return err;
}

static int rockchip_pcie_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct rockchip_pcie *rockchip = dev_get_drvdata(dev);

	pci_stop_root_bus(rockchip->root_bus);
	pci_remove_root_bus(rockchip->root_bus);
	pci_unmap_iospace(rockchip->io);
	irq_domain_remove(rockchip->irq_domain);

	phy_power_off(rockchip->phy);
	phy_exit(rockchip->phy);

	clk_disable_unprepare(rockchip->clk_pcie_pm);
	clk_disable_unprepare(rockchip->hclk_pcie);
	clk_disable_unprepare(rockchip->aclk_perf_pcie);
	clk_disable_unprepare(rockchip->aclk_pcie);

	if (!IS_ERR(rockchip->vpcie3v3))
		regulator_disable(rockchip->vpcie3v3);
	if (!IS_ERR(rockchip->vpcie1v8))
		regulator_disable(rockchip->vpcie1v8);
	if (!IS_ERR(rockchip->vpcie0v9))
		regulator_disable(rockchip->vpcie0v9);

	return 0;
}

static const struct dev_pm_ops rockchip_pcie_pm_ops = {
	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(rockchip_pcie_suspend_noirq,
				      rockchip_pcie_resume_noirq)
@@ -1429,6 +1469,7 @@ static const struct of_device_id rockchip_pcie_of_match[] = {
	{ .compatible = "rockchip,rk3399-pcie", },
	{}
};
MODULE_DEVICE_TABLE(of, rockchip_pcie_of_match);

static struct platform_driver rockchip_pcie_driver = {
	.driver = {
@@ -1437,6 +1478,10 @@ static struct platform_driver rockchip_pcie_driver = {
		.pm = &rockchip_pcie_pm_ops,
	},
	.probe = rockchip_pcie_probe,

	.remove = rockchip_pcie_remove,
};
builtin_platform_driver(rockchip_pcie_driver);
module_platform_driver(rockchip_pcie_driver);

MODULE_AUTHOR("Rockchip Inc");
MODULE_DESCRIPTION("Rockchip AXI PCIe driver");
MODULE_LICENSE("GPL v2");
+2 −0
Original line number Diff line number Diff line
@@ -3383,6 +3383,7 @@ int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr)
	return -ENODEV;
#endif
}
EXPORT_SYMBOL(pci_remap_iospace);

/**
 *	pci_unmap_iospace - Unmap the memory mapped I/O space
@@ -3400,6 +3401,7 @@ void pci_unmap_iospace(struct resource *res)
	unmap_kernel_range(vaddr, resource_size(res));
#endif
}
EXPORT_SYMBOL(pci_unmap_iospace);

static void __pci_set_master(struct pci_dev *dev, bool enable)
{