Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 289616
b: refs/heads/master
c: 457e84b
h: refs/heads/master
v: v3
  • Loading branch information
Felipe Balbi committed Feb 6, 2012
1 parent 3c6df8a commit 0ffddf4
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bb5cfd6811c63c47403e98028bde7e98bd7a1751
refs/heads/master: 457e84b6624b4d97e6ffae437887ea51a22d54a0
5 changes: 5 additions & 0 deletions trunk/drivers/usb/dwc3/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/of.h>

#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
Expand Down Expand Up @@ -404,6 +405,7 @@ static void dwc3_core_exit(struct dwc3 *dwc)

static int __devinit dwc3_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct resource *res;
struct dwc3 *dwc;

Expand Down Expand Up @@ -469,6 +471,9 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
else
dwc->maximum_speed = DWC3_DCFG_SUPERSPEED;

if (of_get_property(node, "tx-fifo-resize", NULL))
dwc->needs_fifo_resize = true;

pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
pm_runtime_forbid(&pdev->dev);
Expand Down
16 changes: 15 additions & 1 deletion trunk/drivers/usb/dwc3/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@
#define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31)
#define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17)

/* Global TX Fifo Size Register */
#define DWC3_GTXFIFOSIZ_TXFDEF(n) ((n) & 0xffff)
#define DWC3_GTXFIFOSIZ_TXFSTADDR(n) ((n) & 0xffff0000)

/* Global HWPARAMS1 Register */
#define DWC3_GHWPARAMS1_EN_PWROPT(n) ((n & (3 << 24)) >> 24)
#define DWC3_GHWPARAMS1_EN_PWROPT_NO 0
Expand Down Expand Up @@ -546,8 +550,13 @@ struct dwc3_hwparams {
#define DWC3_MODE_DRD 2
#define DWC3_MODE_HUB 3

#define DWC3_MDWIDTH(n) (((n) & 0xff00) >> 8)

/* HWPARAMS1 */
#define DWC3_NUM_INT(n) (((n) & (0x3f << 15)) >> 15)
#define DWC3_NUM_INT(n) (((n) & (0x3f << 15)) >> 15)

/* HWPARAMS7 */
#define DWC3_RAM1_DEPTH(n) ((n) & 0xffff)

struct dwc3_request {
struct usb_request request;
Expand Down Expand Up @@ -594,6 +603,8 @@ struct dwc3_request {
* @ep0_expect_in: true when we expect a DATA IN transfer
* @start_config_issued: true when StartConfig command has been issued
* @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround
* @needs_fifo_resize: not all users might want fifo resizing, flag it
* @resize_fifos: tells us it's ok to reconfigure our TxFIFO sizes.
* @ep0_next_event: hold the next expected event
* @ep0state: state of endpoint zero
* @link_state: link state
Expand Down Expand Up @@ -651,6 +662,8 @@ struct dwc3 {
unsigned start_config_issued:1;
unsigned setup_packet_pending:1;
unsigned delayed_status:1;
unsigned needs_fifo_resize:1;
unsigned resize_fifos:1;

enum dwc3_ep0_next ep0_next_event;
enum dwc3_ep0_state ep0state;
Expand Down Expand Up @@ -812,6 +825,7 @@ union dwc3_event {

/* prototypes */
void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);

int dwc3_host_init(struct dwc3 *dwc);
void dwc3_host_exit(struct dwc3 *dwc);
Expand Down
11 changes: 10 additions & 1 deletion trunk/drivers/usb/dwc3/ep0.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,11 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
case DWC3_ADDRESS_STATE:
ret = dwc3_ep0_delegate_req(dwc, ctrl);
/* if the cfg matches and the cfg is non zero */
if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS)))
if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) {
dwc->dev_state = DWC3_CONFIGURED_STATE;
dwc->resize_fifos = true;
dev_dbg(dwc->dev, "resize fifos flag SET\n");
}
break;

case DWC3_CONFIGURED_STATE:
Expand Down Expand Up @@ -707,6 +710,12 @@ static void dwc3_ep0_do_control_status(struct dwc3 *dwc, u32 epnum)
{
struct dwc3_ep *dep = dwc->eps[epnum];

if (dwc->resize_fifos) {
dev_dbg(dwc->dev, "starting to resize fifos\n");
dwc3_gadget_resize_tx_fifos(dwc);
dwc->resize_fifos = 0;
}

WARN_ON(dwc3_ep0_start_control_status(dep));
}

Expand Down
74 changes: 74 additions & 0 deletions trunk/drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,80 @@ 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 < DWC3_ENDPOINTS_NUM; num++) {
struct dwc3_ep *dep = dwc->eps[num];
int fifo_number = dep->number >> 1;
int tmp;

if (!(dep->number & 1))
continue;

if (!(dep->flags & DWC3_EP_ENABLED))
continue;

tmp = dep->endpoint.maxpacket;
tmp += mdwidth;
tmp += mdwidth;

fifo_size = DIV_ROUND_UP(tmp, mdwidth);
fifo_size |= (last_fifo_depth << 16);

dev_vdbg(dwc->dev, "%s: Fifo Addr %04x Size %d\n",
dep->name, last_fifo_depth, fifo_size & 0xffff);

dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(fifo_number),
fifo_size);

last_fifo_depth += (fifo_size & 0xffff);
}

return 0;
}

void dwc3_map_buffer_to_dma(struct dwc3_request *req)
{
struct dwc3 *dwc = req->dep->dwc;
Expand Down

0 comments on commit 0ffddf4

Please sign in to comment.