usb: xhci: Add virt_to_phys() to support mapped platforms 83/268183/1
authorStefan Roese <sr@denx.de>
Tue, 21 Jul 2020 08:46:05 +0000 (10:46 +0200)
committerMarek Szyprowski <m.szyprowski@samsung.com>
Thu, 16 Dec 2021 16:15:02 +0000 (17:15 +0100)
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>
[backport of mainline commit b5152a653d36c67a34b54c4c1e9eb182e7e5b9d6]
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Change-Id: If1ab9d76628c347fdd9950d7c2ad5468d34144ec

drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c

index 19fc414430da789316fb39b2864a3afc1bd04eb5..8058bf191826d5cc0fa524bd8b908aaf62fb60eb 100644 (file)
@@ -221,7 +221,7 @@ static void xhci_link_segments(struct xhci_segment *prev,
                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);
 
@@ -484,7 +484,7 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id)
        /* 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);
@@ -509,7 +509,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
        uint64_t val_64;
        uint64_t trb_64;
        uint32_t val;
-       unsigned long deq;
+       uint64_t deq;
        int i;
        struct xhci_segment *seg;
 
@@ -521,7 +521,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
                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);
 
@@ -529,7 +529,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
        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) |
@@ -559,8 +559,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
        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);
@@ -570,7 +569,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
        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,
@@ -585,7 +584,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
        /* 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);
 
@@ -853,7 +852,7 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,
                        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);
 
        /*
index 119b41848715fd4074f25319828ed35f73cb707e..480aa4a70825644ebfe137aeb75429902b162b2f 100644 (file)
@@ -272,7 +272,7 @@ void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr, u32 slot_id,
                        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));
 
@@ -396,7 +396,7 @@ void xhci_acknowledge_event(struct xhci_ctrl *ctrl)
 
        /* 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);
 }
 
 /**
@@ -574,7 +574,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
        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);
@@ -873,7 +873,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
        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);
index cc931008085af3ca4b05bc986be4249b12d8392d..71e8ea7df95d6d77d2a378412fa94ad36db0e584 100644 (file)
@@ -595,8 +595,7 @@ static int xhci_set_configuration(struct usb_device *udev)
                        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);