Loading Documentation/devicetree/bindings/usb/dwc3.txt +4 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ Optional properties: - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal utmi_l1_suspend_n, false when asserts utmi_sleep_n - snps,hird-threshold: HIRD threshold - snps,num-normal-evt-buffs: If present, specifies number of normal event buffers. Default is 1. - snps,num-gsi-evt-buffs: If present, specifies number of GSI based hardware accelerated event buffers. 1 event buffer is needed per h/w accelerated endpoint. This is usually a subnode to DWC3 glue to which it is connected. Loading @@ -35,4 +38,5 @@ dwc3@4a030000 { usb-phy = <&usb2_phy>, <&usb3,phy>; tx-fifo-resize; snps,usb3-u1u2-disable; snps,num-gsi-evt-buffs = <0x2>; }; arch/arm/boot/dts/qcom/mdmcalifornium.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -575,6 +575,7 @@ snps,lpm-nyet-thresh = <0x8>; snps,bus-suspend-enable; snps,usb3-u1u2-disable; snps,num-gsi-evt-buffs = <0x3>; }; }; Loading drivers/usb/dwc3/core.c +54 −13 Original line number Diff line number Diff line Loading @@ -234,7 +234,7 @@ static void dwc3_free_one_event_buffer(struct dwc3 *dwc, * otherwise ERR_PTR(errno). */ static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length) unsigned length, enum event_buf_type type) { struct dwc3_event_buffer *evt; Loading @@ -244,6 +244,7 @@ static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc, evt->dwc = dwc; evt->length = length; evt->type = type; evt->buf = dma_alloc_coherent(dwc->dev, length, &evt->dma, GFP_KERNEL); if (!evt->buf) Loading Loading @@ -278,26 +279,40 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc) */ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length) { int num; int i; int j = 0; num = DWC3_NUM_INT(dwc->hwparams.hwparams1); dwc->num_event_buffers = num; dwc->num_event_buffers = dwc->num_normal_event_buffers + dwc->num_gsi_event_buffers; dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num, dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * dwc->num_event_buffers, GFP_KERNEL); if (!dwc->ev_buffs) return -ENOMEM; for (i = 0; i < num; i++) { for (i = 0; i < dwc->num_normal_event_buffers; i++) { struct dwc3_event_buffer *evt; evt = dwc3_alloc_one_event_buffer(dwc, length); evt = dwc3_alloc_one_event_buffer(dwc, length, EVT_BUF_TYPE_NORMAL); if (IS_ERR(evt)) { dev_err(dwc->dev, "can't allocate event buffer\n"); return PTR_ERR(evt); } dwc->ev_buffs[i] = evt; dwc->ev_buffs[j++] = evt; } for (i = 0; i < dwc->num_gsi_event_buffers; i++) { struct dwc3_event_buffer *evt; evt = dwc3_alloc_one_event_buffer(dwc, length, EVT_BUF_TYPE_GSI); if (IS_ERR(evt)) { dev_err(dwc->dev, "can't allocate event buffer\n"); return PTR_ERR(evt); } dwc->ev_buffs[j++] = evt; } return 0; Loading @@ -324,10 +339,23 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), lower_32_bits(evt->dma)); if (evt->type == EVT_BUF_TYPE_NORMAL) { dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), upper_32_bits(evt->dma)); dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), DWC3_GEVNTSIZ_SIZE(evt->length)); } else { dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), DWC3_GEVNTADRHI_EVNTADRHI_GSI_EN( DWC3_GEVENT_TYPE_GSI) | DWC3_GEVNTADRHI_EVNTADRHI_GSI_IDX(n)); dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), DWC3_GEVNTCOUNT_EVNTINTRPTMASK | ((evt->length) & 0xffff)); } dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0); } Loading Loading @@ -803,6 +831,7 @@ static int dwc3_probe(struct platform_device *pdev) struct dwc3 *dwc; u8 lpm_nyet_threshold; u8 hird_threshold; u32 num_evt_buffs; int ret; Loading Loading @@ -891,6 +920,18 @@ static int dwc3_probe(struct platform_device *pdev) dwc->disable_clk_gating = of_property_read_bool(node, "snps,disable-clk-gating"); dwc->num_normal_event_buffers = 1; ret = of_property_read_u32(node, "snps,num-normal-evt-buffs", &num_evt_buffs); if (!ret) dwc->num_normal_event_buffers = num_evt_buffs; ret = of_property_read_u32(node, "snps,num-gsi-evt-buffs", &num_evt_buffs); if (!ret) dwc->num_gsi_event_buffers = num_evt_buffs; if (dwc->enable_bus_suspend) { pm_runtime_set_autosuspend_delay(dev, 500); pm_runtime_use_autosuspend(dev); Loading drivers/usb/dwc3/core.h +13 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,11 @@ #define DWC3_GEVNTSIZ(n) (0xc408 + (n * 0x10)) #define DWC3_GEVNTCOUNT(n) (0xc40c + (n * 0x10)) #define DWC3_GEVNTCOUNT_EVNTINTRPTMASK (1 << 31) #define DWC3_GEVNTADRHI_EVNTADRHI_GSI_EN(n) (n << 22) #define DWC3_GEVNTADRHI_EVNTADRHI_GSI_IDX(n) (n << 16) #define DWC3_GEVENT_TYPE_GSI 0x3 #define DWC3_GHWPARAMS8 0xc600 #define DWC3_GFLADJ 0xc630 Loading Loading @@ -439,6 +444,11 @@ struct dwc3_trb; enum event_buf_type { EVT_BUF_TYPE_NORMAL, EVT_BUF_TYPE_GSI }; /** * struct dwc3_event_buffer - Software event buffer representation * @buf: _THE_ buffer Loading @@ -452,6 +462,7 @@ struct dwc3_trb; struct dwc3_event_buffer { void *buf; unsigned length; enum event_buf_type type; unsigned int lpos; unsigned int count; unsigned int flags; Loading Loading @@ -855,6 +866,8 @@ struct dwc3 { u32 nr_scratch; u32 num_event_buffers; u32 num_normal_event_buffers; u32 num_gsi_event_buffers; u32 u1; u32 u1u2; Loading drivers/usb/dwc3/gadget.c +2 −2 Original line number Diff line number Diff line Loading @@ -3443,7 +3443,7 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) spin_lock_irqsave(&dwc->lock, flags); dwc->bh_handled_evt_cnt[dwc->bh_dbg_index] = 0; for (i = 0; i < dwc->num_event_buffers; i++) for (i = 0; i < dwc->num_normal_event_buffers; i++) ret |= dwc3_process_event_buf(dwc, i); spin_unlock_irqrestore(&dwc->lock, flags); Loading Loading @@ -3499,7 +3499,7 @@ static irqreturn_t dwc3_interrupt(int irq, void *_dwc) return IRQ_HANDLED; } for (i = 0; i < dwc->num_event_buffers; i++) { for (i = 0; i < dwc->num_normal_event_buffers; i++) { irqreturn_t status; status = dwc3_check_event_buf(dwc, i); Loading Loading
Documentation/devicetree/bindings/usb/dwc3.txt +4 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ Optional properties: - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal utmi_l1_suspend_n, false when asserts utmi_sleep_n - snps,hird-threshold: HIRD threshold - snps,num-normal-evt-buffs: If present, specifies number of normal event buffers. Default is 1. - snps,num-gsi-evt-buffs: If present, specifies number of GSI based hardware accelerated event buffers. 1 event buffer is needed per h/w accelerated endpoint. This is usually a subnode to DWC3 glue to which it is connected. Loading @@ -35,4 +38,5 @@ dwc3@4a030000 { usb-phy = <&usb2_phy>, <&usb3,phy>; tx-fifo-resize; snps,usb3-u1u2-disable; snps,num-gsi-evt-buffs = <0x2>; };
arch/arm/boot/dts/qcom/mdmcalifornium.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -575,6 +575,7 @@ snps,lpm-nyet-thresh = <0x8>; snps,bus-suspend-enable; snps,usb3-u1u2-disable; snps,num-gsi-evt-buffs = <0x3>; }; }; Loading
drivers/usb/dwc3/core.c +54 −13 Original line number Diff line number Diff line Loading @@ -234,7 +234,7 @@ static void dwc3_free_one_event_buffer(struct dwc3 *dwc, * otherwise ERR_PTR(errno). */ static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length) unsigned length, enum event_buf_type type) { struct dwc3_event_buffer *evt; Loading @@ -244,6 +244,7 @@ static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc, evt->dwc = dwc; evt->length = length; evt->type = type; evt->buf = dma_alloc_coherent(dwc->dev, length, &evt->dma, GFP_KERNEL); if (!evt->buf) Loading Loading @@ -278,26 +279,40 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc) */ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length) { int num; int i; int j = 0; num = DWC3_NUM_INT(dwc->hwparams.hwparams1); dwc->num_event_buffers = num; dwc->num_event_buffers = dwc->num_normal_event_buffers + dwc->num_gsi_event_buffers; dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num, dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * dwc->num_event_buffers, GFP_KERNEL); if (!dwc->ev_buffs) return -ENOMEM; for (i = 0; i < num; i++) { for (i = 0; i < dwc->num_normal_event_buffers; i++) { struct dwc3_event_buffer *evt; evt = dwc3_alloc_one_event_buffer(dwc, length); evt = dwc3_alloc_one_event_buffer(dwc, length, EVT_BUF_TYPE_NORMAL); if (IS_ERR(evt)) { dev_err(dwc->dev, "can't allocate event buffer\n"); return PTR_ERR(evt); } dwc->ev_buffs[i] = evt; dwc->ev_buffs[j++] = evt; } for (i = 0; i < dwc->num_gsi_event_buffers; i++) { struct dwc3_event_buffer *evt; evt = dwc3_alloc_one_event_buffer(dwc, length, EVT_BUF_TYPE_GSI); if (IS_ERR(evt)) { dev_err(dwc->dev, "can't allocate event buffer\n"); return PTR_ERR(evt); } dwc->ev_buffs[j++] = evt; } return 0; Loading @@ -324,10 +339,23 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), lower_32_bits(evt->dma)); if (evt->type == EVT_BUF_TYPE_NORMAL) { dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), upper_32_bits(evt->dma)); dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), DWC3_GEVNTSIZ_SIZE(evt->length)); } else { dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), DWC3_GEVNTADRHI_EVNTADRHI_GSI_EN( DWC3_GEVENT_TYPE_GSI) | DWC3_GEVNTADRHI_EVNTADRHI_GSI_IDX(n)); dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), DWC3_GEVNTCOUNT_EVNTINTRPTMASK | ((evt->length) & 0xffff)); } dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0); } Loading Loading @@ -803,6 +831,7 @@ static int dwc3_probe(struct platform_device *pdev) struct dwc3 *dwc; u8 lpm_nyet_threshold; u8 hird_threshold; u32 num_evt_buffs; int ret; Loading Loading @@ -891,6 +920,18 @@ static int dwc3_probe(struct platform_device *pdev) dwc->disable_clk_gating = of_property_read_bool(node, "snps,disable-clk-gating"); dwc->num_normal_event_buffers = 1; ret = of_property_read_u32(node, "snps,num-normal-evt-buffs", &num_evt_buffs); if (!ret) dwc->num_normal_event_buffers = num_evt_buffs; ret = of_property_read_u32(node, "snps,num-gsi-evt-buffs", &num_evt_buffs); if (!ret) dwc->num_gsi_event_buffers = num_evt_buffs; if (dwc->enable_bus_suspend) { pm_runtime_set_autosuspend_delay(dev, 500); pm_runtime_use_autosuspend(dev); Loading
drivers/usb/dwc3/core.h +13 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,11 @@ #define DWC3_GEVNTSIZ(n) (0xc408 + (n * 0x10)) #define DWC3_GEVNTCOUNT(n) (0xc40c + (n * 0x10)) #define DWC3_GEVNTCOUNT_EVNTINTRPTMASK (1 << 31) #define DWC3_GEVNTADRHI_EVNTADRHI_GSI_EN(n) (n << 22) #define DWC3_GEVNTADRHI_EVNTADRHI_GSI_IDX(n) (n << 16) #define DWC3_GEVENT_TYPE_GSI 0x3 #define DWC3_GHWPARAMS8 0xc600 #define DWC3_GFLADJ 0xc630 Loading Loading @@ -439,6 +444,11 @@ struct dwc3_trb; enum event_buf_type { EVT_BUF_TYPE_NORMAL, EVT_BUF_TYPE_GSI }; /** * struct dwc3_event_buffer - Software event buffer representation * @buf: _THE_ buffer Loading @@ -452,6 +462,7 @@ struct dwc3_trb; struct dwc3_event_buffer { void *buf; unsigned length; enum event_buf_type type; unsigned int lpos; unsigned int count; unsigned int flags; Loading Loading @@ -855,6 +866,8 @@ struct dwc3 { u32 nr_scratch; u32 num_event_buffers; u32 num_normal_event_buffers; u32 num_gsi_event_buffers; u32 u1; u32 u1u2; Loading
drivers/usb/dwc3/gadget.c +2 −2 Original line number Diff line number Diff line Loading @@ -3443,7 +3443,7 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) spin_lock_irqsave(&dwc->lock, flags); dwc->bh_handled_evt_cnt[dwc->bh_dbg_index] = 0; for (i = 0; i < dwc->num_event_buffers; i++) for (i = 0; i < dwc->num_normal_event_buffers; i++) ret |= dwc3_process_event_buf(dwc, i); spin_unlock_irqrestore(&dwc->lock, flags); Loading Loading @@ -3499,7 +3499,7 @@ static irqreturn_t dwc3_interrupt(int irq, void *_dwc) return IRQ_HANDLED; } for (i = 0; i < dwc->num_event_buffers; i++) { for (i = 0; i < dwc->num_normal_event_buffers; i++) { irqreturn_t status; status = dwc3_check_event_buf(dwc, i); Loading