RK3588 EVB1蓝牙休眠唤醒调试

news/2024/10/28 20:28:21/

RK3588 EVB1蓝牙休眠唤醒调试

rk平台支持二级休眠,即SOC大部分电都关了,只留下唤醒源需要的电.

rk3588 evb1因为蓝牙相关的部分大部分IO没有接到PMU电源域,所以调试起来需要另外配置,以方便快速验证.

下面,我们以博通AP6275p芯片为例, 分析下快速验证蓝牙休眠唤醒需要的设定(前提是蓝牙已经正常bringup能工作的情况下).

一. DTS全部配置

为了方便只要答案的同学, 这里直接给出配置:

Subject: [PATCH] dts:arm64:rk3588:config for bt wake up from deep sleepChange-Id: Ia382dbf9860a76d2558f6f6f5f330cd46f58689d
---.../boot/dts/rockchip/rk3588-evb1-bt-wakeup.dtsi   | 52 ++++++++++++++++++++++.../boot/dts/rockchip/rk3588-evb1-lp4-v10.dts      |  1 +2 files changed, 53 insertions(+)create mode 100755 arch/arm64/boot/dts/rockchip/rk3588-evb1-bt-wakeup.dtsidiff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-bt-wakeup.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-evb1-bt-wakeup.dtsi
new file mode 100755
index 0000000..75f79b8
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-bt-wakeup.dtsi
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+&rockchip_suspend {
+	rockchip,sleep-mode-config = <
+		(0
+		| RKPM_SLP_ARMOFF_DDRPD
+		)
+	>;
+	rockchip,wakeup-config = <
+		(0
+		| RKPM_CPU0_WKUP_EN
+		| RKPM_GPIO_WKUP_EN
+		)
+	>;
+
+	status = "okay";
+};
+
+&vdd_log_s0 {
+	regulator-state-mem {
+	regulator-on-in-suspend;
+	regulator-suspend-microvolt = <750000>;
+	};
+};
+
+&vcc_3v3_s0 {
+	regulator-state-mem {
+		regulator-on-in-suspend;
+	};
+};
+
+&vcc_1v8_s0 {
+	regulator-state-mem {
+		regulator-on-in-suspend;
+	};
+};
+
+&vdd_1v8_pll_s0 {
+	regulator-state-mem {
+		regulator-on-in-suspend;
+	};
+};
+
+&wireless_bluetooth {
+	interrupt-parent = <&gpio3>;
+	interrupts = <RK_PA0 IRQ_TYPE_LEVEL_LOW>;
+	wakeup-source;
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10.dts
index d1a264f..ecfbad8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10.dts
@@ -8,6 +8,7 @@#include "rk3588-evb1-lp4.dtsi"#include "rk3588-evb1-imx415.dtsi"
+#include "rk3588-evb1-bt-wakeup.dtsi"#include "rk3588-android.dtsi"

二 分析.

2.1 rockchip_suspend节点

+&rockchip_suspend {
+	rockchip,sleep-mode-config = <
+		(0
+		| RKPM_SLP_ARMOFF_DDRPD
+		)
+	>;
+	rockchip,wakeup-config = <
+		(0
+		| RKPM_CPU0_WKUP_EN
+		| RKPM_GPIO_WKUP_EN
+		)
+	>;
+
+	status = "okay";
+};

这里解释下RKPM_GPIO_WKUP_EN节点, 这里是因为唤醒源是BT_WAKE_HOST_H,即GPIO3_A0. 所以RKPM_GPIO_WKUP_EN唤醒源需要开启.

其他修改部分不是很清晰, 比如sleep-mode-config少休眠了很多模块, 待以后进一步澄清.

2.2 电源域

2.2.1 芯片内部电源域

为了支持休眠唤醒, IC部分,至少BT_WAKE_HOST, UART_RTS, BT_REG_ON(图中1,2,3)几个引脚所在的IC模块要有电.

BT_WAKE_HOST因为是中断源.

UART_RTS是为了保持高电平, 不让外部蓝牙模块发信号(这里存疑, 可能是错的. 因为IC没电也可能可以钳住这个电平).

BT_REG_ON是为了保持高电平让外部蓝牙模块不掉电(同上, 可能是错的).

image-20220514163919983

图1

查3588 TRM, 以上电源域都在VD_LOGIC, 所以以下配置打开:

+&vdd_log_s0 {
+	regulator-state-mem {
+	regulator-on-in-suspend;
+	regulator-suspend-microvolt = <750000>;
+	};
+};

image-20220514165159523

图2

2.2.1 芯片外部电源域.

查图1 BT_WAKE_HOST, UART_RTS, BT_REG_ON外部电源域, 就是图1中的4部分, 即VCC_1V8_S0. 所以这个电源域打开.

+&vcc_1v8_s0 {
+	regulator-state-mem {
+		regulator-on-in-suspend;
+	};
+};

2.2.3 蓝牙模块电源域

image-20220514170425699

如上, VCC_3V3_S0(1)和VCC_1V8_S0(2)要有电, 所以对应节点要打开.VCC_1V8_S0已经打开, 所以还需要打开VCC_3V3_S0.

+&vcc_3v3_s0 {
+	regulator-state-mem {
+		regulator-on-in-suspend;
+	};
+};

2.2.4 32K电源域

image-20220514174426166

这里需要说明的是, 假设蓝牙模块外部32K晶振是3588供电, 那对应的3588模块内部外部电源域都要打开, 但我们是8563供32K.

但是如下配置现在已经无法解释了, 不知道当初为啥要配置. (也许是当初看错, 也许是忘了, 这怪开始没总结. 要验证只能重新搭环境看看这个配置是否必要, 等验证了再回来更新)

+&vdd_1v8_pll_s0 {
+	regulator-state-mem {
+		regulator-on-in-suspend;
+	};
+};

2.4.5 中断源配置

如下, 意思是打开中断源. 当然, 即使不需要中断唤醒, "BT,wake_host_irq"节点还是需要配置.

+&wireless_bluetooth {
+	interrupt-parent = <&gpio3>;
+	interrupts = <RK_PA0 IRQ_TYPE_LEVEL_LOW>;
+	wakeup-source;
+};

3 4 rtk蓝牙特殊处理

在调试rtk 8852be芯片蓝牙唤醒过程中,发现Host系统唤醒后,收不到正确的按键值,从而导致系统重新进休眠.
其原因是芯片驱动不完善,醒来后没法通过蓝牙H5协议和Host蓝牙协议栈握手(博通芯片使用H4协议,并用RTS引脚控制蓝牙芯片的数据发送,所以无此问题).

目前解决办法是,在蓝牙唤醒过程中, rfkill-bt.c的驱动中,发送power up按键,这样,系统就能亮屏.不过, 这里有一个side-effect: 唤醒后因为无法握手会重启蓝牙协议栈,导致蓝牙遥控器连上时间会延迟.

diff --git a/net/rfkill/rfkill-bt.c b/net/rfkill/rfkill-bt.c
index 719a23d..e5209e98 100644
--- a/net/rfkill/rfkill-bt.c
+++ b/net/rfkill/rfkill-bt.c
@@ -39,7 +39,7 @@#include <linux/of_device.h>#include <linux/of_gpio.h>#endif
-
+#include <linux/input.h>#if 0#define DBG(x...) pr_info("[BT_RFKILL]: " x)#else
@@ -72,6 +72,7 @@ struct rfkill_rk_data {};static struct rfkill_rk_data *g_rfkill = NULL;
+static struct input_dev *power_key_dev;static const char bt_name[] =#if defined(CONFIG_BCM4330)
@@ -721,6 +722,26 @@ static int rfkill_rk_probe(struct platform_device *pdev)LOG("%s device registered.\n", pdata->name);+       /* register input device */
+       power_key_dev = input_allocate_device();
+       if (!power_key_dev) {
+               LOG("ir_dev: not enough memory for input device\n");
+               return -ENOMEM;
+       }
+
+       power_key_dev->name = "bt-powerkey";
+       power_key_dev->id.bustype = BUS_HOST;
+
+       power_key_dev->evbit[0] = BIT_MASK(EV_KEY);
+       set_bit(KEY_POWER, power_key_dev->keybit);
+
+       ret = input_register_device(power_key_dev);
+       if (ret) {
+               input_free_device(power_key_dev);
+               LOG("ir_rx_init: register input device exception, exit\n");
+               return -EBUSY;
+       }
+return 0;fail_rfkill:
@@ -776,9 +797,32 @@ static int rfkill_rk_remove(struct platform_device *pdev)return 0;}+static int rfkill_rk_pm_resume(struct device *pdev)
+{
+       LOG("%s, wake up now send power key.....", __func__);
+
+       input_report_key(power_key_dev, KEY_POWER, 1);
+       input_sync(power_key_dev);
+       msleep(1);
+       input_report_key(power_key_dev, KEY_POWER, 0);
+       input_sync(power_key_dev);
+
+       return 0;
+}
+
+static int rfkill_rk_pm_suspend(struct device *pdev)
+{
+       LOG("%s", __func__);
+
+       return 0;
+}
+
+static const struct dev_pm_ops rfkill_rk_pm_ops = {.prepare = rfkill_rk_pm_prepare,.complete = rfkill_rk_pm_complete,
+       .suspend = rfkill_rk_pm_suspend,
+       .resume = rfkill_rk_pm_resume,};#ifdef CONFIG_OF

4 结束

完.


http://www.ppmy.cn/news/503410.html

相关文章

JTA1145 休眠唤醒调试总结

最近因为项目&#xff0c;选择了这颗芯片&#xff0c;花了2天多时间&#xff0c;总算是把这个芯片的休眠唤醒功能基本调了&#xff0c;在这里做一个技术总结&#xff0c;希望可以帮到有需要的人&#xff01; TJA1145芯片简介 TJA1145是一款高速CAN收发器&#xff0c;可在控制…

(24)STM32——待机唤醒(低功耗)笔记

目录 学习目标 运行结果 待机唤醒 模式 待机模式 寄存器 配置 代码 总结 学习目标 本节我们讲解的是有关待机唤醒的知识&#xff0c;这部分知识在51中并未涉及到&#xff0c;我感觉还是有点意思的&#xff0c;有点类似与我们手机的锁屏功能和关机功能&#xff0c;只是…

STM32L031低功耗深度睡眠RTC唤醒注意事项

0. 第一可以进入休眠&#xff0c;第二次无法进入休眠&#xff0c;折腾了好久。后来想想应该是进入休眠后立刻被唤醒了&#xff0c;应该是上次的唤醒中断没清除。在启动唤醒前加入以下语句&#xff0c;问题解决。 __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); //清除标志&#xf…

1568_AURIX_TC275_电源管理_唤醒配置与状态

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 如果有待机RAM保持的功能激活了&#xff0c;那么唤醒以及复位都不会进行RAM的重新初始化。 PORST相关的滤波开了之后&#xff0c;可以抵抗500ns的尖峰脉冲干扰。 CPU不仅可以请求自我进入i…

Stm32 RTC周期唤醒待机模式

Stm32 RTC周期唤醒待机模式 一、前言 二、开发环境 1、软件&#xff1a;CubeMXMDK 2、硬件&#xff1a;超纬电子-NB开发板 三、参考资料 四、实现过程 1、配置CubeMX 2、程序修改 2.1、添加 wukeup函数&#xff0c;通过调用函数进入待机模式 void WKUP_EnterStandby(v…

怎样把LoRa模块功耗降到极致

怎样把LoRa模块功耗降到极致 一. 引言 能耗对于电池供电的产品来说是一个重大的问题&#xff0c;一旦电能耗尽设备将“罢工”&#xff0c;在某些场合电能意味着电子产品的生命。物联网时代将会有越来越多电池供电的设备通过无线通信连接&#xff0c;降低能耗再次摆在工程师…

安卓系统耗电太快?针对wakelock(唤醒锁)的设置优化教程

导读: android为了确保应用程序的正确执行&#xff0c;提供了wakelock(唤醒锁)的api&#xff0c;wakelock是一种锁的机制&#xff0c;只要有应用拿着这个锁&#xff0c;系统就无法进入休眠&#xff0c;手机耗电的问题&#xff0c;其实大部分是这个锁正不正常的问题。 手机上应…

root后待机耗电,手机root后耗电

手机获取了root对手机耗电有影响? 手机获取ROOT权限后一般情况下都不会对手机耗电有影响&#xff0c;甚至将ROOT权限授予安全软件后&#xff0c;还可以一定程度上减少耗电量&#xff0c;增加手机待机时间。 手机获取ROOT权限的主要危害&#xff1a; 1.第三方的恶意软件可以利用…