Skip to content

Commit f6bafc6

Browse files
author
Felipe Balbi
committed
usb: dwc3: convert TRBs into bitshifts
this will get rid of a useless memcpy on IRQ handling, thus improving driver performance. Tested with OMAP5430 running g_mass_storage on SuperSpeed and HighSpeed. Note that we are removing the little endian access of the TRB and all accesses will be in System endianness, if there happens to be a system in BE, bit 12 of GSBUSCFG0 should be set so that HW does byte invariant BE accesses when fetching TRBs. Signed-off-by: Felipe Balbi <[email protected]>
1 parent 3b63736 commit f6bafc6

File tree

3 files changed

+97
-162
lines changed

3 files changed

+97
-162
lines changed

drivers/usb/dwc3/core.h

Lines changed: 38 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@
301301

302302
/* Structures */
303303

304-
struct dwc3_trb_hw;
304+
struct dwc3_trb;
305305

306306
/**
307307
* struct dwc3_event_buffer - Software event buffer representation
@@ -356,7 +356,7 @@ struct dwc3_ep {
356356
struct list_head request_list;
357357
struct list_head req_queued;
358358

359-
struct dwc3_trb_hw *trb_pool;
359+
struct dwc3_trb *trb_pool;
360360
dma_addr_t trb_pool_dma;
361361
u32 free_slot;
362362
u32 busy_slot;
@@ -431,102 +431,49 @@ enum dwc3_device_state {
431431
DWC3_CONFIGURED_STATE,
432432
};
433433

434-
/**
435-
* struct dwc3_trb - transfer request block
436-
* @bpl: lower 32bit of the buffer
437-
* @bph: higher 32bit of the buffer
438-
* @length: buffer size (up to 16mb - 1)
439-
* @pcm1: packet count m1
440-
* @trbsts: trb status
441-
* 0 = ok
442-
* 1 = missed isoc
443-
* 2 = setup pending
444-
* @hwo: hardware owner of descriptor
445-
* @lst: last trb
446-
* @chn: chain buffers
447-
* @csp: continue on short packets (only supported on isoc eps)
448-
* @trbctl: trb control
449-
* 1 = normal
450-
* 2 = control-setup
451-
* 3 = control-status-2
452-
* 4 = control-status-3
453-
* 5 = control-data (first trb of data stage)
454-
* 6 = isochronous-first (first trb of service interval)
455-
* 7 = isochronous
456-
* 8 = link trb
457-
* others = reserved
458-
* @isp_imi: interrupt on short packet / interrupt on missed isoc
459-
* @ioc: interrupt on complete
460-
* @sid_sofn: Stream ID / SOF Number
461-
*/
462-
struct dwc3_trb {
463-
u64 bplh;
464-
465-
union {
466-
struct {
467-
u32 length:24;
468-
u32 pcm1:2;
469-
u32 reserved27_26:2;
470-
u32 trbsts:4;
471-
#define DWC3_TRB_STS_OKAY 0
472-
#define DWC3_TRB_STS_MISSED_ISOC 1
473-
#define DWC3_TRB_STS_SETUP_PENDING 2
474-
};
475-
u32 len_pcm;
476-
};
477-
478-
union {
479-
struct {
480-
u32 hwo:1;
481-
u32 lst:1;
482-
u32 chn:1;
483-
u32 csp:1;
484-
u32 trbctl:6;
485-
u32 isp_imi:1;
486-
u32 ioc:1;
487-
u32 reserved13_12:2;
488-
u32 sid_sofn:16;
489-
u32 reserved31_30:2;
490-
};
491-
u32 control;
492-
};
493-
} __packed;
434+
/* TRB Length, PCM and Status */
435+
#define DWC3_TRB_SIZE_MASK (0x00ffffff)
436+
#define DWC3_TRB_SIZE_LENGTH(n) ((n) & DWC3_TRB_SIZE_MASK)
437+
#define DWC3_TRB_SIZE_PCM1(n) (((n) & 0x03) << 24)
438+
#define DWC3_TRB_SIZE_TRBSTS(n) (((n) & (0x0f << 28) >> 28))
439+
440+
#define DWC3_TRBSTS_OK 0
441+
#define DWC3_TRBSTS_MISSED_ISOC 1
442+
#define DWC3_TRBSTS_SETUP_PENDING 2
443+
444+
/* TRB Control */
445+
#define DWC3_TRB_CTRL_HWO (1 << 0)
446+
#define DWC3_TRB_CTRL_LST (1 << 1)
447+
#define DWC3_TRB_CTRL_CHN (1 << 2)
448+
#define DWC3_TRB_CTRL_CSP (1 << 3)
449+
#define DWC3_TRB_CTRL_TRBCTL(n) (((n) & 0x3f) << 4)
450+
#define DWC3_TRB_CTRL_ISP_IMI (1 << 10)
451+
#define DWC3_TRB_CTRL_IOC (1 << 11)
452+
#define DWC3_TRB_CTRL_SID_SOFN(n) (((n) & 0xffff) << 14)
453+
454+
#define DWC3_TRBCTL_NORMAL DWC3_TRB_CTRL_TRBCTL(1)
455+
#define DWC3_TRBCTL_CONTROL_SETUP DWC3_TRB_CTRL_TRBCTL(2)
456+
#define DWC3_TRBCTL_CONTROL_STATUS2 DWC3_TRB_CTRL_TRBCTL(3)
457+
#define DWC3_TRBCTL_CONTROL_STATUS3 DWC3_TRB_CTRL_TRBCTL(4)
458+
#define DWC3_TRBCTL_CONTROL_DATA DWC3_TRB_CTRL_TRBCTL(5)
459+
#define DWC3_TRBCTL_ISOCHRONOUS_FIRST DWC3_TRB_CTRL_TRBCTL(6)
460+
#define DWC3_TRBCTL_ISOCHRONOUS DWC3_TRB_CTRL_TRBCTL(7)
461+
#define DWC3_TRBCTL_LINK_TRB DWC3_TRB_CTRL_TRBCTL(8)
494462

495463
/**
496-
* struct dwc3_trb_hw - transfer request block (hw format)
464+
* struct dwc3_trb - transfer request block (hw format)
497465
* @bpl: DW0-3
498466
* @bph: DW4-7
499467
* @size: DW8-B
500468
* @trl: DWC-F
501469
*/
502-
struct dwc3_trb_hw {
503-
__le32 bpl;
504-
__le32 bph;
505-
__le32 size;
506-
__le32 ctrl;
470+
struct dwc3_trb {
471+
u32 bpl;
472+
u32 bph;
473+
u32 size;
474+
u32 ctrl;
507475
} __packed;
508476

509-
static inline void dwc3_trb_to_hw(struct dwc3_trb *nat, struct dwc3_trb_hw *hw)
510-
{
511-
hw->bpl = cpu_to_le32(lower_32_bits(nat->bplh));
512-
hw->bph = cpu_to_le32(upper_32_bits(nat->bplh));
513-
hw->size = cpu_to_le32p(&nat->len_pcm);
514-
/* HWO is written last */
515-
hw->ctrl = cpu_to_le32p(&nat->control);
516-
}
517-
518-
static inline void dwc3_trb_to_nat(struct dwc3_trb_hw *hw, struct dwc3_trb *nat)
519-
{
520-
u64 bplh;
521-
522-
bplh = le32_to_cpup(&hw->bpl);
523-
bplh |= (u64) le32_to_cpup(&hw->bph) << 32;
524-
nat->bplh = bplh;
525-
526-
nat->len_pcm = le32_to_cpup(&hw->size);
527-
nat->control = le32_to_cpup(&hw->ctrl);
528-
}
529-
530477
/**
531478
* dwc3_hwparams - copy of HWPARAMS registers
532479
* @hwparams0 - GHWPARAMS0
@@ -573,7 +520,7 @@ struct dwc3_request {
573520
struct dwc3_ep *dep;
574521

575522
u8 epnum;
576-
struct dwc3_trb_hw *trb;
523+
struct dwc3_trb *trb;
577524
dma_addr_t trb_dma;
578525

579526
unsigned direction:1;
@@ -624,7 +571,7 @@ struct dwc3_request {
624571
*/
625572
struct dwc3 {
626573
struct usb_ctrlrequest *ctrl_req;
627-
struct dwc3_trb_hw *ep0_trb;
574+
struct dwc3_trb *ep0_trb;
628575
void *ep0_bounce;
629576
u8 *setup_buf;
630577
dma_addr_t ctrl_req_addr;
@@ -691,19 +638,6 @@ struct dwc3 {
691638

692639
/* -------------------------------------------------------------------------- */
693640

694-
#define DWC3_TRBSTS_OK 0
695-
#define DWC3_TRBSTS_MISSED_ISOC 1
696-
#define DWC3_TRBSTS_SETUP_PENDING 2
697-
698-
#define DWC3_TRBCTL_NORMAL 1
699-
#define DWC3_TRBCTL_CONTROL_SETUP 2
700-
#define DWC3_TRBCTL_CONTROL_STATUS2 3
701-
#define DWC3_TRBCTL_CONTROL_STATUS3 4
702-
#define DWC3_TRBCTL_CONTROL_DATA 5
703-
#define DWC3_TRBCTL_ISOCHRONOUS_FIRST 6
704-
#define DWC3_TRBCTL_ISOCHRONOUS 7
705-
#define DWC3_TRBCTL_LINK_TRB 8
706-
707641
/* -------------------------------------------------------------------------- */
708642

709643
struct dwc3_event_type {

drivers/usb/dwc3/ep0.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
7676
u32 len, u32 type)
7777
{
7878
struct dwc3_gadget_ep_cmd_params params;
79-
struct dwc3_trb_hw *trb_hw;
80-
struct dwc3_trb trb;
79+
struct dwc3_trb *trb;
8180
struct dwc3_ep *dep;
8281

8382
int ret;
@@ -88,19 +87,17 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
8887
return 0;
8988
}
9089

91-
trb_hw = dwc->ep0_trb;
92-
memset(&trb, 0, sizeof(trb));
90+
trb = dwc->ep0_trb;
9391

94-
trb.trbctl = type;
95-
trb.bplh = buf_dma;
96-
trb.length = len;
92+
trb->bpl = lower_32_bits(buf_dma);
93+
trb->bph = upper_32_bits(buf_dma);
94+
trb->size = len;
95+
trb->ctrl = type;
9796

98-
trb.hwo = 1;
99-
trb.lst = 1;
100-
trb.ioc = 1;
101-
trb.isp_imi = 1;
102-
103-
dwc3_trb_to_hw(&trb, trb_hw);
97+
trb->ctrl |= (DWC3_TRB_CTRL_HWO
98+
| DWC3_TRB_CTRL_LST
99+
| DWC3_TRB_CTRL_IOC
100+
| DWC3_TRB_CTRL_ISP_IMI);
104101

105102
memset(&params, 0, sizeof(params));
106103
params.param0 = upper_32_bits(dwc->ep0_trb_addr);
@@ -544,9 +541,10 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
544541
{
545542
struct dwc3_request *r = NULL;
546543
struct usb_request *ur;
547-
struct dwc3_trb trb;
544+
struct dwc3_trb *trb;
548545
struct dwc3_ep *ep0;
549546
u32 transferred;
547+
u32 length;
550548
u8 epnum;
551549

552550
epnum = event->endpoint_number;
@@ -557,16 +555,16 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
557555
r = next_request(&ep0->request_list);
558556
ur = &r->request;
559557

560-
dwc3_trb_to_nat(dwc->ep0_trb, &trb);
558+
trb = dwc->ep0_trb;
559+
length = trb->size & DWC3_TRB_SIZE_MASK;
561560

562561
if (dwc->ep0_bounced) {
563-
564562
transferred = min_t(u32, ur->length,
565-
ep0->endpoint.maxpacket - trb.length);
563+
ep0->endpoint.maxpacket - length);
566564
memcpy(ur->buf, dwc->ep0_bounce, transferred);
567565
dwc->ep0_bounced = false;
568566
} else {
569-
transferred = ur->length - trb.length;
567+
transferred = ur->length - length;
570568
ur->actual += transferred;
571569
}
572570

0 commit comments

Comments
 (0)