From: Wu Liang feng Date: Wed, 10 Aug 2016 03:15:19 +0000 (+0800) Subject: Revert "UPSTREAM: usb: dwc3: drop FIFO resizing logic" X-Git-Tag: firefly_0821_release~1893 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=fe9019cc55d05f07bce6732bd60d1d96ba3574fe;p=firefly-linux-kernel-4.4.55.git Revert "UPSTREAM: usb: dwc3: drop FIFO resizing logic" This reverts commit fea44d339a409a3270c75f91e332c7e54e0ff59d. --- diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 04813b1ad943..8de381a44708 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -14,6 +14,7 @@ Optional properties: the second element is expected to be a handle to the USB3/SS PHY - phys: from the *Generic PHY* bindings - phy-names: from the *Generic PHY* bindings + - tx-fifo-resize: determines if the FIFO *has* to be reallocated. - snps,usb3_lpm_capable: determines if platform is USB3 LPM capable - snps,disable_scramble_quirk: true when SW should disable data scrambling. Only really useful for FPGA builds. @@ -53,8 +54,6 @@ Optional properties: register for post-silicon frame length adjustment when the fladj_30mhz_sdbnd signal is invalid or incorrect. - - tx-fifo-resize: determines if the FIFO *has* to be reallocated. - This is usually a subnode to DWC3 glue to which it is connected. dwc3@4a030000 { @@ -62,4 +61,5 @@ dwc3@4a030000 { reg = <0x4a030000 0xcfff>; interrupts = <0 92 4> usb-phy = <&usb2_phy>, <&usb3,phy>; + tx-fifo-resize; }; diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt index 39acb084bce9..ca164e71dd50 100644 --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt @@ -59,6 +59,7 @@ Example device nodes: interrupts = <0 205 0x4>; phys = <&hs_phy>, <&ss_phy>; phy-names = "usb2-phy", "usb3-phy"; + tx-fifo-resize; dr_mode = "host"; }; }; diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 538ea674e3d9..b8c39d86f565 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -983,6 +983,9 @@ static int dwc3_probe(struct platform_device *pdev) dwc->usb3_lpm_capable = device_property_read_bool(dev, "snps,usb3_lpm_capable"); + dwc->needs_fifo_resize = device_property_read_bool(dev, + "tx-fifo-resize"); + dwc->disable_scramble_quirk = device_property_read_bool(dev, "snps,disable_scramble_quirk"); dwc->u2exit_lfps_quirk = device_property_read_bool(dev, @@ -1030,6 +1033,7 @@ static int dwc3_probe(struct platform_device *pdev) if (pdata->hird_threshold) hird_threshold = pdata->hird_threshold; + dwc->needs_fifo_resize = pdata->tx_fifo_resize; dwc->usb3_lpm_capable = pdata->usb3_lpm_capable; dwc->dr_mode = pdata->dr_mode; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index c78b2bdb4f2c..ed96f7d113f6 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -721,8 +721,10 @@ struct dwc3_scratchpad_array { * 0 - utmi_sleep_n * 1 - utmi_l1_suspend_n * @is_fpga: true when we are using the FPGA board + * @needs_fifo_resize: not all users might want fifo resizing, flag it * @enabled: true when gadget driver is ready * @pullups_connected: true when Run/Stop bit is set + * @resize_fifos: tells us it's ok to reconfigure our TxFIFO sizes. * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround * @start_config_issued: true when StartConfig command has been issued * @three_stage_setup: set if we perform a three phase setup @@ -873,8 +875,10 @@ struct dwc3 { unsigned has_lpm_erratum:1; unsigned is_utmi_l1_suspend:1; unsigned is_fpga:1; + unsigned needs_fifo_resize:1; unsigned enabled:1; unsigned pullups_connected:1; + unsigned resize_fifos:1; unsigned setup_packet_pending:1; unsigned three_stage_setup:1; unsigned usb3_lpm_capable:1; @@ -1045,6 +1049,7 @@ struct dwc3_gadget_ep_cmd_params { /* prototypes */ void dwc3_set_mode(struct dwc3 *dwc, u32 mode); +int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc); int dwc3_soft_reset(struct dwc3 *dwc); int dwc3_event_buffers_setup(struct dwc3 *dwc); void dwc3_event_buffers_cleanup(struct dwc3 *dwc); diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 8e5150ac4194..8d6b75c2f53b 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -583,6 +583,9 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA); dwc3_writel(dwc->regs, DWC3_DCTL, reg); + + dwc->resize_fifos = true; + dwc3_trace(trace_dwc3_ep0, "resize FIFOs flag SET"); } break; @@ -1021,6 +1024,12 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep) { + if (dwc->resize_fifos) { + dwc3_trace(trace_dwc3_ep0, "Resizing FIFOs"); + dwc3_gadget_resize_tx_fifos(dwc); + dwc->resize_fifos = 0; + } + WARN_ON(dwc3_ep0_start_control_status(dep)); } diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index e735b2a88a1a..bc2720108adb 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -145,6 +145,92 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) return -ETIMEDOUT; } +/** + * dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for current use-case + * @dwc: pointer to our context structure + * + * This function will a best effort FIFO allocation in order + * to improve FIFO usage and throughput, while still allowing + * us to enable as many endpoints as possible. + * + * Keep in mind that this operation will be highly dependent + * on the configured size for RAM1 - which contains TxFifo -, + * the amount of endpoints enabled on coreConsultant tool, and + * the width of the Master Bus. + * + * In the ideal world, we would always be able to satisfy the + * following equation: + * + * ((512 + 2 * MDWIDTH-Bytes) + (Number of IN Endpoints - 1) * \ + * (3 * (1024 + MDWIDTH-Bytes) + MDWIDTH-Bytes)) / MDWIDTH-Bytes + * + * Unfortunately, due to many variables that's not always the case. + */ +int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc) +{ + int last_fifo_depth = 0; + int ram1_depth; + int fifo_size; + int mdwidth; + int num; + + if (!dwc->needs_fifo_resize) + return 0; + + ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); + mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); + + /* MDWIDTH is represented in bits, we need it in bytes */ + mdwidth >>= 3; + + /* + * FIXME For now we will only allocate 1 wMaxPacketSize space + * for each enabled endpoint, later patches will come to + * improve this algorithm so that we better use the internal + * FIFO space + */ + for (num = 0; num < dwc->num_in_eps; num++) { + /* bit0 indicates direction; 1 means IN ep */ + struct dwc3_ep *dep = dwc->eps[(num << 1) | 1]; + int mult = 1; + int tmp; + + if (!(dep->flags & DWC3_EP_ENABLED)) + continue; + + if (usb_endpoint_xfer_bulk(dep->endpoint.desc) + || usb_endpoint_xfer_isoc(dep->endpoint.desc)) + mult = 3; + + /* + * REVISIT: the following assumes we will always have enough + * space available on the FIFO RAM for all possible use cases. + * Make sure that's true somehow and change FIFO allocation + * accordingly. + * + * If we have Bulk or Isochronous endpoints, we want + * them to be able to be very, very fast. So we're giving + * those endpoints a fifo_size which is enough for 3 full + * packets + */ + tmp = mult * (dep->endpoint.maxpacket + mdwidth); + tmp += mdwidth; + + fifo_size = DIV_ROUND_UP(tmp, mdwidth); + + fifo_size |= (last_fifo_depth << 16); + + dwc3_trace(trace_dwc3_gadget, "%s: Fifo Addr %04x Size %d", + dep->name, last_fifo_depth, fifo_size & 0xffff); + + dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num), fifo_size); + + last_fifo_depth += (fifo_size & 0xffff); + } + + return 0; +} + void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, int status) { diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 169d304ac31c..b44e818c062e 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -23,6 +23,7 @@ struct dwc3_platform_data { enum usb_device_speed maximum_speed; enum usb_dr_mode dr_mode; + bool tx_fifo_resize; bool usb3_lpm_capable; bool phyif_utmi_16_bits;