Hi, * Merlijn Wajer <merlijn@xxxxxxxxxx> [191209 02:32]: > I'm trying to figure out how I can try get my Nokia N900 to go into off > mode. ... > BTW, the kernel is patched with SGX support, so that may have something > to do with it, but it seems to actually be idle, if I am reading > pm_debug/count correctly. [2] OK that's good to hear :) > # cat idle.sh > #!/bin/sh > > export UART_IDLE_MS=5000 > idle_uarts() { > # Enable autosuspend > uarts=$(find /sys/bus/platform/devices/*.serial/power/ -type d) > for uart in ${uarts}; do > echo -n ${UART_IDLE_MS} > ${uart}/autosuspend_delay_ms > echo -n enabled > ${uart}/wakeup > echo -n auto > ${uart}/control > done > > # Configure wake-up from suspend > uarts=$(find /sys/class/tty/tty[SO]*/power/ -type d 2>/dev/null) > for uart in ${uarts}; do > echo -n enabled > ${uart}/wakeup > done > } > > idle_uarts > > mount -t debugfs debugfs /sys/kernel/debug > echo 1 > /sys/kernel/debug/pm_debug/enable_off_mode The above should do the right thing. > [2] # cat /sys/kernel/debug/pm_debug/count > usbhost_pwrdm > (ON),OFF:0,RET:670,INA:0,ON:671,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0 > sgx_pwrdm (OFF),OFF:24,RET:0,INA:0,ON:24,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0 Yup sgx_pwrdm above looks good. > core_pwrdm > (ON),OFF:0,RET:0,INA:0,ON:1,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0,RET-MEMBANK2-OFF:0 > per_pwrdm (ON),OFF:0,RET:0,INA:0,ON:1,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0 Here per_pwrdm has some device(s) blocking idle for both per and core. Below is my old debug patch that provides more info on the blocking bits. It's probably some cm_idlest_per bit(s) that's blocking compared to the known good 00010000 and 00000042 values. Care to try it and reply with the cm_idlest_per and cm_idlest1_core values you're seeing? I've checked that n900 idles fine for me with omap2plus_defconfig and minimal user space for v5.4. Regards, Tony 8< ----------------------- Allows seeing the deeper idle state blockers in /sys/kernel/debug/pm_debug/count. For example, when off idle is working on beaglboard xm, this is what i see: # sleep 5; cat /sys/kernel/debug/pm_debug/count ... 0006ffff 48005020 (fa005020) cm_idlest_per blocking bits: 00010000 e7ffffbd 48004a20 (fa004a20) cm_idlest1_core blocking bits: 00000042 0000000d 48004a28 (fa004a28) cm_idlest3_core --- arch/arm/mach-omap2/pm-debug.c | 68 ++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -136,10 +136,78 @@ static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user) return 0; } +#include "iomap.h" + +struct dregs { + const char *desc; + u32 phys; + void __iomem *virt; + u32 mask; +}; + +#define PER_CM_BASE 0x48005000 +#define PER_CM_REG(name, offset, mask) \ + { name, PER_CM_BASE + offset, \ + OMAP2_L4_IO_ADDRESS(PER_CM_BASE + offset), mask, } + +static struct dregs cm_per[] = { + PER_CM_REG("cm_idlest_per", 0x20, 0xfff80000), /* p 513 */ + { NULL, }, +}; + +#define CORE_CM_BASE 0x48004a00 +#define CORE_CM_REG(name, offset, mask) \ + { name, CORE_CM_BASE + offset, \ + OMAP2_L4_IO_ADDRESS(CORE_CM_BASE + offset), mask, } + +static struct dregs cm_core[] = { + CORE_CM_REG("cm_idlest1_core", 0x20, 0x9c800109), /* p 467 */ + CORE_CM_REG("cm_idlest3_core", 0x28, 0xfffffffb), + { NULL, }, +}; + +void __dregs_dump(struct dregs *dregs, struct seq_file *s) +{ + for (; dregs->desc; dregs++) { + u32 val, blockers; + + val = __raw_readl(dregs->virt); + + seq_printf(s, "%08x %08x (%p) %s", + val, dregs->phys, dregs->virt, + dregs->desc); + + if (dregs->mask) { + blockers = ~val; + blockers &= ~dregs->mask; + + if (blockers) + seq_printf(s, " blocking bits: %08x", + blockers); + } + + seq_printf(s, "\n"); + } +} + +void cm_per_dump(struct seq_file *s) +{ + __dregs_dump(cm_per, s); +} + +void cm_core_dump(struct seq_file *s) +{ + __dregs_dump(cm_core, s); +} + static int pm_dbg_counters_show(struct seq_file *s, void *unused) { pwrdm_for_each(pwrdm_dbg_show_counter, s); clkdm_for_each(clkdm_dbg_show_counter, s); + if (cpu_is_omap34xx()) { + cm_per_dump(s); + cm_core_dump(s); + } return 0; } -- 2.24.0