From e636c8d336489bf3eed5878299e6cc045bbad077 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 20 Feb 2024 01:17:29 +0000
Subject: [PATCH] debug lk
---
kernel/drivers/pci/controller/pcie-rockchip-host.c | 249 +++++++++++++++++--------------------------------
1 files changed, 87 insertions(+), 162 deletions(-)
diff --git a/kernel/drivers/pci/controller/pcie-rockchip-host.c b/kernel/drivers/pci/controller/pcie-rockchip-host.c
index 9490727..b461bc6 100644
--- a/kernel/drivers/pci/controller/pcie-rockchip-host.c
+++ b/kernel/drivers/pci/controller/pcie-rockchip-host.c
@@ -102,16 +102,13 @@
static int rockchip_pcie_valid_device(struct rockchip_pcie *rockchip,
struct pci_bus *bus, int dev)
{
- /* access only one slot on each root port */
- if (bus->number == rockchip->root_bus_nr && dev > 0)
- return 0;
-
/*
- * do not read more than one device on the bus directly attached
+ * Access only one slot on each root port.
+ * Do not read more than one device on the bus directly attached
* to RC's downstream side.
*/
- if (bus->primary == rockchip->root_bus_nr && dev > 0)
- return 0;
+ if (pci_is_root_bus(bus) || pci_is_root_bus(bus->parent))
+ return dev == 0;
return 1;
}
@@ -204,7 +201,7 @@
return PCIBIOS_BAD_REGISTER_NUMBER;
}
- if (bus->parent->number == rockchip->root_bus_nr)
+ if (pci_is_root_bus(bus->parent))
rockchip_pcie_cfg_configuration_accesses(rockchip,
AXI_WRAPPER_TYPE0_CFG);
else
@@ -238,7 +235,7 @@
if (!IS_ALIGNED(busdev, size))
return PCIBIOS_BAD_REGISTER_NUMBER;
- if (bus->parent->number == rockchip->root_bus_nr)
+ if (pci_is_root_bus(bus->parent))
rockchip_pcie_cfg_configuration_accesses(rockchip,
AXI_WRAPPER_TYPE0_CFG);
else
@@ -267,7 +264,7 @@
return PCIBIOS_DEVICE_NOT_FOUND;
}
- if (bus->number == rockchip->root_bus_nr)
+ if (pci_is_root_bus(bus))
return rockchip_pcie_rd_own_conf(rockchip, where, size, val);
return rockchip_pcie_rd_other_conf(rockchip, bus, devfn, where, size,
@@ -282,7 +279,7 @@
if (!rockchip_pcie_valid_device(rockchip, bus, PCI_SLOT(devfn)))
return PCIBIOS_DEVICE_NOT_FOUND;
- if (bus->number == rockchip->root_bus_nr)
+ if (pci_is_root_bus(bus))
return rockchip_pcie_wr_own_conf(rockchip, where, size, val);
return rockchip_pcie_wr_other_conf(rockchip, bus, devfn, where, size,
@@ -444,6 +441,11 @@
status &= ~PCIE_RC_CONFIG_LINK_CAP_L0S;
rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LINK_CAP);
}
+
+ status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DCSR);
+ status &= ~PCIE_RC_CONFIG_DCSR_MPS_MASK;
+ status |= PCIE_RC_CONFIG_DCSR_MPS_256;
+ rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DCSR);
return 0;
err_power_off_phy:
@@ -632,10 +634,8 @@
struct platform_device *pdev = to_platform_device(dev);
irq = platform_get_irq_byname(pdev, "sys");
- if (irq < 0) {
- dev_err(dev, "missing sys IRQ resource\n");
+ if (irq < 0)
return irq;
- }
err = devm_request_irq(dev, irq, rockchip_pcie_subsys_irq_handler,
IRQF_SHARED, "pcie-sys", rockchip);
@@ -645,20 +645,16 @@
}
irq = platform_get_irq_byname(pdev, "legacy");
- if (irq < 0) {
- dev_err(dev, "missing legacy IRQ resource\n");
+ if (irq < 0)
return irq;
- }
irq_set_chained_handler_and_data(irq,
rockchip_pcie_legacy_int_handler,
rockchip);
irq = platform_get_irq_byname(pdev, "client");
- if (irq < 0) {
- dev_err(dev, "missing client IRQ resource\n");
+ if (irq < 0)
return irq;
- }
err = devm_request_irq(dev, irq, rockchip_pcie_client_irq_handler,
IRQF_SHARED, "pcie-client", rockchip);
@@ -685,10 +681,6 @@
if (err)
return err;
- err = rockchip_pcie_setup_irq(rockchip);
- if (err)
- return err;
-
rockchip->vpcie12v = devm_regulator_get_optional(dev, "vpcie12v");
if (IS_ERR(rockchip->vpcie12v)) {
if (PTR_ERR(rockchip->vpcie12v) != -ENODEV)
@@ -703,19 +695,13 @@
dev_info(dev, "no vpcie3v3 regulator found\n");
}
- rockchip->vpcie1v8 = devm_regulator_get_optional(dev, "vpcie1v8");
- if (IS_ERR(rockchip->vpcie1v8)) {
- if (PTR_ERR(rockchip->vpcie1v8) != -ENODEV)
- return PTR_ERR(rockchip->vpcie1v8);
- dev_info(dev, "no vpcie1v8 regulator found\n");
- }
+ rockchip->vpcie1v8 = devm_regulator_get(dev, "vpcie1v8");
+ if (IS_ERR(rockchip->vpcie1v8))
+ return PTR_ERR(rockchip->vpcie1v8);
- rockchip->vpcie0v9 = devm_regulator_get_optional(dev, "vpcie0v9");
- if (IS_ERR(rockchip->vpcie0v9)) {
- if (PTR_ERR(rockchip->vpcie0v9) != -ENODEV)
- return PTR_ERR(rockchip->vpcie0v9);
- dev_info(dev, "no vpcie0v9 regulator found\n");
- }
+ rockchip->vpcie0v9 = devm_regulator_get(dev, "vpcie0v9");
+ if (IS_ERR(rockchip->vpcie0v9))
+ return PTR_ERR(rockchip->vpcie0v9);
return 0;
}
@@ -741,27 +727,22 @@
}
}
- if (!IS_ERR(rockchip->vpcie1v8)) {
- err = regulator_enable(rockchip->vpcie1v8);
- if (err) {
- dev_err(dev, "fail to enable vpcie1v8 regulator\n");
- goto err_disable_3v3;
- }
+ err = regulator_enable(rockchip->vpcie1v8);
+ if (err) {
+ dev_err(dev, "fail to enable vpcie1v8 regulator\n");
+ goto err_disable_3v3;
}
- if (!IS_ERR(rockchip->vpcie0v9)) {
- err = regulator_enable(rockchip->vpcie0v9);
- if (err) {
- dev_err(dev, "fail to enable vpcie0v9 regulator\n");
- goto err_disable_1v8;
- }
+ err = regulator_enable(rockchip->vpcie0v9);
+ if (err) {
+ dev_err(dev, "fail to enable vpcie0v9 regulator\n");
+ goto err_disable_1v8;
}
return 0;
err_disable_1v8:
- if (!IS_ERR(rockchip->vpcie1v8))
- regulator_disable(rockchip->vpcie1v8);
+ regulator_disable(rockchip->vpcie1v8);
err_disable_3v3:
if (!IS_ERR(rockchip->vpcie3v3))
regulator_disable(rockchip->vpcie3v3);
@@ -809,6 +790,7 @@
rockchip->irq_domain = irq_domain_add_linear(intc, PCI_NUM_INTX,
&intx_domain_ops, rockchip);
+ of_node_put(intc);
if (!rockchip->irq_domain) {
dev_err(dev, "failed to get a INTx IRQ domain\n");
return -EINVAL;
@@ -890,19 +872,28 @@
static int rockchip_pcie_cfg_atu(struct rockchip_pcie *rockchip)
{
struct device *dev = rockchip->dev;
+ struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rockchip);
+ struct resource_entry *entry;
+ u64 pci_addr, size;
int offset;
int err;
int reg_no;
rockchip_pcie_cfg_configuration_accesses(rockchip,
AXI_WRAPPER_TYPE0_CFG);
+ entry = resource_list_first_type(&bridge->windows, IORESOURCE_MEM);
+ if (!entry)
+ return -ENODEV;
- for (reg_no = 0; reg_no < (rockchip->mem_size >> 20); reg_no++) {
+ size = resource_size(entry->res);
+ pci_addr = entry->res->start - entry->offset;
+ rockchip->msg_bus_addr = pci_addr;
+
+ for (reg_no = 0; reg_no < (size >> 20); reg_no++) {
err = rockchip_pcie_prog_ob_atu(rockchip, reg_no + 1,
AXI_WRAPPER_MEM_WRITE,
20 - 1,
- rockchip->mem_bus_addr +
- (reg_no << 20),
+ pci_addr + (reg_no << 20),
0);
if (err) {
dev_err(dev, "program RC mem outbound ATU failed\n");
@@ -922,14 +913,22 @@
return err;
}
- offset = rockchip->mem_size >> 20;
- for (reg_no = 0; reg_no < (rockchip->io_size >> 20); reg_no++) {
+ entry = resource_list_first_type(&bridge->windows, IORESOURCE_IO);
+ if (!entry)
+ return -ENODEV;
+
+ /* store the register number offset to program RC io outbound ATU */
+ offset = size >> 20;
+
+ size = resource_size(entry->res);
+ pci_addr = entry->res->start - entry->offset;
+
+ for (reg_no = 0; reg_no < (size >> 20); reg_no++) {
err = rockchip_pcie_prog_ob_atu(rockchip,
reg_no + 1 + offset,
AXI_WRAPPER_IO_WRITE,
20 - 1,
- rockchip->io_bus_addr +
- (reg_no << 20),
+ pci_addr + (reg_no << 20),
0);
if (err) {
dev_err(dev, "program RC io outbound ATU failed\n");
@@ -942,13 +941,10 @@
AXI_WRAPPER_NOR_MSG,
20 - 1, 0, 0);
- rockchip->msg_bus_addr = rockchip->mem_bus_addr +
- ((reg_no + offset) << 20);
-
+ rockchip->msg_bus_addr += ((reg_no + offset) << 20);
rockchip->msg_region = devm_ioremap(dev, rockchip->msg_bus_addr, SZ_1M);
if (!rockchip->msg_region)
err = -ENOMEM;
-
return err;
}
@@ -1031,8 +1027,7 @@
rockchip_pcie_disable_clocks(rockchip);
- if (!IS_ERR(rockchip->vpcie0v9))
- regulator_disable(rockchip->vpcie0v9);
+ regulator_disable(rockchip->vpcie0v9);
return ret;
}
@@ -1042,12 +1037,10 @@
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
int err;
- if (!IS_ERR(rockchip->vpcie0v9)) {
- err = regulator_enable(rockchip->vpcie0v9);
- if (err) {
- dev_err(dev, "fail to enable vpcie0v9 regulator\n");
- return err;
- }
+ err = regulator_enable(rockchip->vpcie0v9);
+ if (err) {
+ dev_err(dev, "fail to enable vpcie0v9 regulator\n");
+ return err;
}
err = rockchip_pcie_enable_clocks(rockchip);
@@ -1056,22 +1049,28 @@
if (!rockchip->dma_trx_enabled)
err = rockchip_pcie_resume_for_user(dev);
+ if (err)
+ goto err_disable_clocks;
- return err;
+ return 0;
+err_disable_clocks:
+ rockchip_pcie_disable_clocks(rockchip);
err_disable_0v9:
- if (!IS_ERR(rockchip->vpcie0v9))
- regulator_disable(rockchip->vpcie0v9);
+ regulator_disable(rockchip->vpcie0v9);
+
return err;
}
static int rockchip_pcie_really_probe(struct rockchip_pcie *rockchip)
{
int err;
- struct pci_bus *bus, *child;
- struct device *dev = rockchip->dev;
err = rockchip_pcie_host_init_port(rockchip);
+ if (err)
+ return err;
+
+ err = rockchip_pcie_setup_irq(rockchip);
if (err)
return err;
@@ -1081,31 +1080,12 @@
if (err)
return err;
- list_splice_init(&rockchip->resources, &rockchip->bridge->windows);
- rockchip->bridge->dev.parent = dev;
rockchip->bridge->sysdata = rockchip;
- rockchip->bridge->busnr = 0;
rockchip->bridge->ops = &rockchip_pcie_ops;
- rockchip->bridge->map_irq = of_irq_parse_and_map_pci;
- rockchip->bridge->swizzle_irq = pci_common_swizzle;
- err = pci_scan_root_bus_bridge(rockchip->bridge);
- if (err < 0)
- return err;
-
- bus = rockchip->bridge->bus;
-
- rockchip->root_bus = bus;
-
- pci_bus_size_bridges(bus);
- pci_bus_assign_resources(bus);
- list_for_each_entry(child, &bus->children, node)
- pcie_bus_configure_settings(child);
-
- pci_bus_add_devices(bus);
device_init_wakeup(rockchip->dev, true);
- return 0;
+ return pci_host_probe(rockchip->bridge);
}
static ssize_t pcie_deferred_store(struct device *dev,
@@ -1171,12 +1151,8 @@
static int rockchip_pcie_probe(struct platform_device *pdev)
{
struct rockchip_pcie *rockchip;
- struct pci_host_bridge *bridge;
struct device *dev = &pdev->dev;
- struct resource_entry *win;
- resource_size_t io_base;
- struct resource *mem;
- struct resource *io;
+ struct pci_host_bridge *bridge;
int err;
if (!dev->of_node)
@@ -1212,58 +1188,17 @@
if (err < 0)
goto err_vpcie;
- INIT_LIST_HEAD(&rockchip->resources);
-
- err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
- &rockchip->resources, &io_base);
- if (err)
- goto err_remove_irq_domain;
-
- err = devm_request_pci_bus_resources(dev, &rockchip->resources);
- if (err)
- goto err_free_res;
-
- /* Get the I/O and memory ranges from DT */
- resource_list_for_each_entry(win, &rockchip->resources) {
- switch (resource_type(win->res)) {
- case IORESOURCE_IO:
- io = win->res;
- io->name = "I/O";
- rockchip->io_size = resource_size(io);
- rockchip->io_bus_addr = io->start - win->offset;
- err = pci_remap_iospace(io, io_base);
- if (err) {
- dev_warn(dev, "error %d: failed to map resource %pR\n",
- err, io);
- continue;
- }
- rockchip->io = io;
- break;
- case IORESOURCE_MEM:
- mem = win->res;
- mem->name = "MEM";
- rockchip->mem_size = resource_size(mem);
- rockchip->mem_bus_addr = mem->start - win->offset;
- break;
- case IORESOURCE_BUS:
- rockchip->root_bus_nr = win->res->start;
- break;
- default:
- continue;
- }
- }
-
if (rockchip->deferred) {
err = sysfs_create_group(&pdev->dev.kobj, &pcie_attr_group);
if (err) {
dev_err(&pdev->dev, "SysFS group creation failed\n");
- goto err_unmap_iospace;
+ goto err_remove_irq_domain;
}
} else {
err = rockchip_pcie_really_probe(rockchip);
if (err) {
dev_err(&pdev->dev, "deferred probe failed\n");
- goto err_probe_dma;
+ goto err_deinit_port;
}
}
@@ -1274,7 +1209,7 @@
if (IS_ERR(rockchip->dma_obj)) {
dev_err(dev, "failed to prepare dma object\n");
err = -EINVAL;
- goto err_probe_dma;
+ goto err_deinit_port;
}
if (rockchip->dma_obj) {
@@ -1284,13 +1219,10 @@
return 0;
-err_probe_dma:
+err_deinit_port:
+ rockchip_pcie_deinit_phys(rockchip);
if (rockchip->deferred)
sysfs_remove_group(&pdev->dev.kobj, &pcie_attr_group);
-err_unmap_iospace:
- pci_unmap_iospace(rockchip->io);
-err_free_res:
- pci_free_resource_list(&rockchip->resources);
err_remove_irq_domain:
irq_domain_remove(rockchip->irq_domain);
err_vpcie:
@@ -1298,10 +1230,8 @@
regulator_disable(rockchip->vpcie12v);
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);
+ regulator_disable(rockchip->vpcie1v8);
+ regulator_disable(rockchip->vpcie0v9);
err_set_vpcie:
rockchip_pcie_disable_clocks(rockchip);
return err;
@@ -1313,6 +1243,7 @@
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
u32 status1, status2;
u32 status;
+ struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rockchip);
status1 = rockchip_pcie_read(rockchip, PCIE_CLIENT_BASIC_STATUS1);
status2 = rockchip_pcie_read(rockchip, PCIE_CLIENT_DEBUG_OUT_0);
@@ -1320,12 +1251,8 @@
if (!PCIE_LINK_UP(status1) || !PCIE_LINK_IS_L0(status2))
rockchip->in_remove = 1;
- if (rockchip->root_bus) {
- pci_stop_root_bus(rockchip->root_bus);
- pci_remove_root_bus(rockchip->root_bus);
- }
-
- pci_unmap_iospace(rockchip->io);
+ pci_stop_root_bus(bridge->bus);
+ pci_remove_root_bus(bridge->bus);
irq_domain_remove(rockchip->irq_domain);
/* disable link state */
@@ -1353,10 +1280,8 @@
regulator_disable(rockchip->vpcie12v);
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);
+ regulator_disable(rockchip->vpcie1v8);
+ regulator_disable(rockchip->vpcie0v9);
device_init_wakeup(rockchip->dev, false);
--
Gitblit v1.6.2