Bring-up of the Moto Edge 40 Pro (rtwo) on the SM8550 kernel: - dts: NT37705 DSI panel with DSC, Goodix GT9916P touch, ADSP/CDSP with pmic-glink (battery, UCSI), Adreno 740, WiFi (WCN7850/ath12k), physical keys, and USB-C DisplayPort (pmic-glink altmode -> PS5169 redriver -> FSA4480 -> QMP combo PHY -> mdss_dp0) following the sm8550-qrd layout. - DP link capped at HBR (link-frequencies on &mdss_dp0_out): the DP->HDMI converter of a common USB-C hub trains fine at HBR2 but its HDMI output flickers and drops HPD; HBR x2 still covers 1080p60. - new drivers: typec-mux-ps5169.c (Parade PS5169 redriver as typec switch/retimer), panel-novatek-nt37705.c. - patches: msm DP invalid LTTPR caps + no push_idle with the link down (hardware reset on unplug), msm DSI keeps the panel DSC config, ath12k regd fixes and MHI keep-awake, ICC keepalive for the MDP fetch path. - rtwo.config / config-motorola-rtwo.aarch64: options for all of the above. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnHwDU5yL8L6qgPEN5CV5m
88 lines
3.2 KiB
Diff
88 lines
3.2 KiB
Diff
Add ath12k.mhi_keep_awake to keep the WCN7850 out of MHI M1/M2.
|
|
|
|
Diagnostic for the rtwo WiFi bring-up. With CONFIG_ATH12K_DEBUG the log
|
|
shows that the firmware returns HTC credits for the WMI endpoint
|
|
normally (trailers on EP0, ~3 ms after each command) until the moment
|
|
the device reports M1 and the host moves it to M2 (MHI_CB_IDLE, 22 us
|
|
after the last credit is spent). After that the target sends nothing on
|
|
any endpoint and there is no RDDM/SYS_ERR, so it is asleep, not crashed.
|
|
|
|
WCN7850 uses shadow registers for the CE doorbells (below
|
|
ACCESS_ALWAYS_OFF), so those writes never go through pci_ops->wakeup().
|
|
mhi_keep_awake=1 takes an MHI device wake reference right after power
|
|
up and holds it until mhi_stop, so the device stays in M0. With it
|
|
off, MHI_CB_IDLE is logged at warn level to see when it happens.
|
|
|
|
--- a/drivers/net/wireless/ath/ath12k/pci.h 2026-09-22 20:54:12.225709859 -0300
|
|
+++ b/drivers/net/wireless/ath/ath12k/pci.h 2026-09-22 20:54:12.243985679 -0300
|
|
@@ -93,6 +93,7 @@
|
|
ATH12K_PCI_FLAG_IS_MSI_64,
|
|
ATH12K_PCI_ASPM_RESTORE,
|
|
ATH12K_PCI_FLAG_MULTI_MSI_VECTORS,
|
|
+ ATH12K_PCI_FLAG_MHI_KEEP_AWAKE,
|
|
};
|
|
|
|
struct ath12k_pci_ops {
|
|
--- a/drivers/net/wireless/ath/ath12k/mhi.c 2026-09-22 20:54:12.223301456 -0300
|
|
+++ b/drivers/net/wireless/ath/ath12k/mhi.c 2026-09-22 20:54:12.244083641 -0300
|
|
@@ -18,6 +18,16 @@
|
|
#define OTP_VALID_DUALMAC_BOARD_ID_MASK 0x1000
|
|
#define MHI_CB_INVALID 0xff
|
|
|
|
+/* rtwo bring-up: the WMI endpoint runs out of HTC credits at the exact
|
|
+ * moment the device reports M1 and the host moves it to M2
|
|
+ * (MHI_CB_IDLE); after that the target never sends anything again.
|
|
+ * Holding MHI device wake for the whole session keeps it in M0, to
|
|
+ * tell whether the M1/M2 transition is what loses the WMI doorbells.
|
|
+ */
|
|
+static bool ath12k_mhi_keep_awake;
|
|
+module_param_named(mhi_keep_awake, ath12k_mhi_keep_awake, bool, 0644);
|
|
+MODULE_PARM_DESC(mhi_keep_awake, "Hold MHI device wake while powered on (never enter M1/M2)");
|
|
+
|
|
void ath12k_mhi_set_mhictrl_reset(struct ath12k_base *ab)
|
|
{
|
|
u32 val;
|
|
@@ -148,6 +158,11 @@
|
|
case MHI_CB_SYS_ERROR:
|
|
ath12k_warn(ab, "firmware crashed: MHI_CB_SYS_ERROR\n");
|
|
break;
|
|
+ case MHI_CB_IDLE:
|
|
+ /* rtwo: log at warn level so it shows up without debug_mask */
|
|
+ ath12k_warn(ab, "mhi idle: device moved to M2 (keep_awake %d)\n",
|
|
+ test_bit(ATH12K_PCI_FLAG_MHI_KEEP_AWAKE, &ab_pci->flags));
|
|
+ break;
|
|
case MHI_CB_EE_RDDM:
|
|
if (ab_pci->mhi_pre_cb == MHI_CB_EE_RDDM) {
|
|
ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
|
@@ -493,6 +508,20 @@
|
|
if (ret)
|
|
goto out;
|
|
|
|
+ if (ath12k_mhi_keep_awake) {
|
|
+ ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
|
|
+ if (ret) {
|
|
+ ath12k_warn(ab_pci->ab,
|
|
+ "mhi_keep_awake: failed to hold device wake: %d\n",
|
|
+ ret);
|
|
+ ret = 0;
|
|
+ } else {
|
|
+ set_bit(ATH12K_PCI_FLAG_MHI_KEEP_AWAKE, &ab_pci->flags);
|
|
+ ath12k_info(ab_pci->ab,
|
|
+ "mhi_keep_awake: holding device wake, M1/M2 disabled\n");
|
|
+ }
|
|
+ }
|
|
+
|
|
return 0;
|
|
|
|
out:
|
|
@@ -501,6 +530,9 @@
|
|
|
|
void ath12k_mhi_stop(struct ath12k_pci *ab_pci, bool is_suspend)
|
|
{
|
|
+ if (test_and_clear_bit(ATH12K_PCI_FLAG_MHI_KEEP_AWAKE, &ab_pci->flags))
|
|
+ mhi_device_put(ab_pci->mhi_ctrl->mhi_dev);
|
|
+
|
|
/* During suspend we need to use mhi_power_down_keep_dev()
|
|
* workaround, otherwise ath12k_core_resume() will timeout
|
|
* during resume.
|