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/AM3358:GPIO 从待机状态唤醒

Guru**** 1958595 points
Other Parts Discussed in Thread: SYSCONFIG
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/633767/linux-am3358-gpio-wake-up-from-standby

器件型号:AM3358
Thread 中讨论的其他器件:SysConfig

工具/软件: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

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    已通知 PM 专家。 他们将在这里作出回应。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、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

x 出现错误。请重试或与管理员联系。