Re: [U-Boot] [u-boot 32/40] usb: dwc3: Add chained TRB support for ep0
Hi, On Monday 16 February 2015 06:34 PM, Lukasz Majewski wrote: Hi Kishon, Hi Lukasz, On Monday 16 February 2015 05:12 PM, Lukasz Majewski wrote: Hi Kishon, dwc3 can do only max packet aligned transfers. So in case request length is not max packet aligned and is bigger than DWC3_EP0_BOUNCE_SIZE two chained TRBs is required to handle the transfer. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/usb/dwc3/ep0.c| 72 + drivers/usb/dwc3/gadget.c |2 +- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index fce2558..c2fe0ec 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -48,7 +48,7 @@ static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) } static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, - u32 len, u32 type) + u32 len, u32 type, unsigned chain) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_trb *trb; @@ -62,7 +62,10 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, return 0; } - trb = dwc-ep0_trb; + trb = dwc-ep0_trb[dep-free_slot]; + + if (chain) + dep-free_slot++; trb-bpl = lower_32_bits(buf_dma); trb-bph = upper_32_bits(buf_dma); @@ -70,13 +73,20 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, trb-ctrl = type; trb-ctrl |= (DWC3_TRB_CTRL_HWO - | DWC3_TRB_CTRL_LST - | DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI); + if (chain) + trb-ctrl |= DWC3_TRB_CTRL_CHN; + else + trb-ctrl |= (DWC3_TRB_CTRL_IOC + | DWC3_TRB_CTRL_LST); + dwc3_flush_cache((int)buf_dma, len); dwc3_flush_cache((int)trb, sizeof(*trb)); + if (chain) + return 0; + memset(params, 0, sizeof(params)); params.param0 = upper_32_bits(dwc-ep0_trb_addr); params.param1 = lower_32_bits(dwc-ep0_trb_addr); @@ -289,7 +299,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) int ret; ret = dwc3_ep0_start_trans(dwc, 0, dwc-ctrl_req_addr, 8, - DWC3_TRBCTL_CONTROL_SETUP); + DWC3_TRBCTL_CONTROL_SETUP, 0); WARN_ON(ret 0); } @@ -799,6 +809,23 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, maxp = ep0-endpoint.maxpacket; + /* Handle the first TRB before handling the bounce buffer if the request Minor comment - please fix above comment. Sorry. Didn't get what should I fix here? The comment should be as follow: /* * Handle the first . * * */ The first line is wrong (/* Handle ...). ah.. alright. Thanks Kishon ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [u-boot 32/40] usb: dwc3: Add chained TRB support for ep0
Hi Kishon, Hi Lukasz, On Monday 16 February 2015 05:12 PM, Lukasz Majewski wrote: Hi Kishon, dwc3 can do only max packet aligned transfers. So in case request length is not max packet aligned and is bigger than DWC3_EP0_BOUNCE_SIZE two chained TRBs is required to handle the transfer. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/usb/dwc3/ep0.c| 72 + drivers/usb/dwc3/gadget.c |2 +- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index fce2558..c2fe0ec 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -48,7 +48,7 @@ static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) } static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, - u32 len, u32 type) + u32 len, u32 type, unsigned chain) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_trb *trb; @@ -62,7 +62,10 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, return 0; } - trb = dwc-ep0_trb; + trb = dwc-ep0_trb[dep-free_slot]; + + if (chain) + dep-free_slot++; trb-bpl = lower_32_bits(buf_dma); trb-bph = upper_32_bits(buf_dma); @@ -70,13 +73,20 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, trb-ctrl = type; trb-ctrl |= (DWC3_TRB_CTRL_HWO - | DWC3_TRB_CTRL_LST - | DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI); + if (chain) + trb-ctrl |= DWC3_TRB_CTRL_CHN; + else + trb-ctrl |= (DWC3_TRB_CTRL_IOC + | DWC3_TRB_CTRL_LST); + dwc3_flush_cache((int)buf_dma, len); dwc3_flush_cache((int)trb, sizeof(*trb)); + if (chain) + return 0; + memset(params, 0, sizeof(params)); params.param0 = upper_32_bits(dwc-ep0_trb_addr); params.param1 = lower_32_bits(dwc-ep0_trb_addr); @@ -289,7 +299,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) int ret; ret = dwc3_ep0_start_trans(dwc, 0, dwc-ctrl_req_addr, 8, - DWC3_TRBCTL_CONTROL_SETUP); + DWC3_TRBCTL_CONTROL_SETUP, 0); WARN_ON(ret 0); } @@ -799,6 +809,23 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, maxp = ep0-endpoint.maxpacket; + /* Handle the first TRB before handling the bounce buffer if the request Minor comment - please fix above comment. Sorry. Didn't get what should I fix here? The comment should be as follow: /* * Handle the first . * * */ The first line is wrong (/* Handle ...). Btw thanks for reviewing all the patches. Cheers Kishon -- Best regards, Lukasz Majewski Samsung RD Institute Poland (SRPOL) | Linux Platform Group ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [u-boot 32/40] usb: dwc3: Add chained TRB support for ep0
Hi Kishon, dwc3 can do only max packet aligned transfers. So in case request length is not max packet aligned and is bigger than DWC3_EP0_BOUNCE_SIZE two chained TRBs is required to handle the transfer. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/usb/dwc3/ep0.c| 72 + drivers/usb/dwc3/gadget.c |2 +- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index fce2558..c2fe0ec 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -48,7 +48,7 @@ static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) } static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, - u32 len, u32 type) + u32 len, u32 type, unsigned chain) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_trb *trb; @@ -62,7 +62,10 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, return 0; } - trb = dwc-ep0_trb; + trb = dwc-ep0_trb[dep-free_slot]; + + if (chain) + dep-free_slot++; trb-bpl = lower_32_bits(buf_dma); trb-bph = upper_32_bits(buf_dma); @@ -70,13 +73,20 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, trb-ctrl = type; trb-ctrl |= (DWC3_TRB_CTRL_HWO - | DWC3_TRB_CTRL_LST - | DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI); + if (chain) + trb-ctrl |= DWC3_TRB_CTRL_CHN; + else + trb-ctrl |= (DWC3_TRB_CTRL_IOC + | DWC3_TRB_CTRL_LST); + dwc3_flush_cache((int)buf_dma, len); dwc3_flush_cache((int)trb, sizeof(*trb)); + if (chain) + return 0; + memset(params, 0, sizeof(params)); params.param0 = upper_32_bits(dwc-ep0_trb_addr); params.param1 = lower_32_bits(dwc-ep0_trb_addr); @@ -289,7 +299,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) int ret; ret = dwc3_ep0_start_trans(dwc, 0, dwc-ctrl_req_addr, 8, - DWC3_TRBCTL_CONTROL_SETUP); +DWC3_TRBCTL_CONTROL_SETUP, 0); WARN_ON(ret 0); } @@ -799,6 +809,23 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, maxp = ep0-endpoint.maxpacket; + /* Handle the first TRB before handling the bounce buffer if the request Minor comment - please fix above comment. + * length is greater than the bounce buffer size + */ + if (!IS_ALIGNED(ur-length, maxp) + ur-length DWC3_EP0_BOUNCE_SIZE) { + transfer_size = (ur-length / maxp) * maxp; + transferred = transfer_size - length; + buf = (u8 *)buf + transferred; + ur-actual += transferred; + + trb++; + dwc3_flush_cache((int)trb, sizeof(*trb)); + length = trb-size DWC3_TRB_SIZE_MASK; + + ep0-free_slot = 0; + } + if (dwc-ep0_bounced) { transfer_size = roundup((ur-length - transfer_size), maxp); @@ -827,7 +854,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, ret = dwc3_ep0_start_trans(dwc, epnum, dwc-ctrl_req_addr, 0, - DWC3_TRBCTL_CONTROL_DATA); + DWC3_TRBCTL_CONTROL_DATA, 0); WARN_ON(ret 0); } } @@ -908,11 +935,11 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, if (req-request.length == 0) { ret = dwc3_ep0_start_trans(dwc, dep-number, - dwc-ctrl_req_addr, 0, - DWC3_TRBCTL_CONTROL_DATA); - } else if (!IS_ALIGNED(req-request.length, dep-endpoint.maxpacket) - (dep-number == 0)) { - u32 transfer_size; +dwc-ctrl_req_addr, 0, +DWC3_TRBCTL_CONTROL_DATA, 0); + } else if (!IS_ALIGNED(req-request.length, dep-endpoint.maxpacket) + (dep-number == 0)) { + u32 transfer_size = 0; u32 maxpacket; ret = usb_gadget_map_request(dwc-gadget, req-request, @@ -922,10 +949,18 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, return; } - WARN_ON(req-request.length DWC3_EP0_BOUNCE_SIZE); - maxpacket = dep-endpoint.maxpacket; - transfer_size = roundup(req-request.length, maxpacket); + if (req-request.length DWC3_EP0_BOUNCE_SIZE) { + transfer_size = (req-request.length /
Re: [U-Boot] [u-boot 32/40] usb: dwc3: Add chained TRB support for ep0
Hi Lukasz, On Monday 16 February 2015 05:12 PM, Lukasz Majewski wrote: Hi Kishon, dwc3 can do only max packet aligned transfers. So in case request length is not max packet aligned and is bigger than DWC3_EP0_BOUNCE_SIZE two chained TRBs is required to handle the transfer. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/usb/dwc3/ep0.c| 72 + drivers/usb/dwc3/gadget.c |2 +- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index fce2558..c2fe0ec 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -48,7 +48,7 @@ static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) } static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, - u32 len, u32 type) + u32 len, u32 type, unsigned chain) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_trb *trb; @@ -62,7 +62,10 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, return 0; } - trb = dwc-ep0_trb; + trb = dwc-ep0_trb[dep-free_slot]; + + if (chain) + dep-free_slot++; trb-bpl = lower_32_bits(buf_dma); trb-bph = upper_32_bits(buf_dma); @@ -70,13 +73,20 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, trb-ctrl = type; trb-ctrl |= (DWC3_TRB_CTRL_HWO - | DWC3_TRB_CTRL_LST - | DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI); + if (chain) + trb-ctrl |= DWC3_TRB_CTRL_CHN; + else + trb-ctrl |= (DWC3_TRB_CTRL_IOC + | DWC3_TRB_CTRL_LST); + dwc3_flush_cache((int)buf_dma, len); dwc3_flush_cache((int)trb, sizeof(*trb)); + if (chain) + return 0; + memset(params, 0, sizeof(params)); params.param0 = upper_32_bits(dwc-ep0_trb_addr); params.param1 = lower_32_bits(dwc-ep0_trb_addr); @@ -289,7 +299,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) int ret; ret = dwc3_ep0_start_trans(dwc, 0, dwc-ctrl_req_addr, 8, - DWC3_TRBCTL_CONTROL_SETUP); + DWC3_TRBCTL_CONTROL_SETUP, 0); WARN_ON(ret 0); } @@ -799,6 +809,23 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, maxp = ep0-endpoint.maxpacket; + /* Handle the first TRB before handling the bounce buffer if the request Minor comment - please fix above comment. Sorry. Didn't get what should I fix here? Btw thanks for reviewing all the patches. Cheers Kishon ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [u-boot 32/40] usb: dwc3: Add chained TRB support for ep0
dwc3 can do only max packet aligned transfers. So in case request length is not max packet aligned and is bigger than DWC3_EP0_BOUNCE_SIZE two chained TRBs is required to handle the transfer. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/usb/dwc3/ep0.c| 72 + drivers/usb/dwc3/gadget.c |2 +- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index fce2558..c2fe0ec 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -48,7 +48,7 @@ static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) } static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, - u32 len, u32 type) + u32 len, u32 type, unsigned chain) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_trb *trb; @@ -62,7 +62,10 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, return 0; } - trb = dwc-ep0_trb; + trb = dwc-ep0_trb[dep-free_slot]; + + if (chain) + dep-free_slot++; trb-bpl = lower_32_bits(buf_dma); trb-bph = upper_32_bits(buf_dma); @@ -70,13 +73,20 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, trb-ctrl = type; trb-ctrl |= (DWC3_TRB_CTRL_HWO - | DWC3_TRB_CTRL_LST - | DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI); + if (chain) + trb-ctrl |= DWC3_TRB_CTRL_CHN; + else + trb-ctrl |= (DWC3_TRB_CTRL_IOC + | DWC3_TRB_CTRL_LST); + dwc3_flush_cache((int)buf_dma, len); dwc3_flush_cache((int)trb, sizeof(*trb)); + if (chain) + return 0; + memset(params, 0, sizeof(params)); params.param0 = upper_32_bits(dwc-ep0_trb_addr); params.param1 = lower_32_bits(dwc-ep0_trb_addr); @@ -289,7 +299,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) int ret; ret = dwc3_ep0_start_trans(dwc, 0, dwc-ctrl_req_addr, 8, - DWC3_TRBCTL_CONTROL_SETUP); + DWC3_TRBCTL_CONTROL_SETUP, 0); WARN_ON(ret 0); } @@ -799,6 +809,23 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, maxp = ep0-endpoint.maxpacket; + /* Handle the first TRB before handling the bounce buffer if the request +* length is greater than the bounce buffer size +*/ + if (!IS_ALIGNED(ur-length, maxp) + ur-length DWC3_EP0_BOUNCE_SIZE) { + transfer_size = (ur-length / maxp) * maxp; + transferred = transfer_size - length; + buf = (u8 *)buf + transferred; + ur-actual += transferred; + + trb++; + dwc3_flush_cache((int)trb, sizeof(*trb)); + length = trb-size DWC3_TRB_SIZE_MASK; + + ep0-free_slot = 0; + } + if (dwc-ep0_bounced) { transfer_size = roundup((ur-length - transfer_size), maxp); @@ -827,7 +854,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, ret = dwc3_ep0_start_trans(dwc, epnum, dwc-ctrl_req_addr, 0, - DWC3_TRBCTL_CONTROL_DATA); + DWC3_TRBCTL_CONTROL_DATA, 0); WARN_ON(ret 0); } } @@ -908,11 +935,11 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, if (req-request.length == 0) { ret = dwc3_ep0_start_trans(dwc, dep-number, - dwc-ctrl_req_addr, 0, - DWC3_TRBCTL_CONTROL_DATA); - } else if (!IS_ALIGNED(req-request.length, dep-endpoint.maxpacket) -(dep-number == 0)) { - u32 transfer_size; + dwc-ctrl_req_addr, 0, + DWC3_TRBCTL_CONTROL_DATA, 0); + } else if (!IS_ALIGNED(req-request.length, dep-endpoint.maxpacket) + (dep-number == 0)) { + u32 transfer_size = 0; u32 maxpacket; ret = usb_gadget_map_request(dwc-gadget, req-request, @@ -922,10 +949,18 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, return; } - WARN_ON(req-request.length DWC3_EP0_BOUNCE_SIZE); - maxpacket = dep-endpoint.maxpacket; - transfer_size = roundup(req-request.length, maxpacket); + if (req-request.length DWC3_EP0_BOUNCE_SIZE) { + transfer_size =