soc/qualcomm/x1p42100: Reduce USB OTG state enable timeout to 20ms
Reduce maximum timeout from 100ms to 20ms for OTG Enablement polling for USB Type-C. Avoid OTG enablement polling when in sink mode BUG=b:455551151 TEST: Verify USB3.0 (SS) works for C0/C1 on Google/Bluey. Background: During USB Type-C port initialization, the OTG (On-The-Go) status must be verified when the port operates in source mode to ensure proper VBUS power delivery. The previous implementation polled the OTG status register with a 100ms timeout on all ports regardless of their role. Previous Implementation Issues: 1. Overly conservative timeout: The 100ms maximum wait significantly exceeded actual requirements, as OTG enablement consistently completes in approximately 14ms under normal conditions 2. Inefficient polling logic: OTG status was polled even when ports operated in sink mode, where OTG functionality is irrelevant since the port receives rather than provides power Improvements: 1. Timeout reduction: Decreased maximum polling duration from 100ms to 20ms, maintaining adequate margin (>40% headroom) while reducing boot time by up to 80ms per sink-mode port 2. Mode-aware polling: Added logic to detect port role and skip OTG status polling entirely for sink-mode ports, as demonstrated by the "Primary in SNK mode - skipping OTG status read" log entry The changes maintain full USB3.0 SuperSpeed functionality while improving initialization efficiency. The 20ms timeout remains sufficiently conservative to accommodate normal timing variations. Debug logs: [DEBUG] QMP PHY SS0 initialized and locked in 1671us, phy_status: 0x86868686 [INFO ] Enabling Primary VBUS SuperSpeed [INFO ] Primary in SNK mode - skipping OTG status read [INFO ] Primary Type-C Status: [INFO ] Misc Status (0x2B0B): 0x1a [INFO ] Src Status (0x2B08): 0x00 [INFO ] Mode Config (0x2B44): 0x00 [INFO ] Interrupt En Cfg 1 (0x2B5E): 0xff [INFO ] State Machine Status (0x2B09): 0x02 [DEBUG] USB HS PHY initialized for index 3 [DEBUG] QMP-1x16 USB4 DP PHY SS1 init [DEBUG] QMP PHY SS1 initialized and locked in 1671us, phy_status: 0x86868686 [INFO ] Enabling Secondary VBUS SuperSpeed [INFO ] Secondary in SRC mode - OTG Status: 0x02, State: 0x02 (OTG Enabled) - Time: 14 ms [INFO ] Secondary Type-C Status: [INFO ] Misc Status (0x2B0B): 0x4b [INFO ] Src Status (0x2B08): 0x08 [INFO ] Mode Config (0x2B44): 0x00 [INFO ] Interrupt En Cfg 1 (0x2B5E): 0xff [INFO ] State Machine Status (0x2B09): 0xa6 confirmed that there are no otg polling for sink mode and polling timeout is reduced to max of 20ms. Change-Id: I7467248185c9d0526816ac62e1e1a1496440fddc Signed-off-by: Hari L <haril@qualcomm.corp-partner.google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/89826 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Kapil Porwal <kapilporwal@google.com> Reviewed-by: Paul Menzel <paulepanter@mailbox.org>
This commit is contained in:
parent
f4af55a008
commit
8449a15aed
2 changed files with 38 additions and 60 deletions
|
|
@ -106,24 +106,21 @@
|
|||
#define SCHG_DCDC_CMD_OTG 0x2740
|
||||
#define SCHG_DCDC_OTG_CFG 0x2753
|
||||
#define SCHG_DCDC_OTG_STATUS 0x270D
|
||||
#define SCHG_DCDC_ENG_SDCDC_CFG7 0x27C7
|
||||
#define SCHG_DCDC_ENG_SDCDC_GM_CLOOP_PD_OTG_BUCK_MASK 0x30
|
||||
|
||||
/* OTG Status register bit definitions */
|
||||
#define OTG_STATE_MASK 0x07
|
||||
#define OTG_STATE_DISABLED 0x00
|
||||
#define OTG_STATE_ENABLING 0x01
|
||||
#define OTG_STATE_ENABLED 0x02
|
||||
#define OTG_STATE_DISABLING 0x03
|
||||
#define OTG_STATE_ERROR 0x04
|
||||
|
||||
/* OTG Status check timeout and polling interval */
|
||||
#define OTG_STATUS_TIMEOUT_MS 100
|
||||
#define OTG_STATUS_POLL_INTERVAL_MS 2
|
||||
#define OTG_STATUS_TIMEOUT_MS 20
|
||||
#define OTG_STATUS_POLL_DELAY_MS 2
|
||||
|
||||
/* Type-C register offsets */
|
||||
#define SCHG_TYPE_C_TYPE_C_MISC_STATUS 0x2B0B
|
||||
#define SCHG_TYPE_C_TYPE_C_SRC_STATUS 0x2B08
|
||||
#define SCHG_TYPE_C_TYPE_C_MODE_CFG 0x2B44
|
||||
#define TYPEC_VBUS_STATUS_MASK BIT(5)
|
||||
#define TYPEC_SNK_SRC_MODE BIT(6)
|
||||
#define CCOUT_INVERT_POLARITY 0x03
|
||||
|
||||
/* USB Repeater SPMI Tune register offsets */
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <soc/qcom_spmi.h>
|
||||
#include <delay.h>
|
||||
#include <gpio.h>
|
||||
#include <timer.h>
|
||||
|
||||
struct usb_dwc3 {
|
||||
u32 sbuscfg0;
|
||||
|
|
@ -667,53 +668,6 @@ void usb_update_refclk_for_core(u32 core_num, bool enable)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* wait_for_otg_enabled - Waits for OTG block to reach enabled state
|
||||
* @status_reg_addr: SPMI address of the OTG status register
|
||||
* @core_name: Name of the core for logging (e.g., "SMB1", "SMB2")
|
||||
* @return: true if OTG enabled successfully, false if timeout or error
|
||||
*/
|
||||
static bool wait_for_otg_enabled(u32 status_reg_addr, const char *core_name)
|
||||
{
|
||||
u32 timeout_ms = 0;
|
||||
u8 otg_status;
|
||||
u8 otg_state;
|
||||
|
||||
while (timeout_ms < OTG_STATUS_TIMEOUT_MS) {
|
||||
otg_status = spmi_read8(status_reg_addr);
|
||||
otg_state = otg_status & OTG_STATE_MASK;
|
||||
|
||||
printk(BIOS_DEBUG, "%s OTG Status: 0x%02x, State: 0x%02x\n",
|
||||
core_name, otg_status, otg_state);
|
||||
|
||||
switch (otg_state) {
|
||||
case OTG_STATE_ENABLED:
|
||||
printk(BIOS_INFO, "%s OTG block enabled successfully\n", core_name);
|
||||
return true;
|
||||
case OTG_STATE_ERROR:
|
||||
printk(BIOS_ERR, "%s OTG block in ERROR state (0x%02x)\n",
|
||||
core_name, otg_status);
|
||||
return false;
|
||||
case OTG_STATE_DISABLED:
|
||||
case OTG_STATE_ENABLING:
|
||||
case OTG_STATE_DISABLING:
|
||||
/* Continue polling */
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_WARNING, "%s OTG block in unknown state: 0x%02x\n",
|
||||
core_name, otg_state);
|
||||
break;
|
||||
}
|
||||
|
||||
mdelay(OTG_STATUS_POLL_INTERVAL_MS);
|
||||
timeout_ms += OTG_STATUS_POLL_INTERVAL_MS;
|
||||
}
|
||||
|
||||
printk(BIOS_ERR, "%s OTG enable timeout after %d ms, final state: 0x%02x\n",
|
||||
core_name, timeout_ms, otg_state);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* enable_vbus_ss - Enables VBUS SuperSpeed for specified USB core
|
||||
* @config: Controller configuration containing SMB slave address
|
||||
|
|
@ -721,15 +675,43 @@ static bool wait_for_otg_enabled(u32 status_reg_addr, const char *core_name)
|
|||
void enable_vbus_ss(const struct dwc3_controller_config *config)
|
||||
{
|
||||
u8 slave = config->smb_slave_addr;
|
||||
u8 misc_status, otg_status = 0, otg_state = 0;
|
||||
struct stopwatch sw;
|
||||
|
||||
printk(BIOS_INFO, "Enabling %s VBUS SuperSpeed\n", config->name);
|
||||
|
||||
/* Configure SDCDC CFG7 register before enabling OTG */
|
||||
spmi_write8(SPMI_ADDR(slave, SCHG_DCDC_ENG_SDCDC_CFG7),
|
||||
SCHG_DCDC_ENG_SDCDC_GM_CLOOP_PD_OTG_BUCK_MASK);
|
||||
|
||||
spmi_write8(SPMI_ADDR(slave, SCHG_DCDC_OTG_CFG), 0x20);
|
||||
spmi_write8(SPMI_ADDR(slave, SCHG_DCDC_CMD_OTG), 0x1);
|
||||
|
||||
/* Wait for OTG block to reach enabled state */
|
||||
if (!wait_for_otg_enabled(SPMI_ADDR(slave, SCHG_DCDC_OTG_STATUS), config->name))
|
||||
printk(BIOS_ERR, "%s OTG enable failed\n", config->name);
|
||||
/* Check Type-C mode */
|
||||
misc_status = spmi_read8(SPMI_ADDR(slave, SCHG_TYPE_C_TYPE_C_MISC_STATUS));
|
||||
|
||||
/* Check SNK_SRC_MODE bit (bit 6): 0 = SNK, 1 = SRC */
|
||||
if (misc_status & TYPEC_SNK_SRC_MODE) {
|
||||
/* In SRC mode, poll OTG status until enabled */
|
||||
stopwatch_init_msecs_expire(&sw, OTG_STATUS_TIMEOUT_MS);
|
||||
while (!stopwatch_expired(&sw)) {
|
||||
otg_status = spmi_read8(SPMI_ADDR(slave, SCHG_DCDC_OTG_STATUS));
|
||||
otg_state = otg_status & OTG_STATE_MASK;
|
||||
|
||||
if (otg_state == OTG_STATE_ENABLED) {
|
||||
printk(BIOS_INFO, "%s in SRC mode - OTG Status: 0x%02x, State: 0x%02x (OTG Enabled)\n",
|
||||
config->name, otg_status, otg_state);
|
||||
return;
|
||||
}
|
||||
mdelay(OTG_STATUS_POLL_DELAY_MS);
|
||||
}
|
||||
|
||||
/* Timeout - log final state */
|
||||
printk(BIOS_INFO, "%s in SRC mode - OTG Status: 0x%02x, State: 0x%02x - Timeout after %d ms\n",
|
||||
config->name, otg_status, otg_state, OTG_STATUS_TIMEOUT_MS);
|
||||
} else {
|
||||
printk(BIOS_INFO, "%s in SNK mode - skipping OTG status read\n", config->name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -746,8 +728,7 @@ void usb_typec_status_check(const struct dwc3_controller_config *config)
|
|||
mode_cfg = spmi_read8(SPMI_ADDR(slave, SCHG_TYPE_C_TYPE_C_MODE_CFG));
|
||||
|
||||
printk(BIOS_INFO, "%s Type-C Status:\n", config->name);
|
||||
printk(BIOS_INFO, " Misc Status (0x2B0B): 0x%02x, VBUS Status (bit 5): %d\n",
|
||||
misc_status, (misc_status & TYPEC_VBUS_STATUS_MASK) ? 1 : 0);
|
||||
printk(BIOS_INFO, " Misc Status (0x2B0B): 0x%02x\n", misc_status);
|
||||
printk(BIOS_INFO, " Src Status (0x2B08): 0x%02x\n", src_status);
|
||||
printk(BIOS_INFO, " Mode Config (0x2B44): 0x%02x\n", mode_cfg);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue