aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2018-05-23 13:41:37 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-06-01 07:24:51 -0400
commit12de0a35c996c3a75d050bff748815db3432849c (patch)
tree3009c2b100d6cbc0ade131c531bbd52fed455430
parent36b6857932f380fcb55c31ac75857e3e81dd583a (diff)
xhci: Add quirk to zero 64bit registers on Renesas PCIe controllers
Some Renesas controllers get into a weird state if they are reset while programmed with 64bit addresses (they will preserve the top half of the address in internal, non visible registers). You end up with half the address coming from the kernel, and the other half coming from the firmware. Also, changing the programming leads to extra accesses even if the controller is supposed to be halted. The controller ends up with a fatal fault, and is then ripe for being properly reset. On the flip side, this is completely unsafe if the defvice isn't behind an IOMMU, so we have to make sure that this is the case. Can you say "broken"? This is an alternative method to the one introduced in 8466489ef5ba ("xhci: Reset Renesas uPD72020x USB controller for 32-bit DMA issue"), which will subsequently be removed. Tested-by: Domenico Andreoli <domenico.andreoli@linux.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Tested-by: Faiz Abbas <faiz_abbas@ti.com> Tested-by: Domenico Andreoli <domenico.andreoli@linux.com> Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/host/xhci-pci.c8
-rw-r--r--drivers/usb/host/xhci.c65
-rw-r--r--drivers/usb/host/xhci.h1
3 files changed, 72 insertions, 2 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 85ffda85f8ab..e0a0a12871e2 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -196,11 +196,15 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
196 xhci->quirks |= XHCI_BROKEN_STREAMS; 196 xhci->quirks |= XHCI_BROKEN_STREAMS;
197 } 197 }
198 if (pdev->vendor == PCI_VENDOR_ID_RENESAS && 198 if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
199 pdev->device == 0x0014) 199 pdev->device == 0x0014) {
200 xhci->quirks |= XHCI_TRUST_TX_LENGTH; 200 xhci->quirks |= XHCI_TRUST_TX_LENGTH;
201 xhci->quirks |= XHCI_ZERO_64B_REGS;
202 }
201 if (pdev->vendor == PCI_VENDOR_ID_RENESAS && 203 if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
202 pdev->device == 0x0015) 204 pdev->device == 0x0015) {
203 xhci->quirks |= XHCI_RESET_ON_RESUME; 205 xhci->quirks |= XHCI_RESET_ON_RESUME;
206 xhci->quirks |= XHCI_ZERO_64B_REGS;
207 }
204 if (pdev->vendor == PCI_VENDOR_ID_VIA) 208 if (pdev->vendor == PCI_VENDOR_ID_VIA)
205 xhci->quirks |= XHCI_RESET_ON_RESUME; 209 xhci->quirks |= XHCI_RESET_ON_RESUME;
206 210
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 02b5ea790a90..8c8da2d657fa 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -209,6 +209,68 @@ int xhci_reset(struct xhci_hcd *xhci)
209 return ret; 209 return ret;
210} 210}
211 211
212static void xhci_zero_64b_regs(struct xhci_hcd *xhci)
213{
214 struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
215 int err, i;
216 u64 val;
217
218 /*
219 * Some Renesas controllers get into a weird state if they are
220 * reset while programmed with 64bit addresses (they will preserve
221 * the top half of the address in internal, non visible
222 * registers). You end up with half the address coming from the
223 * kernel, and the other half coming from the firmware. Also,
224 * changing the programming leads to extra accesses even if the
225 * controller is supposed to be halted. The controller ends up with
226 * a fatal fault, and is then ripe for being properly reset.
227 *
228 * Special care is taken to only apply this if the device is behind
229 * an iommu. Doing anything when there is no iommu is definitely
230 * unsafe...
231 */
232 if (!(xhci->quirks & XHCI_ZERO_64B_REGS) || !dev->iommu_group)
233 return;
234
235 xhci_info(xhci, "Zeroing 64bit base registers, expecting fault\n");
236
237 /* Clear HSEIE so that faults do not get signaled */
238 val = readl(&xhci->op_regs->command);
239 val &= ~CMD_HSEIE;
240 writel(val, &xhci->op_regs->command);
241
242 /* Clear HSE (aka FATAL) */
243 val = readl(&xhci->op_regs->status);
244 val |= STS_FATAL;
245 writel(val, &xhci->op_regs->status);
246
247 /* Now zero the registers, and brace for impact */
248 val = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr);
249 if (upper_32_bits(val))
250 xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr);
251 val = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
252 if (upper_32_bits(val))
253 xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring);
254
255 for (i = 0; i < HCS_MAX_INTRS(xhci->hcs_params1); i++) {
256 struct xhci_intr_reg __iomem *ir;
257
258 ir = &xhci->run_regs->ir_set[i];
259 val = xhci_read_64(xhci, &ir->erst_base);
260 if (upper_32_bits(val))
261 xhci_write_64(xhci, 0, &ir->erst_base);
262 val= xhci_read_64(xhci, &ir->erst_dequeue);
263 if (upper_32_bits(val))
264 xhci_write_64(xhci, 0, &ir->erst_dequeue);
265 }
266
267 /* Wait for the fault to appear. It will be cleared on reset */
268 err = xhci_handshake(&xhci->op_regs->status,
269 STS_FATAL, STS_FATAL,
270 XHCI_MAX_HALT_USEC);
271 if (!err)
272 xhci_info(xhci, "Fault detected\n");
273}
212 274
213#ifdef CONFIG_USB_PCI 275#ifdef CONFIG_USB_PCI
214/* 276/*
@@ -1006,6 +1068,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
1006 1068
1007 xhci_dbg(xhci, "Stop HCD\n"); 1069 xhci_dbg(xhci, "Stop HCD\n");
1008 xhci_halt(xhci); 1070 xhci_halt(xhci);
1071 xhci_zero_64b_regs(xhci);
1009 xhci_reset(xhci); 1072 xhci_reset(xhci);
1010 spin_unlock_irq(&xhci->lock); 1073 spin_unlock_irq(&xhci->lock);
1011 xhci_cleanup_msix(xhci); 1074 xhci_cleanup_msix(xhci);
@@ -4917,6 +4980,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
4917 if (retval) 4980 if (retval)
4918 return retval; 4981 return retval;
4919 4982
4983 xhci_zero_64b_regs(xhci);
4984
4920 xhci_dbg(xhci, "Resetting HCD\n"); 4985 xhci_dbg(xhci, "Resetting HCD\n");
4921 /* Reset the internal HC memory state and registers. */ 4986 /* Reset the internal HC memory state and registers. */
4922 retval = xhci_reset(xhci); 4987 retval = xhci_reset(xhci);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 2303ee4307af..939e2f86b595 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1841,6 +1841,7 @@ struct xhci_hcd {
1841#define XHCI_HW_LPM_DISABLE BIT_ULL(29) 1841#define XHCI_HW_LPM_DISABLE BIT_ULL(29)
1842#define XHCI_SUSPEND_DELAY BIT_ULL(30) 1842#define XHCI_SUSPEND_DELAY BIT_ULL(30)
1843#define XHCI_INTEL_USB_ROLE_SW BIT_ULL(31) 1843#define XHCI_INTEL_USB_ROLE_SW BIT_ULL(31)
1844#define XHCI_ZERO_64B_REGS BIT_ULL(32)
1844 1845
1845 unsigned int num_active_eps; 1846 unsigned int num_active_eps;
1846 unsigned int limit_active_eps; 1847 unsigned int limit_active_eps;