This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
工具/软件:Linux
你好
我目前正在使用基于4.11.12的定制内核、但我已确认最新的4.9 ti-SDK 中存在相同的配置。
我已应用最新的 PM 主线补丁、我可以通过 GPIO0线路和 UART0暂停和从 DeepSlep0和待机状态恢复。 因此、我的配置中就有该功能。
我需要通过 GPIO2引脚从待机模式唤醒。 我已将问题缩小到 GPIO_SysConfig 中的 ENAWAKEUP 位。 它不是由 SDK 或主线源代码中的驱动程序设置的。
在深入探讨这一点时、我注意到有一些寄存器偏移被用于唤醒使能、这些偏移在 AM335x 系列的技术参考中没有定义。
也就是 #define OMAP4_GPIO_WAKE_EN 0x0120
GPIO 寄存器定义中未列出该偏移量、到目前为止、我无法找到谁在设置唤醒使能位。 我能够用 dev2mem 手动插入寄存器、获得一个成功的唤醒周期、但是当我再次查看寄存器时、它已经被恢复为禁用状态。 我觉得驱动程序中的上下文恢复正在进行、但我找不到对寄存器的直接引用。
主线和 SDK 驱动程序是相同的、因此似乎存在于整个电路板上。 我发现很多线程都试图从非 GPIO0引脚唤醒、但没有提到这个位、这似乎使它起作用。
软件团队有什么想法吗?
Matt
您好、Matthew、
您是否使用 AM335x TI 电路板(EVM、SK、BBB)或定制电路板? 我建议您首先仅使用 AM335x TI PSDK4.1 (内核4.9.41)、成功后、您可以将代码传输到4.11内核。
您是否使用 GPIO2 GPIO 密钥、唤醒功能修改 DTS 文件?
我将检查您的具体问题、同时查看以下链接是否将提供帮助:
processors.wiki.ti.com/.../Linux_Core_Power_Management_User's_Guide_(v4.4)
processors.wiki.ti.com/.../Debugging_AM335x_Suspend-Resume_Issues
www.ti.com/.../sprac74a.pdf
e2e.ti.com/.../572939
e2e.ti.com/.../550811
e2e.ti.com/.../546397
e2e.ti.com/.../498933
e2e.ti.com/.../626971
此致、
帕维尔
[引用用户="Matthew Harlan"] 我已将问题范围缩小到 GPIO_SysConfig 中的 ENAWAKEUP 位。 它不是由 SDK 或主线源代码中的驱动程序设置的。
GPIO Linux 驱动程序(OMAP4-GPIO)为:
linux-kernel/drivers/gpio/GPIO-omap.c
Linux-kernel/include/linux/platform_data/gpio-omap.h
我确认 GPIO 驱动程序未修改 GPIO_SysConfig[2] ENAWAKEUP。
该寄存器和位似乎在以下文件中进行了描述和修改:
linux-kernel/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
/*
*'GPIO'类:用于 GPIO 0、1、2、3
*
静态结构 omap_hwmod_class_sysconfig am33xx_gpio_sysc ={
.rev_fs = 0x0000、
.sysc_fs = 0x0010、
.syss_off = 0x0114、
.sysc_flags =(SYSC_HWAS_AUTOIDLE | SYSC_HW_ENAWAKEUP |
SYSC_FAS_SIDLEMODE | SYSC_FAS_SOFTRESET |
SYSS_has 复位状态)、
.idlemodes =(sidle_force | sidle_no | sidle_smart|
sidle_smart_wKUP)、
.sysc_fields =&omap_hwmod_sysc_type1、
};
Linux-kernel/arch/arm/mach-OMAP2/omap_hwmod.h
linux-kernel/arch/arm/mach-omap2/omap_hwmod.c
此致、
帕维尔
[引用用户="Matthew Harlan"]
在深入探讨这一点时、我注意到有一些寄存器偏移被用于唤醒使能、这些偏移在 AM335x 系列的技术参考中没有定义。
也就是 #define OMAP4_GPIO_WAKE_EN 0x0120
GPIO 寄存器定义中未列出该偏移量、到目前为止、我无法找到谁在设置唤醒使能位。
[/报价]
我们在 AM335x TRM 中没有这样的寄存器(偏移量0x120)、并且这个 OMAP4_GPIO_WAKE_EN 寄存器不在 GPIO-OMAP.c 驱动程序中使用。 GPIO-OMAP.c 驱动程序中使用的唯一唤醒相关寄存器是 OMAP4_GPIO_IRQWAKEN0 (偏移量0x44)。
此致、
帕维尔
Pavel、
这在定制板上。
对于我的 GPIO0唤醒、我的构建中包含了这个 dtsi。
/{
VBATT_WAKEUP{
兼容="GPIO-keys";
pinctrl-names ="default";
pinctrl-0 =<VBATT_WAKE_PINs>;
WAKE@0{
标签="WAKE";
linux、code = ;
GPIO =<&GPIO0 6 GPIO_ACTIVE_HIGH_>;
唤醒源;
};
};
};
在深度睡眠0和待机模式下、我通过该输入获得正确操作、但我知道 GPIO0的行为是 A、但由于唤醒域与外设的不同、它的行为是不同的。
对于我的 GPIO2、它用作来自触摸屏控制器的中断。 我已删除触控驱动程序并替换为类似的设备树条目。
/{
LCD_WAKEUP{
兼容="GPIO-keys";
pinctrl-names ="default";
pinctrl-0 =<&tp_GPIO_PINs>;
WAKE@0{
标签="TP";
linux、code = ;
GPIO =<&GPIO2 5 GPIO_ACTIVE_HIGH_>;
唤醒源;
};
};
};
这对 GPIO2无效。
我在挂起和恢复时已转储 GPIO 寄存器、我的 IRQWAKE 寄存器已正确设置。 该模块的 SysConfig ENWAKEUP 似乎从未设置。 但是、如果我手动执行它、它会起作用。
这种情况发生在基于4.9 SDK 的内核和我的4.11内核上。
我感觉这被埋在 hwmod 驱动程序中的某个位置、因为我跟踪了 hwmod 中的 enable_wakeup 调用。 但到目前为止、我还没有找到自动设置 SysConfig 值的位置。
Matt
Matt、
[引用用户="Matthew Harlan"]
对于我的 GPIO2、它用作来自触摸屏控制器的中断。 我已删除触控驱动程序并替换为类似的设备树条目。
/{
LCD_WAKEUP{
兼容="GPIO-keys";
pinctrl-names ="default";
pinctrl-0 =<&tp_GPIO_PINs>;
WAKE@0{
标签="TP";
linux、code = ;
GPIO =<&GPIO2 5 GPIO_ACTIVE_HIGH_>;
唤醒源;
};
};
};
这对 GPIO2无效。
[/报价]
您的 DTS 文件看起来正确。 您还可以检查 GPIO_keys.c 驱动程序、确保解析唤醒源条目(button->wakeup 设置为1)、调用函数 device_init_wake()、enable_IRQ_wake ()、pm_STOP_WAKE_WAKEUP ()、pm_WAKEUP_EVENT ()、 已定义 CONFIG_PM_SLEEP。
还请确保在 GPIO2_5引脚上有唤醒事件、并使用示波器进行检查。
[引用用户="Matthew Harlan">我在暂停和恢复时转储了 GPIO 寄存器、我的 IRQWAKE 寄存器设置正确。 该模块的 SysConfig ENWAKEUP 似乎从未设置。 但是、如果我手动执行它、它会起作用。
如您所知、此寄存器/位在引导和暂停/恢复期间在 OMAP-hwmod.c 驱动程序中设置。 检查是否调用了相关函数:omap_hwmod_enable()、_omap_device_enable_hwmods()、omap_device_enable()、omap_device_build_from _dt()、_omap_device_notifier_call()
_omap_device_enable_hwmods ()、omap_device_enable ()、omap_device_build_from _dt ()、_omap_device_nodifier_call ()函数位于:
linux-kernel/arch/arm/mach-omap2/omap_device.c
此致、
帕维尔
我找到了一个解决方案。
最后、这是 Dave Gerlach 的暗示、结果证明了这一点。
在 hwmod 驱动程序中、ENWAKEUP 位作为空闲序列的一部分进行设置。 如果在 hwmod 定义中设置了正确的标志、则_idle_sysc 将更改寄存器。 我通过战略性 printk 找到了这一点。
但是、到空闲的转换也会调用 SoC_ops.disable_module 和_disable_clocks。 我不确定哪一方是违规方、但其中一项更改是防止 GPIO 模块生成唤醒事件。 GPIO0的处理方式与唤醒电源域内的处理方式不同。
我的解决方案是将所需的 GPIO 保持在一起、使其不会进入空闲状态。 您可以通过将 devicetree 属性 ti、no-idle 添加到 GPIO 模块来实现此目的。
我在 am33xx.dtsi 中进行了更改
GPIO2:GPIO@481ac000{ compatible ="ti、OMAP4-GPIO"; ti、hwmods ="GPIO3"; GPIO 控制器; #GPIO-cells =<2>; 中断控制器; #interrupt-cells =<2>; reg =<0x481ac000 0x1000>; 中断=<32>; ti、无空闲; };
Dave 提到这可能会破坏 Deepsleep0、但我似乎仍然能够使用我的 GPIO0源唤醒器件。 我们没有使用 Deepsleep0、因此它对我们来说并不重要、因此我没有再对它进行测试。
您的里程数可能非常高、但它对我们很有用。
Matt