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:
Коммит
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.
|
||||
|
||||
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
|
||||
|
|
|
@ -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,24 +441,25 @@ 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) {
|
||||
scale = 3; /* 0.001x */
|
||||
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;
|
||||
}
|
||||
if (curr <= 0)
|
||||
return;
|
||||
|
||||
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);
|
||||
scale = 3; /* 0.001x */
|
||||
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);
|
||||
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 */
|
||||
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 @@ err_aclk_pcie:
|
|||
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");
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче