From: Inochi Amaoto <inochiama@gmail.com>
To: Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Chen Wang <chen.wang@linux.dev>,
Inochi Amaoto <inochiama@gmail.com>,
Paul Walmsley <pjw@kernel.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Alexandre Ghiti <alex@ghiti.fr>,
Minas Harutyunyan <hminas@synopsys.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Longbin Li <looong.bin@gmail.com>,
Dinh Nguyen <dinguyen@opensource.altera.com>,
Paul Zimmerman <paulz@synopsys.com>, Felipe Balbi <balbi@ti.com>
Cc: devicetree@vger.kernel.org, sophgo@lists.linux.dev,
linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-usb@vger.kernel.org, Yixun Lan <dlan@gentoo.org>
Subject: [PATCH 3/4] usb: dwc2: Add USB DRD support on CV1800 series SoC
Date: Tue, 10 Nov 2026 15:06:24 +0800 [thread overview]
Message-ID: <20261110070627.217946-4-inochiama@gmail.com> (raw)
In-Reply-To: <20261110070627.217946-1-inochiama@gmail.com>
On CV1800 series SoC, it has a problem that it enters the role switch
with a persistent Session End Detected interrupt. As a result, GOTGINT
bit 2 remains set after write-one-to-clear accesses and prevents a
normal boot.
Keeping the BVALID override asserted in host mode avoids the observed
interrupt storm while allowing host enumeration and device operation.
As the BVALOVAL field is device only in the datasheet, this change is
added as a quirk.
Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
---
drivers/usb/dwc2/core.h | 3 +++
drivers/usb/dwc2/drd.c | 29 +++++++++++++++++++++--------
drivers/usb/dwc2/params.c | 1 +
3 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 298b418e6859..52ac64f67f41 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -357,6 +357,8 @@ enum dwc2_ep0_state {
* case.
* 0 - No (default)
* 1 - Yes
+ * @force_bvalid_in_host: Set the BVALID override value to 1 in host mode to
+ * avoid persistent Session End Detected interrupts.
* @power_down: Specifies whether the controller support power_down.
* If power_down is enabled, the controller will enter
* power_down in both peripheral and host mode when
@@ -460,6 +462,7 @@ struct dwc2_core_params {
bool reload_ctl;
bool uframe_sched;
bool external_id_pin_ctl;
+ bool force_bvalid_in_host;
int power_down;
#define DWC2_POWER_DOWN_PARAM_NONE 0
diff --git a/drivers/usb/dwc2/drd.c b/drivers/usb/dwc2/drd.c
index 1ad3804cbc80..4f7441a87c85 100644
--- a/drivers/usb/dwc2/drd.c
+++ b/drivers/usb/dwc2/drd.c
@@ -28,10 +28,13 @@ static void dwc2_ovr_init(struct dwc2_hsotg *hsotg)
gotgctl = dwc2_readl(hsotg, GOTGCTL);
dwc2_ovr_gotgctl(gotgctl);
gotgctl &= ~(GOTGCTL_BVALOVAL | GOTGCTL_AVALOVAL | GOTGCTL_VBVALOVAL);
- if (hsotg->role_sw_default_mode == USB_DR_MODE_HOST)
+ if (hsotg->role_sw_default_mode == USB_DR_MODE_HOST) {
gotgctl |= GOTGCTL_AVALOVAL | GOTGCTL_VBVALOVAL;
- else if (hsotg->role_sw_default_mode == USB_DR_MODE_PERIPHERAL)
+ if (hsotg->params.force_bvalid_in_host)
+ gotgctl |= GOTGCTL_BVALOVAL;
+ } else if (hsotg->role_sw_default_mode == USB_DR_MODE_PERIPHERAL) {
gotgctl |= GOTGCTL_BVALOVAL | GOTGCTL_VBVALOVAL;
+ }
dwc2_writel(hsotg, gotgctl, GOTGCTL);
spin_unlock_irqrestore(&hsotg->lock, flags);
@@ -45,18 +48,26 @@ static int dwc2_ovr_avalid(struct dwc2_hsotg *hsotg, bool valid)
u32 gotgctl = dwc2_readl(hsotg, GOTGCTL);
/* Check if A-Session is already in the right state */
- if ((valid && (gotgctl & GOTGCTL_ASESVLD)) ||
+ if ((valid && (gotgctl & GOTGCTL_ASESVLD) &&
+ (!hsotg->params.force_bvalid_in_host ||
+ (dwc2_is_host_mode(hsotg) && (gotgctl & GOTGCTL_BVALOVAL) &&
+ (gotgctl & GOTGCTL_AVALOVAL)))) ||
(!valid && !(gotgctl & GOTGCTL_ASESVLD)))
return -EALREADY;
/* Always enable overrides to handle the resume case */
dwc2_ovr_gotgctl(gotgctl);
- gotgctl &= ~GOTGCTL_BVALOVAL;
- if (valid)
+ if (valid) {
gotgctl |= GOTGCTL_AVALOVAL | GOTGCTL_VBVALOVAL;
- else
- gotgctl &= ~(GOTGCTL_AVALOVAL | GOTGCTL_VBVALOVAL);
+ if (hsotg->params.force_bvalid_in_host)
+ gotgctl |= GOTGCTL_BVALOVAL;
+ else
+ gotgctl &= ~GOTGCTL_BVALOVAL;
+ } else {
+ gotgctl &= ~(GOTGCTL_BVALOVAL | GOTGCTL_AVALOVAL |
+ GOTGCTL_VBVALOVAL);
+ }
dwc2_writel(hsotg, gotgctl, GOTGCTL);
return 0;
@@ -67,7 +78,9 @@ static int dwc2_ovr_bvalid(struct dwc2_hsotg *hsotg, bool valid)
u32 gotgctl = dwc2_readl(hsotg, GOTGCTL);
/* Check if B-Session is already in the right state */
- if ((valid && (gotgctl & GOTGCTL_BSESVLD)) ||
+ if ((valid && (gotgctl & GOTGCTL_BSESVLD) &&
+ (!hsotg->params.force_bvalid_in_host ||
+ (dwc2_is_device_mode(hsotg) && !(gotgctl & GOTGCTL_AVALOVAL)))) ||
(!valid && !(gotgctl & GOTGCTL_BSESVLD)))
return -EALREADY;
diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c
index 091bfcfef753..16db9c3c1991 100644
--- a/drivers/usb/dwc2/params.c
+++ b/drivers/usb/dwc2/params.c
@@ -222,6 +222,7 @@ static void dwc2_set_cv1800_params(struct dwc2_hsotg *hsotg)
{
struct dwc2_core_params *p = &hsotg->params;
+ p->force_bvalid_in_host = true;
p->otg_caps.hnp_support = false;
p->otg_caps.srp_support = false;
p->host_dma = false;
--
2.56.0
next prev parent reply other threads:[~2026-11-10 7:06 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 7:06 [PATCH 0/4] usb: dwc2: Add USB DRD support on CV1800 Series SoC Inochi Amaoto
2026-11-10 7:06 ` [PATCH 1/4] usb: dwc2: gadget: honor pullup requests in core_connect Inochi Amaoto
2026-11-10 7:06 ` [PATCH 2/4] usb: dwc2: drd: Sync the generic PHY mode with role requests Inochi Amaoto
2026-11-10 7:06 ` Inochi Amaoto [this message]
2026-11-10 7:06 ` [PATCH 4/4] riscv: dts: sophgo: Enable USB role switch on Huashan PI Inochi Amaoto
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261110070627.217946-4-inochiama@gmail.com \
--to=inochiama@gmail.com \
--cc=alex@ghiti.fr \
--cc=aou@eecs.berkeley.edu \
--cc=balbi@ti.com \
--cc=chen.wang@linux.dev \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dinguyen@opensource.altera.com \
--cc=dlan@gentoo.org \
--cc=gregkh@linuxfoundation.org \
--cc=hminas@synopsys.com \
--cc=krzk+dt@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux-usb@vger.kernel.org \
--cc=looong.bin@gmail.com \
--cc=palmer@dabbelt.com \
--cc=paulz@synopsys.com \
--cc=pjw@kernel.org \
--cc=robh@kernel.org \
--cc=sophgo@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®