OSDN Git Service

usb: dwc3: Add support for GSI operations to gadget framework
authorHemant Kumar <hemantk@codeaurora.org>
Sat, 10 Oct 2015 02:36:21 +0000 (19:36 -0700)
committerDavid Keitel <dkeitel@codeaurora.org>
Tue, 22 Mar 2016 18:07:02 +0000 (11:07 -0700)
Targets supporting h/w accelerated path over GSI require
GSI specific configuration of USB controller.

Add support to enable h/w accelerated path to IPA.
Include operations to configure USB endpoints as
GSI capable, allocate TRBs that are associated with
GSI capable endpoints, perform operations on these
endpoints, and enable the GSI wrapper in DWC3 controller.
This allows a function driver to use GSI based h/w
accelerated data path.

Change-Id: I62688c70a04b1fdab3e522e0af759ebab69d92d7
Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/gadget.c
drivers/usb/dwc3/gadget.h

index c09a09a..c793b5e 100644 (file)
@@ -931,6 +931,7 @@ static int dwc3_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
+       dwc->reg_phys = res->start;
        dwc->xhci_resources[0].start = res->start;
        dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
                                        DWC3_XHCI_REGS_END;
index 89d6c06..7f24c37 100644 (file)
@@ -498,6 +498,7 @@ struct dwc3_ep_events {
  * @endpoint: usb endpoint
  * @request_list: list of requests for this endpoint
  * @req_queued: list of requests on this ep which have TRBs setup
+ * @trb_dma_pool: dma pool used to get aligned trb memory pool
  * @trb_pool: array of transaction buffers
  * @trb_pool_dma: dma address of @trb_pool
  * @free_slot: next slot which is going to be used
@@ -523,6 +524,7 @@ struct dwc3_ep {
        struct list_head        request_list;
        struct list_head        req_queued;
 
+       struct dma_pool         *trb_dma_pool;
        struct dwc3_trb         *trb_pool;
        dma_addr_t              trb_pool_dma;
        u32                     free_slot;
@@ -732,6 +734,7 @@ struct dwc3_scratchpad_array {
  * @gadget_driver: pointer to the gadget driver
  * @regs: base address for our registers
  * @regs_size: address space size
+ * @reg_phys: physical base address of dwc3 core register address space
  * @nr_scratch: number of scratch buffers
  * @num_event_buffers: calculated number of event buffers
  * @u1u2: only used on revisions <1.83a for workaround
@@ -847,6 +850,7 @@ struct dwc3 {
 
        void __iomem            *regs;
        size_t                  regs_size;
+       phys_addr_t             reg_phys;
 
        enum usb_dr_mode        dr_mode;
 
index 5a9ea5a..08f818d 100644 (file)
@@ -400,11 +400,18 @@ static void dwc3_free_trb_pool(struct dwc3_ep *dep)
 {
        struct dwc3             *dwc = dep->dwc;
 
-       dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
-                       dep->trb_pool, dep->trb_pool_dma);
+       /* Freeing of GSI EP TRBs are handled by GSI EP ops. */
+       if (dep->endpoint.ep_type == EP_TYPE_GSI)
+               return;
+
+       if (dep->trb_pool && dep->trb_pool_dma) {
+               dma_free_coherent(dwc->dev,
+                       sizeof(struct dwc3_trb) * DWC3_TRB_NUM, dep->trb_pool,
+                       dep->trb_pool_dma);
 
-       dep->trb_pool = NULL;
-       dep->trb_pool_dma = 0;
+               dep->trb_pool = NULL;
+               dep->trb_pool_dma = 0;
+       }
 }
 
 static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep)
@@ -601,7 +608,6 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
        return 0;
 }
 
-static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force);
 static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
 {
        struct dwc3_request             *req;
@@ -639,7 +645,10 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
 
        dwc3_trace(trace_dwc3_gadget, "Disabling %s", dep->name);
 
-       dwc3_remove_requests(dwc, dep);
+       if (dep->endpoint.ep_type == EP_TYPE_NORMAL)
+               dwc3_remove_requests(dwc, dep);
+       else if (dep->endpoint.ep_type == EP_TYPE_GSI)
+               dwc3_stop_active_transfer(dwc, dep->number, true);
 
        /* make sure HW endpoint isn't stalled */
        if (dep->flags & DWC3_EP_STALL)
@@ -2387,7 +2396,7 @@ static void dwc3_reset_gadget(struct dwc3 *dwc)
        }
 }
 
-static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force)
+void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force)
 {
        struct dwc3_ep *dep;
        struct dwc3_gadget_ep_cmd_params params;
index 2938cd6..719326d 100644 (file)
@@ -95,6 +95,7 @@ int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value);
 int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
                gfp_t gfp_flags);
 int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol);
+void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force);
 
 static inline dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep,
                struct dwc3_trb *trb)