Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp1885960ybz; Thu, 30 Apr 2020 07:13:11 -0700 (PDT) X-Google-Smtp-Source: APiQypJAV4dB/+VC7KSTsq90p415DX0qRNa8eX9xD4g1jQuPM6CJTs3KM6qw4q9QrMKRFRTW5/TR X-Received: by 2002:a17:906:304d:: with SMTP id d13mr2659326ejd.159.1588255991108; Thu, 30 Apr 2020 07:13:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588255991; cv=none; d=google.com; s=arc-20160816; b=KbW000dE+McKc2NMzraF9LXYo6R6+k41Ns5Xam/cMVc5DvuXsbZ8eJI9pV6qPmm1Hq pv72049EE0uq+fkMPX049inagdtra6ZPuUSdAafC/2Mx0FdbGJ751xboV8RdUHzUxLjX LWieQxN/vqoRrsssELbK9tGDa7pl5vKaP0UrQxxlxwDKxsFpxAWHvVqgd43+KsDlP1W3 A7lIPR4dGVEvCIMBvozaJyJJBoTixzzQlJhmPSVlaCkJrxXIYc325EICXPQmKbq5NUx2 oIPgZ7j6IZ1fDNUHut428ormHHmqZkpy3BMPu1BnEXYwSCmxLGLAHJd9iDensCn0639U vJ9A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=/AUBxekiAFXgEdeWD8pYDZsQSmnLu9nPAxfvvfIuTWk=; b=eEkzqDjGP2jvYfP++hWfDJglEVvib5O8GRogYVFN0xWTlPIhpLwSebaSAQKB71U3Xh OE5bgkUefJLBXFOjal3tQQHj2yG/MRGNB0t2EdMdg07C0LTkJcKG6Y668Zbh6JqNb8HW FprwENnOOwEOdvzK5/NQzZg3LjW80j2kPm9rkTHZ2VAbng3Fj2XW2/Yt3MscFGXV38ER AJG19fKgbEHKqPXmuXcW8CdPauBnqvAW1KW9d/rqOSrZLdlADGRSngXi56fo/xer4k3g 7dHTM6XdS86gZQkrl+3pVnRqEQNV5Wz73I8bRYD6FQx3M3d1VFfYHd9IVlCV4MX8MY+3 pMJg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=NIYmexUO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id f3si5534428edy.68.2020.04.30.07.12.42; Thu, 30 Apr 2020 07:13:11 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=NIYmexUO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728069AbgD3Nv1 (ORCPT + 99 others); Thu, 30 Apr 2020 09:51:27 -0400 Received: from mail.kernel.org ([198.145.29.99]:59374 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727972AbgD3NvQ (ORCPT ); Thu, 30 Apr 2020 09:51:16 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 907192082E; Thu, 30 Apr 2020 13:51:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1588254675; bh=xgLQmrYQLaqzEq2YE5Jd2f4XvD6+UY39LmbWTDJ6BCs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NIYmexUOrWijR53/qFeIIwMKkKSxjc3tGorxfasMYiNRpFyaPLb/lBcNYexgFURoM T+EhZGqacu+p/RDTb0nfvOB1DSHjajzUJB1WWLPVlY5pL1S7tJK4FVsFITNvMFbEZI Ii7XjKDLY8KzxCCVNngW7B2drO4cJfbTE82Mfqzc= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Thinh Nguyen , Thinh Nguyen , Felipe Balbi , Sasha Levin , linux-usb@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH AUTOSEL 5.6 27/79] usb: dwc3: gadget: Properly set maxpacket limit Date: Thu, 30 Apr 2020 09:49:51 -0400 Message-Id: <20200430135043.19851-27-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200430135043.19851-1-sashal@kernel.org> References: <20200430135043.19851-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Thinh Nguyen [ Upstream commit d94ea5319813658ad5861d161ae16a194c2abf88 ] Currently the calculation of max packet size limit for IN endpoints is too restrictive. This prevents a matching of a capable hardware endpoint during configuration. Below is the minimum recommended HW configuration to support a particular endpoint setup from the databook: For OUT endpoints, the databook recommended the minimum RxFIFO size to be at least 3x MaxPacketSize + 3x setup packets size (8 bytes each) + clock crossing margin (16 bytes). For IN endpoints, the databook recommended the minimum TxFIFO size to be at least 3x MaxPacketSize for endpoints that support burst. If the endpoint doesn't support burst or when the device is operating in USB 2.0 mode, a minimum TxFIFO size of 2x MaxPacketSize is recommended. Base on these recommendations, we can calculate the MaxPacketSize limit of each endpoint. This patch revises the IN endpoint MaxPacketSize limit and also sets the MaxPacketSize limit for OUT endpoints. Reference: Databook 3.30a section 3.2.2 and 3.2.3 Signed-off-by: Thinh Nguyen Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin --- drivers/usb/dwc3/core.h | 4 +++ drivers/usb/dwc3/gadget.c | 52 ++++++++++++++++++++++++++++++--------- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 3ecc69c5b150f..ce4acbf7fef90 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -310,6 +310,10 @@ #define DWC3_GTXFIFOSIZ_TXFDEF(n) ((n) & 0xffff) #define DWC3_GTXFIFOSIZ_TXFSTADDR(n) ((n) & 0xffff0000) +/* Global RX Fifo Size Register */ +#define DWC31_GRXFIFOSIZ_RXFDEP(n) ((n) & 0x7fff) /* DWC_usb31 only */ +#define DWC3_GRXFIFOSIZ_RXFDEP(n) ((n) & 0xffff) + /* Global Event Size Registers */ #define DWC3_GEVNTSIZ_INTMASK BIT(31) #define DWC3_GEVNTSIZ_SIZE(n) ((n) & 0xffff) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 9460d42f86757..1e68c90a83781 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2227,7 +2227,6 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) { struct dwc3 *dwc = dep->dwc; int mdwidth; - int kbytes; int size; mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); @@ -2243,17 +2242,17 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) /* FIFO Depth is in MDWDITH bytes. Multiply */ size *= mdwidth; - kbytes = size / 1024; - if (kbytes == 0) - kbytes = 1; - /* - * FIFO sizes account an extra MDWIDTH * (kbytes + 1) bytes for - * internal overhead. We don't really know how these are used, - * but documentation say it exists. + * To meet performance requirement, a minimum TxFIFO size of 3x + * MaxPacketSize is recommended for endpoints that support burst and a + * minimum TxFIFO size of 2x MaxPacketSize for endpoints that don't + * support burst. Use those numbers and we can calculate the max packet + * limit as below. */ - size -= mdwidth * (kbytes + 1); - size /= kbytes; + if (dwc->maximum_speed >= USB_SPEED_SUPER) + size /= 3; + else + size /= 2; usb_ep_set_maxpacket_limit(&dep->endpoint, size); @@ -2271,8 +2270,39 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep) { struct dwc3 *dwc = dep->dwc; + int mdwidth; + int size; + + mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); + + /* MDWIDTH is represented in bits, convert to bytes */ + mdwidth /= 8; - usb_ep_set_maxpacket_limit(&dep->endpoint, 1024); + /* All OUT endpoints share a single RxFIFO space */ + size = dwc3_readl(dwc->regs, DWC3_GRXFIFOSIZ(0)); + if (dwc3_is_usb31(dwc)) + size = DWC31_GRXFIFOSIZ_RXFDEP(size); + else + size = DWC3_GRXFIFOSIZ_RXFDEP(size); + + /* FIFO depth is in MDWDITH bytes */ + size *= mdwidth; + + /* + * To meet performance requirement, a minimum recommended RxFIFO size + * is defined as follow: + * RxFIFO size >= (3 x MaxPacketSize) + + * (3 x 8 bytes setup packets size) + (16 bytes clock crossing margin) + * + * Then calculate the max packet limit as below. + */ + size -= (3 * 8) + 16; + if (size < 0) + size = 0; + else + size /= 3; + + usb_ep_set_maxpacket_limit(&dep->endpoint, size); dep->endpoint.max_streams = 15; dep->endpoint.ops = &dwc3_gadget_ep_ops; list_add_tail(&dep->endpoint.ep_list, -- 2.20.1