public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Workaround for uPD72020x USB3 chips
@ 2017-07-10 15:52 Marc Zyngier
  2017-07-10 15:52 ` [PATCH 1/2] PCI: Implement pci_reset_function_locked Marc Zyngier
                   ` (4 more replies)
  0 siblings, 5 replies; 16+ messages in thread
From: Marc Zyngier @ 2017-07-10 15:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Mathias Nyman, Greg Kroah-Hartman
  Cc: linux-pci, linux-kernel, linux-usb, Ard Biesheuvel

Ard and myself have just spent quite some time lately trying to pin
down an issue in the DMA code which was taking the form of a PCIe USB3
controller issuing a DMA access at some bizarre address, and being
caught red-handed by the IOMMU.

After much head scratching and most of a week-end spent on tracing the
damn thing, I'm now convinced that the DMA code is fine, the XHCI
driver is correct, but that the HW (a Renesas uPD720202 chip) is a
nasty piece of work.

The issue is as follow:

- EFI initializes the controller using physical addresses above the
  4GB limit (this is on an arm64 box where the memory starts at
  0x80_00000000...).

- The kernel takes over, sends a XHCI reset to the controller, and
  because we have an IOMMU sitting between the controller and memory,
  provides *virtual* addresses. Trying to make things a bit faster for
  our controller, it issues IOVAs in the low 4GB range).

- Low and behold, the controller is now issuing transactions with a
  0x80 prefix in front of our IOVA. Yes, the same prefix that was
  programmed during the EFI configuration. IOMMU fault, not happy.

If the kernel is hacked to only generate IOVAs that are more than
32bit wide, the HW behaves correctly. The only way I can explain this
behaviour is that the HW latches the top 32bit of the ERST (it is
always the ERST IOVA that appears in my traces) in some internal
register, and that the XHCI reset fails to clear it. Writing zero in
the top bits is not enough to clear it either.

So far, the only solution we have for this lovely piece of kit is to
force a PCI reset at probe time, which puts it right. The patches are
pretty ugly, but that's the best I could come up with so far.

Tested on a pair of AMD Opteron 1100 boxes with Renesas uPD720201 and
uPD720202 controllers.

Marc Zyngier (2):
  PCI: Implement pci_reset_function_locked
  usb: host: pci_quirks: Force hard reset of Renesas uPD72020x USB
    controller

 drivers/pci/pci.c             | 35 +++++++++++++++++++++++++++++++++++
 drivers/usb/host/pci-quirks.c | 20 ++++++++++++++++++++
 drivers/usb/host/pci-quirks.h |  1 +
 drivers/usb/host/xhci-pci.c   |  7 +++++++
 include/linux/pci.h           |  1 +
 5 files changed, 64 insertions(+)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2017-08-02  1:12 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-07-10 15:52 [PATCH 0/2] Workaround for uPD72020x USB3 chips Marc Zyngier
2017-07-10 15:52 ` [PATCH 1/2] PCI: Implement pci_reset_function_locked Marc Zyngier
2017-07-10 15:52 ` [PATCH 2/2] usb: host: pci_quirks: Force hard reset of Renesas uPD72020x USB controller Marc Zyngier
2017-07-17 12:02   ` Mathias Nyman
2017-07-10 17:21 ` [PATCH 0/2] Workaround for uPD72020x USB3 chips Ard Biesheuvel
2017-07-12 19:04   ` Ard Biesheuvel
2017-07-13  3:12 ` Bjorn Helgaas
2017-07-13  6:48   ` Ard Biesheuvel
2017-07-13  7:46     ` Marc Zyngier
2017-07-13 11:36       ` Bjorn Helgaas
2017-07-13 12:18         ` Marc Zyngier
2017-07-13  8:26   ` Greg Kroah-Hartman
2017-07-13 11:37     ` Bjorn Helgaas
2017-08-01 21:44     ` Bjorn Helgaas
2017-08-01 21:53       ` Ard Biesheuvel
2017-08-02  1:12 ` Bjorn Helgaas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox