From patchwork Wed Apr 1 14:18:45 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Temerkhanov X-Patchwork-Id: 457265 X-Patchwork-Delegate: marek.vasut@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id BCBDB1400A0 for ; Thu, 2 Apr 2015 01:17:48 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="verification failed; unprotected key" header.d=gmail.com header.i=@gmail.com header.b=PMeDTWop; dkim-adsp=none (unprotected policy); dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D6228A7444; Wed, 1 Apr 2015 16:17:42 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6Yrl3j3b9SBw; Wed, 1 Apr 2015 16:17:42 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id DE7CCA7441; Wed, 1 Apr 2015 16:17:39 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 842604B632 for ; Wed, 1 Apr 2015 16:17:34 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id e1m4Qu0fuYYf for ; Wed, 1 Apr 2015 16:17:34 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-la0-f54.google.com (mail-la0-f54.google.com [209.85.215.54]) by theia.denx.de (Postfix) with ESMTPS id 26FBDA7422 for ; Wed, 1 Apr 2015 16:17:29 +0200 (CEST) Received: by labe2 with SMTP id e2so37777676lab.3 for ; Wed, 01 Apr 2015 07:17:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5a3uxx3S++bjZPir/m2HCOSQD/B6sZi0zDguLol6lSQ=; b=PMeDTWopTKO9W59vqPW+9QI8jCPwbz94KGhHebIyXtWh7uQCpNsuSjIUMnqKEmVL3R dyhutUIfQIoe38D2hCFwcxhITxBWQxhU5lPT4SWMhR5yHrfo9sgfyXZ97BrXICCokm5a 8FIBrLX9365dUmSMz3eBmzHpuiVz9qXDmKKG6trkANENIh0YjEMHE4202lVn1usB8ald gRVNnxzp9JoD8Z1td4trrxs06m9P+aFWTv9Xpb/sIirNVkXa7CENiRLxtc9B90TSmu+r iEaL8CxhSuqlOLrgdcsq0EA8pT3LdLe3qT7EioKpA3yIXL0DKFlnhN/TrHdmbzMengFY yMAQ== X-Received: by 10.112.122.7 with SMTP id lo7mr3821461lbb.7.1427897849181; Wed, 01 Apr 2015 07:17:29 -0700 (PDT) Received: from snickers.office.auriga.msk ([81.19.133.99]) by mx.google.com with ESMTPSA id zo8sm441709lbc.37.2015.04.01.07.17.27 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 01 Apr 2015 07:17:28 -0700 (PDT) From: Sergey Temerkhanov To: u-boot@lists.denx.de, marex@denx.de Date: Wed, 1 Apr 2015 17:18:45 +0300 Message-Id: <1427897926-2739-3-git-send-email-s.temerkhanov@gmail.com> X-Mailer: git-send-email 2.2.0 In-Reply-To: <1427897926-2739-1-git-send-email-s.temerkhanov@gmail.com> References: <1427897926-2739-1-git-send-email-s.temerkhanov@gmail.com> Cc: Radha Mohan Chintakuntla Subject: [U-Boot] [PATCH 2/3] usb: 64-bit architectures support for xHCI X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This commit allows xHCI to use both 64 and 32 bit memory physical addresses depending on architecture it's being built for. Also it makes use of readq()/writeq() on 64-bit systems Signed-off-by: Sergey Temerkhanov Signed-off-by: Radha Mohan Chintakuntla --- drivers/usb/host/xhci-mem.c | 20 ++++++++++---------- drivers/usb/host/xhci-ring.c | 30 +++++++++++++++--------------- drivers/usb/host/xhci.c | 10 +++++----- drivers/usb/host/xhci.h | 13 +++++++++++-- 4 files changed, 41 insertions(+), 32 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 89908e8..10f11cd 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -31,7 +31,7 @@ * @param len the length of the cache line to be flushed * @return none */ -void xhci_flush_cache(uint32_t addr, u32 len) +void xhci_flush_cache(uintptr_t addr, u32 len) { BUG_ON((void *)addr == NULL || len == 0); @@ -46,7 +46,7 @@ void xhci_flush_cache(uint32_t addr, u32 len) * @param len the length of the cache line to be invalidated * @return none */ -void xhci_inval_cache(uint32_t addr, u32 len) +void xhci_inval_cache(uintptr_t addr, u32 len) { BUG_ON((void *)addr == NULL || len == 0); @@ -175,7 +175,7 @@ static void *xhci_malloc(unsigned int size) BUG_ON(!ptr); memset(ptr, '\0', size); - xhci_flush_cache((uint32_t)ptr, size); + xhci_flush_cache((uintptr_t)ptr, size); return ptr; } @@ -400,8 +400,8 @@ int xhci_alloc_virt_device(struct usb_device *udev) /* Point to output device context in dcbaa. */ ctrl->dcbaa->dev_context_ptrs[slot_id] = byte_64; - xhci_flush_cache((uint32_t)&ctrl->dcbaa->dev_context_ptrs[slot_id], - sizeof(__le64)); + xhci_flush_cache((uintptr_t)&ctrl->dcbaa->dev_context_ptrs[slot_id], + sizeof(__le64)); return 0; } @@ -478,8 +478,8 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr, entry->rsvd = 0; seg = seg->next; } - xhci_flush_cache((uint32_t)ctrl->erst.entries, - ERST_NUM_SEGS * sizeof(struct xhci_erst_entry)); + xhci_flush_cache((uintptr_t)ctrl->erst.entries, + ERST_NUM_SEGS * sizeof(struct xhci_erst_entry)); deq = (unsigned long)ctrl->event_ring->dequeue; @@ -496,7 +496,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 |= ((u32)(ctrl->erst.entries) & ~ERST_PTR_MASK); + val_64 |= ((uintptr_t)(ctrl->erst.entries) & ~ERST_PTR_MASK); xhci_writeq(&ctrl->ir_set->erst_base, val_64); @@ -715,6 +715,6 @@ void xhci_setup_addressable_virt_dev(struct usb_device *udev) /* Steps 7 and 8 were done in xhci_alloc_virt_device() */ - xhci_flush_cache((uint32_t)ep0_ctx, sizeof(struct xhci_ep_ctx)); - xhci_flush_cache((uint32_t)slot_ctx, sizeof(struct xhci_slot_ctx)); + xhci_flush_cache((uintptr_t)ep0_ctx, sizeof(struct xhci_ep_ctx)); + xhci_flush_cache((uintptr_t)slot_ctx, sizeof(struct xhci_slot_ctx)); } diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index b5aade9..f3759d4 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -122,8 +122,8 @@ static void inc_enq(struct xhci_ctrl *ctrl, struct xhci_ring *ring, next->link.control |= cpu_to_le32(chain); next->link.control ^= cpu_to_le32(TRB_CYCLE); - xhci_flush_cache((uint32_t)next, - sizeof(union xhci_trb)); + xhci_flush_cache((uintptr_t)next, + sizeof(union xhci_trb)); } /* Toggle the cycle bit after the last ring segment. */ if (last_trb_on_last_seg(ctrl, ring, @@ -191,7 +191,7 @@ static struct xhci_generic_trb *queue_trb(struct xhci_ctrl *ctrl, for (i = 0; i < 4; i++) trb->field[i] = cpu_to_le32(trb_fields[i]); - xhci_flush_cache((uint32_t)trb, sizeof(struct xhci_generic_trb)); + xhci_flush_cache((uintptr_t)trb, sizeof(struct xhci_generic_trb)); inc_enq(ctrl, ring, more_trbs_coming); @@ -244,7 +244,7 @@ static int prepare_ring(struct xhci_ctrl *ctrl, struct xhci_ring *ep_ring, next->link.control ^= cpu_to_le32(TRB_CYCLE); - xhci_flush_cache((uint32_t)next, sizeof(union xhci_trb)); + xhci_flush_cache((uintptr_t)next, sizeof(union xhci_trb)); /* Toggle the cycle bit after the last ring segment. */ if (last_trb_on_last_seg(ctrl, ep_ring, @@ -364,7 +364,7 @@ static void giveback_first_trb(struct usb_device *udev, int ep_index, else start_trb->field[3] &= cpu_to_le32(~TRB_CYCLE); - xhci_flush_cache((uint32_t)start_trb, sizeof(struct xhci_generic_trb)); + xhci_flush_cache((uintptr_t)start_trb, sizeof(struct xhci_generic_trb)); /* Ringing EP doorbell here */ xhci_writel(&ctrl->dba->doorbell[udev->slot_id], @@ -403,8 +403,8 @@ static int event_ready(struct xhci_ctrl *ctrl) { union xhci_trb *event; - xhci_inval_cache((uint32_t)ctrl->event_ring->dequeue, - sizeof(union xhci_trb)); + xhci_inval_cache((uintptr_t)ctrl->event_ring->dequeue, + sizeof(union xhci_trb)); event = ctrl->event_ring->dequeue; @@ -576,8 +576,8 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, ep_index = usb_pipe_ep_index(pipe); virt_dev = ctrl->devs[slot_id]; - xhci_inval_cache((uint32_t)virt_dev->out_ctx->bytes, - virt_dev->out_ctx->size); + xhci_inval_cache((uintptr_t)virt_dev->out_ctx->bytes, + virt_dev->out_ctx->size); ep_ctx = xhci_get_ep_ctx(ctrl, virt_dev->out_ctx, ep_index); @@ -644,7 +644,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, first_trb = true; /* flush the buffer before use */ - xhci_flush_cache((uint32_t)buffer, length); + xhci_flush_cache((uintptr_t)buffer, length); /* Queue the first TRB, even if it's zero-length */ do { @@ -722,7 +722,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, record_transfer_result(udev, event, length); xhci_acknowledge_event(ctrl); - xhci_inval_cache((uint32_t)buffer, length); + xhci_inval_cache((uintptr_t)buffer, length); return (udev->status != USB_ST_NOT_PROC) ? 0 : -1; } @@ -776,8 +776,8 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, return ret; } - xhci_inval_cache((uint32_t)virt_dev->out_ctx->bytes, - virt_dev->out_ctx->size); + xhci_inval_cache((uintptr_t)virt_dev->out_ctx->bytes, + virt_dev->out_ctx->size); struct xhci_ep_ctx *ep_ctx = NULL; ep_ctx = xhci_get_ep_ctx(ctrl, virt_dev->out_ctx, ep_index); @@ -874,7 +874,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, trb_fields[2] = length_field; trb_fields[3] = field | ep_ring->cycle_state; - xhci_flush_cache((uint32_t)buffer, length); + xhci_flush_cache((uintptr_t)buffer, length); queue_trb(ctrl, ep_ring, true, trb_fields); } @@ -915,7 +915,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, /* Invalidate buffer to make it available to usb-core */ if (length > 0) - xhci_inval_cache((uint32_t)buffer, length); + xhci_inval_cache((uintptr_t)buffer, length); if (GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len)) == COMP_SHORT_TX) { diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 87f2972..f8b5ce4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -256,7 +256,7 @@ static int xhci_configure_endpoints(struct usb_device *udev, bool ctx_change) virt_dev = ctrl->devs[udev->slot_id]; in_ctx = virt_dev->in_ctx; - xhci_flush_cache((uint32_t)in_ctx->bytes, in_ctx->size); + xhci_flush_cache((uintptr_t)in_ctx->bytes, in_ctx->size); xhci_queue_command(ctrl, in_ctx->bytes, udev->slot_id, 0, ctx_change ? TRB_EVAL_CONTEXT : TRB_CONFIG_EP); event = xhci_wait_for_event(ctrl, TRB_COMPLETION); @@ -325,7 +325,7 @@ static int xhci_set_configuration(struct usb_device *udev) max_ep_flag = ep_flag; } - xhci_inval_cache((uint32_t)out_ctx->bytes, out_ctx->size); + xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size); /* slot context */ xhci_slot_copy(ctrl, in_ctx, out_ctx); @@ -442,8 +442,8 @@ static int xhci_address_device(struct usb_device *udev) */ return ret; - xhci_inval_cache((uint32_t)virt_dev->out_ctx->bytes, - virt_dev->out_ctx->size); + xhci_inval_cache((uintptr_t)virt_dev->out_ctx->bytes, + virt_dev->out_ctx->size); slot_ctx = xhci_get_slot_ctx(ctrl, virt_dev->out_ctx); debug("xHC internal address is: %d\n", @@ -525,7 +525,7 @@ int xhci_check_maxpacket(struct usb_device *udev) ifdesc = &udev->config.if_desc[0]; out_ctx = ctrl->devs[slot_id]->out_ctx; - xhci_inval_cache((uint32_t)out_ctx->bytes, out_ctx->size); + xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size); ep_ctx = xhci_get_ep_ctx(ctrl, out_ctx, ep_index); hw_max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2)); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 6685ed2..0951e87 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -17,6 +17,7 @@ #ifndef HOST_XHCI_H_ #define HOST_XHCI_H_ +#include #include #include #include @@ -1108,20 +1109,28 @@ static inline void xhci_writel(uint32_t volatile *regs, const unsigned int val) */ static inline u64 xhci_readq(__le64 volatile *regs) { +#if BITS_PER_LONG == 64 + return readq(regs); +#else __u32 *ptr = (__u32 *)regs; u64 val_lo = readl(ptr); u64 val_hi = readl(ptr + 1); return val_lo + (val_hi << 32); +#endif } static inline void xhci_writeq(__le64 volatile *regs, const u64 val) { +#if BITS_PER_LONG == 64 + writeq(val, regs); +#else __u32 *ptr = (__u32 *)regs; u32 val_lo = lower_32_bits(val); /* FIXME */ u32 val_hi = upper_32_bits(val); writel(val_lo, ptr); writel(val_hi, ptr + 1); +#endif } int xhci_hcd_init(int index, struct xhci_hccr **ret_hccr, @@ -1242,8 +1251,8 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, struct devrequest *req, int length, void *buffer); int xhci_check_maxpacket(struct usb_device *udev); -void xhci_flush_cache(uint32_t addr, u32 type_len); -void xhci_inval_cache(uint32_t addr, u32 type_len); +void xhci_flush_cache(uintptr_t addr, u32 type_len); +void xhci_inval_cache(uintptr_t addr, u32 type_len); void xhci_cleanup(struct xhci_ctrl *ctrl); struct xhci_ring *xhci_ring_alloc(unsigned int num_segs, bool link_trbs); int xhci_alloc_virt_device(struct usb_device *udev);