On Tue, Jul 22, 2014 at 06:52:12PM -0400, Murali Karicheri wrote:
> Bjorn,
> 
> On 07/22/2014 06:35 PM, Bjorn Helgaas wrote:
> >On Mon, Jul 21, 2014 at 12:58:44PM -0400, Murali Karicheri wrote:
> >>keystone PCIe controller is based on v3.65 version of the
> >>designware h/w. Main differences are
> >>    1. No ATU support
> >>    2. Legacy and MSI irq functions are implemented in
> >>       application register space
> >>    3. MSI interrupts are multiplexed over 8 IRQ lines to the Host
> >>       side.
> >>All of the Application register space handing code are organized into
> >>pci-keystone-dw.c and the functions are called from pci-keystone.c
> >>to implement PCI controller driver. Also add necessary DT documentation
> >>for the driver.
> >>
> >>Signed-off-by: Murali Karicheri<m-kariche...@ti.com>
> >>Acked-by: Santosh Shilimkar<santosh.shilim...@ti.com>
> >>...
> >
> >>+++ b/Documentation/devicetree/bindings/pci/pci-keystone.txt
> >>...
> >
> >>+Note for PCI driver usage
> >>+=========================
> >>+Driver requires pci=pcie_bus_perf in the bootargs for proper functioning.
> >
> >Whoa, why is this?  Special boot args should not be required.
> 
> This was discussed initially and I had added following commit to get
> this working instead of a PCI quirk. To get some background please
> see the thread for commit below that you also had signed off as
> well.

I applied 8b5742ad156d because it's something all arches should do
(actually, we *should* do it in the PCI core, but nobody's gotten
around to doing that yet).  It has nothing to do with Keystone
support, and it doesn't mean I'm in favor of a boot argument.

I think the discussion you mentioned is [1].  I see hints that there
might be a Keystone hardware defect related to MRSS, but I don't see a
clear description of it.  If you have a hardware erratum document,
those usually contain pretty good descriptions.

If there is a hardware defect, a PCI quirk is a reasonable way to work
around it, since that's the main purpose of quirks.  fixup_mpss_256()
is an example of something that sounds superficially similar.

I don't think there's a way for a device to advertise the maximum MRSS
value it supports.  MRSS only controls the maximum Read Request size
the device can generate, and I wouldn't think there's much to go wrong
there, because the request doesn't contain any data, so MRSS doesn't
affect the packet size of the *request*.

I think it's more likely that a hardware problem would affect the
*response*, where, e.g., a device might advertise (via the Device
Capabilities Max_Payload_Size_Supported field) that it can support an
MPS of 1024, but it can't actually handle a TLP that big.  Software
would have to work around that by artificially limiting the MPS to
something smaller than the MPSS advertised by the device.  This is
what fixup_mpss_256() is doing.

If there is a hardware problem with MRSS specifically, you can
probably still do a quirk, but it might also involve a little work in
the PCI core to add something similar to pcie_mpss to support the
quirk.

Bjorn

[1] 
http://lkml.kernel.org/r/1400169692-9677-6-git-send-email-m-kariche...@ti.com

> commit 8b5742ad156d30ee38486652cdbd152e2d6ebbcc
> Author: Murali Karicheri <m-kariche...@ti.com>
> Date:   Wed May 28 13:14:53 2014 -0400
> 
>     ARM/PCI: Call pcie_bus_configure_settings() to set MPS
> 
>     Call pcie_bus_configure_settings() on ARM, like for other platforms.
>     pcie_bus_configure_settings() makes sure the MPS across the bus
> is uniform
>     and provides the ability to tune the MRSS and MPS to higher performance
>     values.  This is particularly important for embedded where there is no
>     firmware to program these PCIe settings for the OS.
> 
>     Signed-off-by: Murali Karicheri <m-kariche...@ti.com>
>     Signed-off-by: Bjorn Helgaas <bhelg...@google.com>
>     CC: Russell King <li...@arm.linux.org.uk>
>     CC: Arnd Bergmann <a...@arndb.de>
>     CC: Jason Gunthorpe <jguntho...@obsidianresearch.com>
>     CC: Santosh Shilimkar <santosh.shilim...@ti.com>
> 
> This was added as a preparatory patch to support keystone and
> avoid a PCI quirk to do the same. Keystone has MRSS limitation
> of 256 bytes. So adding a bootargs flag was suggested a better
> option than a PCI quirk.
> 
> I will look into the rest of the comments and possibly try to
> address them or discuss.
> 
> BTW, please apply patch 1-3 that has already got ack from maintainers
> and is indepdent of this patch.
> 
> Thanks
> 
> Murali
> 
> >
> >>diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> >>index 21df477..f8bc475 100644
> >>--- a/drivers/pci/host/Kconfig
> >>+++ b/drivers/pci/host/Kconfig
> >>@@ -46,4 +46,9 @@ config PCI_HOST_GENERIC
> >>      Say Y here if you want to support a simple generic PCI host
> >>      controller, such as the one emulated by kvmtool.
> >>
> >>+config PCI_KEYSTONE
> >>+   bool "TI Keystone PCIe controller"
> >>+   depends on ARCH_KEYSTONE
> >>+   select PCIE_DW
> >>+   select PCIEPORTBUS
> >
> >It'd be nice to have some help text here.  I know, not everybody else does.
> >
> >>+++ b/drivers/pci/host/pci-keystone-dw.c
> >>...
> >>+void ks_dw_pcie_handle_msi_irq(struct keystone_pcie *ks_pcie , int offset)
> >>+{
> >>+   struct pcie_port *pp =&ks_pcie->pp;
> >>+   u32 pending, vector;
> >>+   int src, virq;
> >>+
> >>+   pending = readl(ks_pcie->va_app_base + MSI0_IRQ_STATUS + (offset<<  4));
> >
> >Blank line here (before the block comment).
> >
> >>+   /*
> >>+    * MSI0, Status bit 0-3 shows vectors 0, 8, 16, 24, MSI1 status bit
> >>+    * shows 1, 9, 17, 25 and so forth
> >>+    */
> >>+   for (src = 0; src<  4; src++) {
> >>+           if (BIT(src)&  pending) {
> >>+                   vector = offset + (src<<  3);
> >>+                   virq = irq_linear_revmap(pp->irq_domain, vector);
> >>+                   dev_dbg(pp->dev,
> >>+                           "irq: bit %d, vector %d, virq %d\n",
> >>+                            src, vector, virq);
> >>+                   generic_handle_irq(virq);
> >>+           }
> >>+   }
> >>+}
> >>+
> >>...
> >
> >>+static void __iomem *ks_pcie_cfg_setup(struct keystone_pcie *ks_pcie, u8 
> >>bus,
> >>+                                   unsigned int devfn)
> >>+{
> >>+   u8 device = PCI_SLOT(devfn), function = PCI_FUNC(devfn);
> >>+   struct pcie_port *pp =&ks_pcie->pp;
> >>+   u32 regval;
> >>+
> >>+   if (bus == 0)
> >>+           return pp->dbi_base;
> >>+
> >>+   regval = (bus<<  16) | (device<<  8) | function;
> >>+   /*
> >>+    * Since Bus#1 will be a virtual bus, we need to have TYPE0
> >>+    * access only.
> >>+    * TYPE 1
> >>+    */
> >>+   if (bus != 1)
> >>+           regval |= BIT(24);
> >>+
> >>+   writel(regval, ks_pcie->va_app_base + CFG_SETUP);
> >>+   return pp->va_cfg0_base;
> >>+}
> >>+
> >>+int ks_dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
> >>+           unsigned int devfn, int where, int size, u32 *val)
> >>+{
> >>+   struct keystone_pcie *ks_pcie = to_keystone_pcie(pp);
> >>+   u8 bus_num = bus->number;
> >>+   void __iomem *addr;
> >>+   int ret;
> >>+
> >>+   addr = ks_pcie_cfg_setup(ks_pcie, bus_num, devfn);
> >>+   ret = dw_pcie_cfg_read(addr + (where&  ~0x3), where, size, val);
> >
> >This *looks* like it needs a lock to protect against concurrent
> >ks_pcie_cfg_setup() users, since it writes a register.
> >
> >>+
> >>+   return ret;
> >
> >Please use the same style as in ks_dw_pcie_wr_other_conf(), i.e., get rid
> >of "ret".
> >
> >>+}
> >>+
> >>+int ks_dw_pcie_wr_other_conf(struct pcie_port *pp,
> >>+           struct pci_bus *bus, unsigned int devfn, int where,
> >>+           int size, u32 val)
> >>+{
> >>+   struct keystone_pcie *ks_pcie = to_keystone_pcie(pp);
> >>+   u8 bus_num = bus->number;
> >>+   void __iomem *addr;
> >>+
> >>+   addr = ks_pcie_cfg_setup(ks_pcie, bus_num, devfn);
> >>+
> >>+   return dw_pcie_cfg_write(addr + (where&  ~0x3), where, size, val);
> >>+}
> >
> >>+++ b/drivers/pci/host/pci-keystone.c
> >>...
> >
> >>+static struct platform_driver ks_pcie_driver __refdata = {
> >
> >Why does this need to be __refdata?  There are no other occurrences in
> >drivers/pci.
> >
> >>+   .probe  = ks_pcie_probe,
> >>+   .remove = __exit_p(ks_pcie_remove),
> >>+   .driver = {
> >>+           .name   = "keystone-pcie",
> >>+           .owner  = THIS_MODULE,
> >>+           .of_match_table = of_match_ptr(ks_pcie_of_match),
> >>+   },
> >>+};
> >
> >Bjorn
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to