So far we've been content with passing physical addresses when
configuring memory addresses into XHCI controllers, but not all
platforms have buses with transparent mappings. Specifically the
Raspberry Pi 4 might introduce an offset to memory accesses incoming
from its PCIe port.
Introduce xhci_virt_to_bus() and xhci_bus_to_virt() to cater with these
limitations, and make sure we don't break non DM users.
Signed-off-by: Nicolas Saenz Julienne
Reviewed-by: Simon Glass
Reviewed-by: Stefan Roese
---
Changes since v4:
- Introduce macro to access ctrl->dev
- No need to make code conditional on DM_DMA with new macros
Changes since v3:
- Don't call phys_to_bus()/bus_to_phys(), we only support DM
drivers/usb/host/xhci-mem.c | 45 +++-
drivers/usb/host/xhci-ring.c | 11 +
drivers/usb/host/xhci.c | 4 ++--
include/usb/xhci.h | 20 +++-
4 files changed, 52 insertions(+), 28 deletions(-)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index b002d6f166..83147d51b5 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -110,7 +110,7 @@ static void xhci_scratchpad_free(struct xhci_ctrl *ctrl)
ctrl->dcbaa->dev_context_ptrs[0] = 0;
- free((void *)(uintptr_t)le64_to_cpu(ctrl->scratchpad->sp_array[0]));
+ free(xhci_bus_to_virt(ctrl,
le64_to_cpu(ctrl->scratchpad->sp_array[0])));
free(ctrl->scratchpad->sp_array);
free(ctrl->scratchpad);
ctrl->scratchpad = NULL;
@@ -216,8 +216,8 @@ static void *xhci_malloc(unsigned int size)
* @param link_trbsflag to indicate whether to link the trbs or NOT
* @return none
*/
-static void xhci_link_segments(struct xhci_segment *prev,
- struct xhci_segment *next, bool link_trbs)
+static void xhci_link_segments(struct xhci_ctrl *ctrl, struct xhci_segment
*prev,
+ struct xhci_segment *next, bool link_trbs)
{
u32 val;
u64 val_64 = 0;
@@ -226,7 +226,7 @@ static void xhci_link_segments(struct xhci_segment *prev,
return;
prev->next = next;
if (link_trbs) {
- val_64 = virt_to_phys(next->trbs);
+ val_64 = xhci_virt_to_bus(ctrl, next->trbs);
prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
cpu_to_le64(val_64);
@@ -304,7 +304,8 @@ static struct xhci_segment *xhci_segment_alloc(void)
* @param link_trbsflag to indicate whether to link the trbs or NOT
* @return pointer to the newly created RING
*/
-struct xhci_ring *xhci_ring_alloc(unsigned int num_segs, bool link_trbs)
+struct xhci_ring *xhci_ring_alloc(struct xhci_ctrl *ctrl, unsigned int
num_segs,
+ bool link_trbs)
{
struct xhci_ring *ring;
struct xhci_segment *prev;
@@ -327,12 +328,12 @@ struct xhci_ring *xhci_ring_alloc(unsigned int num_segs,
bool link_trbs)
next = xhci_segment_alloc();
BUG_ON(!next);
- xhci_link_segments(prev, next, link_trbs);
+ xhci_link_segments(ctrl, prev, next, link_trbs);
prev = next;
num_segs--;
}
- xhci_link_segments(prev, ring->first_seg, link_trbs);
+ xhci_link_segments(ctrl, prev, ring->first_seg, link_trbs);
if (link_trbs) {
/* See section 4.9.2.1 and 6.4.4.1 */
prev->trbs[TRBS_PER_SEGMENT-1].link.control |=
@@ -354,6 +355,7 @@ static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl)
struct xhci_hccr *hccr = ctrl->hccr;
struct xhci_hcor *hcor = ctrl->hcor;
struct xhci_scratchpad *scratchpad;
+ uint64_t val_64;
int num_sp;
uint32_t page_size;
void *buf;
@@ -371,8 +373,9 @@ static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl)
scratchpad->sp_array = xhci_malloc(num_sp * sizeof(u64));
if (!scratchpad->sp_array)
goto fail_sp2;
- ctrl->dcbaa->dev_context_ptrs[0] =
- cpu_to_le64((uintptr_t)scratchpad->sp_array);
+
+ val_64 = xhci_virt_to_bus(ctrl, scratchpad->sp_array);
+ ctrl->dcbaa->dev_context_ptrs[0] = cpu_to_le64(val_64);
xhci_flush_cache((uintptr_t)&ctrl->dcbaa->dev_context_ptrs[0],
sizeof(ctrl->dcbaa->dev_context_ptrs[0]));
@@ -393,8 +396,8 @@ static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl)
xhci_flush_cache((uintptr_t)buf, num_sp * page_size);
for (i = 0; i < num_sp; i++) {
- uintptr_t ptr = (uintptr_t)buf + i * page_size;
- scratchpad->sp_array[i] = cpu_to_le64(ptr);
+ val_64 = xhci_virt_to_bus(ctrl, buf + i * page_size);
+ scratchpad->sp_array[i] = cpu_to_le64(val_64);
}
xhci_flush_cache((uintptr_t)scratchpad->sp_array,
@@ -484,9 +487,9 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned
int sl