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
This commit is contained in:
commit
9577367283
|
@ -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.
|
Say Y here if you want ECAM support for CN88XX-Pass-1.x Cavium Thunder SoCs.
|
||||||
|
|
||||||
config PCIE_ROCKCHIP
|
config PCIE_ROCKCHIP
|
||||||
bool "Rockchip PCIe controller"
|
tristate "Rockchip PCIe controller"
|
||||||
depends on ARCH_ROCKCHIP || COMPILE_TEST
|
depends on ARCH_ROCKCHIP || COMPILE_TEST
|
||||||
depends on OF
|
depends on OF
|
||||||
depends on PCI_MSI_IRQ_DOMAIN
|
depends on PCI_MSI_IRQ_DOMAIN
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <linux/irqdomain.h>
|
#include <linux/irqdomain.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/mfd/syscon.h>
|
#include <linux/mfd/syscon.h>
|
||||||
|
#include <linux/module.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/of_pci.h>
|
#include <linux/of_pci.h>
|
||||||
|
@ -223,9 +224,11 @@ struct rockchip_pcie {
|
||||||
int link_gen;
|
int link_gen;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct irq_domain *irq_domain;
|
struct irq_domain *irq_domain;
|
||||||
u32 io_size;
|
|
||||||
int offset;
|
int offset;
|
||||||
|
struct pci_bus *root_bus;
|
||||||
|
struct resource *io;
|
||||||
phys_addr_t io_bus_addr;
|
phys_addr_t io_bus_addr;
|
||||||
|
u32 io_size;
|
||||||
void __iomem *msg_region;
|
void __iomem *msg_region;
|
||||||
u32 mem_size;
|
u32 mem_size;
|
||||||
phys_addr_t msg_bus_addr;
|
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)
|
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))
|
if (IS_ERR(rockchip->vpcie3v3))
|
||||||
return;
|
return;
|
||||||
|
@ -437,24 +441,25 @@ static void rockchip_pcie_set_power_limit(struct rockchip_pcie *rockchip)
|
||||||
* to the actual power supply.
|
* to the actual power supply.
|
||||||
*/
|
*/
|
||||||
curr = regulator_get_current_limit(rockchip->vpcie3v3);
|
curr = regulator_get_current_limit(rockchip->vpcie3v3);
|
||||||
if (curr > 0) {
|
if (curr <= 0)
|
||||||
scale = 3; /* 0.001x */
|
return;
|
||||||
curr = curr / 1000; /* convert to mA */
|
|
||||||
power = (curr * 3300) / 1000; /* milliwatt */
|
|
||||||
while (power > PCIE_RC_CONFIG_DCR_CSPL_LIMIT) {
|
|
||||||
if (!scale) {
|
|
||||||
dev_warn(rockchip->dev, "invalid power supply\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
scale--;
|
|
||||||
power = power / 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DCR);
|
scale = 3; /* 0.001x */
|
||||||
status |= (power << PCIE_RC_CONFIG_DCR_CSPL_SHIFT) |
|
curr = curr / 1000; /* convert to mA */
|
||||||
(scale << PCIE_RC_CONFIG_DCR_CPLS_SHIFT);
|
power = (curr * 3300) / 1000; /* milliwatt */
|
||||||
rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DCR);
|
while (power > PCIE_RC_CONFIG_DCR_CSPL_LIMIT) {
|
||||||
|
if (!scale) {
|
||||||
|
dev_warn(rockchip->dev, "invalid power supply\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
scale--;
|
||||||
|
power = power / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DCR);
|
||||||
|
status |= (power << PCIE_RC_CONFIG_DCR_CSPL_SHIFT) |
|
||||||
|
(scale << PCIE_RC_CONFIG_DCR_CPLS_SHIFT);
|
||||||
|
rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DCR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -596,7 +601,12 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
|
||||||
|
|
||||||
/* Set RC's clock architecture as common clock */
|
/* Set RC's clock architecture as common clock */
|
||||||
status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS);
|
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);
|
rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS);
|
||||||
|
|
||||||
/* Enable Gen1 training */
|
/* Enable Gen1 training */
|
||||||
|
@ -1359,6 +1369,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
|
||||||
err, io);
|
err, io);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
rockchip->io = io;
|
||||||
break;
|
break;
|
||||||
case IORESOURCE_MEM:
|
case IORESOURCE_MEM:
|
||||||
mem = win->res;
|
mem = win->res;
|
||||||
|
@ -1390,6 +1401,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto err_free_res;
|
goto err_free_res;
|
||||||
}
|
}
|
||||||
|
rockchip->root_bus = bus;
|
||||||
|
|
||||||
pci_bus_size_bridges(bus);
|
pci_bus_size_bridges(bus);
|
||||||
pci_bus_assign_resources(bus);
|
pci_bus_assign_resources(bus);
|
||||||
|
@ -1397,7 +1409,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
|
||||||
pcie_bus_configure_settings(child);
|
pcie_bus_configure_settings(child);
|
||||||
|
|
||||||
pci_bus_add_devices(bus);
|
pci_bus_add_devices(bus);
|
||||||
return err;
|
return 0;
|
||||||
|
|
||||||
err_free_res:
|
err_free_res:
|
||||||
pci_free_resource_list(&res);
|
pci_free_resource_list(&res);
|
||||||
|
@ -1420,6 +1432,34 @@ err_aclk_pcie:
|
||||||
return err;
|
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 = {
|
static const struct dev_pm_ops rockchip_pcie_pm_ops = {
|
||||||
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(rockchip_pcie_suspend_noirq,
|
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(rockchip_pcie_suspend_noirq,
|
||||||
rockchip_pcie_resume_noirq)
|
rockchip_pcie_resume_noirq)
|
||||||
|
@ -1429,6 +1469,7 @@ static const struct of_device_id rockchip_pcie_of_match[] = {
|
||||||
{ .compatible = "rockchip,rk3399-pcie", },
|
{ .compatible = "rockchip,rk3399-pcie", },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, rockchip_pcie_of_match);
|
||||||
|
|
||||||
static struct platform_driver rockchip_pcie_driver = {
|
static struct platform_driver rockchip_pcie_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
|
@ -1437,6 +1478,10 @@ static struct platform_driver rockchip_pcie_driver = {
|
||||||
.pm = &rockchip_pcie_pm_ops,
|
.pm = &rockchip_pcie_pm_ops,
|
||||||
},
|
},
|
||||||
.probe = rockchip_pcie_probe,
|
.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");
|
||||||
|
|
|
@ -3383,6 +3383,7 @@ int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(pci_remap_iospace);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pci_unmap_iospace - Unmap the memory mapped I/O space
|
* 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));
|
unmap_kernel_range(vaddr, resource_size(res));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(pci_unmap_iospace);
|
||||||
|
|
||||||
static void __pci_set_master(struct pci_dev *dev, bool enable)
|
static void __pci_set_master(struct pci_dev *dev, bool enable)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue