usb: xhci: Add virt_to_phys() to support mapped platforms
Some platforms, like MIPS Octeon, use mapped addresses (virtual address
!= physical address). On these platforms we need to make sure, that the
local virtual addresses are converted to physical (DMA) addresses for
the xHCI controller. This patch adds the missing virt_to_phys() calls,
so that the correct addresses are used.
Signed-off-by: Stefan Roese <sr@denx.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Marek Vasut <marex@denx.de>
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index bf60a9c..1da0524 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -226,7 +226,7 @@
return;
prev->next = next;
if (link_trbs) {
- val_64 = (uintptr_t)next->trbs;
+ val_64 = virt_to_phys(next->trbs);
prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
cpu_to_le64(val_64);
@@ -489,7 +489,7 @@
/* Allocate endpoint 0 ring */
virt_dev->eps[0].ring = xhci_ring_alloc(1, true);
- byte_64 = (uintptr_t)(virt_dev->out_ctx->bytes);
+ byte_64 = virt_to_phys(virt_dev->out_ctx->bytes);
/* Point to output device context in dcbaa. */
ctrl->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(byte_64);
@@ -514,7 +514,7 @@
uint64_t val_64;
uint64_t trb_64;
uint32_t val;
- unsigned long deq;
+ uint64_t deq;
int i;
struct xhci_segment *seg;
@@ -526,7 +526,7 @@
return -ENOMEM;
}
- val_64 = (uintptr_t)ctrl->dcbaa;
+ val_64 = virt_to_phys(ctrl->dcbaa);
/* Set the pointer in DCBAA register */
xhci_writeq(&hcor->or_dcbaap, val_64);
@@ -534,7 +534,7 @@
ctrl->cmd_ring = xhci_ring_alloc(1, true);
/* Set the address in the Command Ring Control register */
- trb_64 = (uintptr_t)ctrl->cmd_ring->first_seg->trbs;
+ trb_64 = virt_to_phys(ctrl->cmd_ring->first_seg->trbs);
val_64 = xhci_readq(&hcor->or_crcr);
val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
(trb_64 & (u64) ~CMD_RING_RSVD_BITS) |
@@ -564,8 +564,7 @@
for (val = 0, seg = ctrl->event_ring->first_seg;
val < ERST_NUM_SEGS;
val++) {
- trb_64 = 0;
- trb_64 = (uintptr_t)seg->trbs;
+ trb_64 = virt_to_phys(seg->trbs);
struct xhci_erst_entry *entry = &ctrl->erst.entries[val];
entry->seg_addr = cpu_to_le64(trb_64);
entry->seg_size = cpu_to_le32(TRBS_PER_SEGMENT);
@@ -575,7 +574,7 @@
xhci_flush_cache((uintptr_t)ctrl->erst.entries,
ERST_NUM_SEGS * sizeof(struct xhci_erst_entry));
- deq = (unsigned long)ctrl->event_ring->dequeue;
+ deq = virt_to_phys(ctrl->event_ring->dequeue);
/* Update HC event ring dequeue pointer */
xhci_writeq(&ctrl->ir_set->erst_dequeue,
@@ -590,7 +589,7 @@
/* this is the event ring segment table pointer */
val_64 = xhci_readq(&ctrl->ir_set->erst_base);
val_64 &= ERST_PTR_MASK;
- val_64 |= ((uintptr_t)(ctrl->erst.entries) & ~ERST_PTR_MASK);
+ val_64 |= virt_to_phys(ctrl->erst.entries) & ~ERST_PTR_MASK;
xhci_writeq(&ctrl->ir_set->erst_base, val_64);
@@ -858,7 +857,7 @@
cpu_to_le32(((0 & MAX_BURST_MASK) << MAX_BURST_SHIFT) |
((3 & ERROR_COUNT_MASK) << ERROR_COUNT_SHIFT));
- trb_64 = (uintptr_t)virt_dev->eps[0].ring->first_seg->trbs;
+ trb_64 = virt_to_phys(virt_dev->eps[0].ring->first_seg->trbs);
ep0_ctx->deq = cpu_to_le64(trb_64 | virt_dev->eps[0].ring->cycle_state);
/*
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 86aeaab..092ed6e 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -275,7 +275,7 @@
u32 ep_index, trb_type cmd)
{
u32 fields[4];
- u64 val_64 = (uintptr_t)ptr;
+ u64 val_64 = virt_to_phys(ptr);
BUG_ON(prepare_ring(ctrl, ctrl->cmd_ring, EP_STATE_RUNNING));
@@ -399,7 +399,7 @@
/* Inform the hardware */
xhci_writeq(&ctrl->ir_set->erst_dequeue,
- (uintptr_t)ctrl->event_ring->dequeue | ERST_EHB);
+ virt_to_phys(ctrl->event_ring->dequeue) | ERST_EHB);
}
/**
@@ -577,7 +577,7 @@
u64 addr;
int ret;
u32 trb_fields[4];
- u64 val_64 = (uintptr_t)buffer;
+ u64 val_64 = virt_to_phys(buffer);
debug("dev=%p, pipe=%lx, buffer=%p, length=%d\n",
udev, pipe, buffer, length);
@@ -876,7 +876,7 @@
if (length > 0) {
if (req->requesttype & USB_DIR_IN)
field |= TRB_DIR_IN;
- buf_64 = (uintptr_t)buffer;
+ buf_64 = virt_to_phys(buffer);
trb_fields[0] = lower_32_bits(buf_64);
trb_fields[1] = upper_32_bits(buf_64);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index f635bb3..126dabc 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -631,8 +631,7 @@
cpu_to_le32(MAX_BURST(max_burst) |
ERROR_COUNT(err_count));
- trb_64 = (uintptr_t)
- virt_dev->eps[ep_index].ring->enqueue;
+ trb_64 = virt_to_phys(virt_dev->eps[ep_index].ring->enqueue);
ep_ctx[ep_index]->deq = cpu_to_le64(trb_64 |
virt_dev->eps[ep_index].ring->cycle_state);