[PATCH v2] PCI: designware: move remaining rc setup code to dw_pcie_setup_rc()
From: Gabriele Paoloni <hidden>
Date: 2016-04-06 14:50:42
Also in:
linux-pci, lkml
Hi, sorry to be late on this
-----Original Message----- From: linux-kernel-owner at vger.kernel.org [mailto:linux-kernel- owner at vger.kernel.org] On Behalf Of Jisheng Zhang Sent: 16 March 2016 11:41 To: jingoohan1 at gmail.com; pratyush.anand at gmail.com; bhelgaas at google.com Cc: linux-pci at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm- kernel at lists.infradead.org; Jisheng Zhang Subject: [PATCH v2] PCI: designware: move remaining rc setup code to dw_pcie_setup_rc() dw_pcie_setup_rc(), as its name indicates, setups the RC. But current dw_pcie_host_init() also contains some necessary rc setup code. Another reason: the host may lost power during suspend to ram, the RC need to be re-setup after resume. The rc can't be correctly resumed without the rc setup code in dw_pcie_host_init(). So this patch moves the code to dw_pcie_setup_rc() to address the above two issues. After this patch, each pcie designware driver users could call dw_pcie_setup_rc() to re-setup rc when resume back.
I think this patch breaks the Hisilicon driver... Our driver performs linkup setup in UEFI therefore we do not call dw_pcie_setup_rc(), we only call dw_pcie_host_init(). Maybe better to group the part of code to be moved in as separate function... Thanks and sorry for late reply. Gab
quoted hunk ↗ jump to hunk
Signed-off-by: Jisheng Zhang <redacted> --- Since v1: - fix gcc warning found by lkp, thanks drivers/pci/host/pcie-designware.c | 39 +++++++++++++++++++----------- -------- 1 file changed, 19 insertions(+), 20 deletions(-)diff --git a/drivers/pci/host/pcie-designware.cb/drivers/pci/host/pcie-designware.c index a4cccd3..261e4a11 100644--- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c@@ -434,7 +434,6 @@ int dw_pcie_host_init(struct pcie_port *pp) struct platform_device *pdev = to_platform_device(pp->dev); struct pci_bus *bus, *child; struct resource *cfg_res; - u32 val; int i, ret; LIST_HEAD(res); struct resource_entry *win;@@ -544,25 +543,6 @@ int dw_pcie_host_init(struct pcie_port *pp) if (pp->ops->host_init) pp->ops->host_init(pp); - /* - * If the platform provides ->rd_other_conf, it means theplatform - * uses its own address translation component rather than ATU, so - * we should not program the ATU here. - */ - if (!pp->ops->rd_other_conf) - dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, - PCIE_ATU_TYPE_MEM, pp->mem_base, - pp->mem_bus_addr, pp->mem_size); - - dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); - - /* program correct class for RC */ - dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI); - - dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val); - val |= PORT_LOGIC_SPEED_CHANGE; - dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val); - pp->root_bus_nr = pp->busn->start; if (IS_ENABLED(CONFIG_PCI_MSI)) { bus = pci_scan_root_bus_msi(pp->dev, pp->root_bus_nr,@@ -800,6 +780,25 @@ void dw_pcie_setup_rc(struct pcie_port *pp) val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR; dw_pcie_writel_rc(pp, val, PCI_COMMAND); + + /* + * If the platform provides ->rd_other_conf, it means theplatform + * uses its own address translation component rather than ATU, so + * we should not program the ATU here. + */ + if (!pp->ops->rd_other_conf) + dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, + PCIE_ATU_TYPE_MEM, pp->mem_base, + pp->mem_bus_addr, pp->mem_size); + + dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); + + /* program correct class for RC */ + dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI); + + dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val); + val |= PORT_LOGIC_SPEED_CHANGE; + dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val); } MODULE_AUTHOR("Jingoo Han [off-list ref]"); -- 2.7.0