diff mbox

N900 sleep mode (in 4.5-rc0, if that matters)

Message ID 20160125163332.GT19432@atomide.com (mailing list archive)
State New, archived
Headers show

Commit Message

Tony Lindgren Jan. 25, 2016, 4:33 p.m. UTC
* Pavel Machek <pavel@ucw.cz> [160123 04:11]:
> 
> So far, the LEDs stubbornly stay on :-(. Machine is booted off
> sd-card, and I'm connected to it over wifi. GSM is active, X is
> running.

If LEDs stay on, you're not entering deeper idle states.

> Normally, ping looks like this:
> 
> 64 bytes from 192.168.43.15: icmp_seq=371 ttl=64 time=2.18 ms
> 64 bytes from 192.168.43.15: icmp_seq=372 ttl=64 time=2.21 ms
> 64 bytes from 192.168.43.15: icmp_seq=373 ttl=64 time=2.94 ms
> 
> When I enable the off mode:
> echo 1 > /sys/kernel/debug/pm_debug/enable_off_mode
> 
> Wifi is no longer happy:
> 
> 64 bytes from 192.168.43.15: icmp_seq=426 ttl=64 time=351 ms
> 64 bytes from 192.168.43.15: icmp_seq=427 ttl=64 time=178 ms
> 64 bytes from 192.168.43.15: icmp_seq=428 ttl=64 time=2.36 ms

Latencies of several hundred ms are expected when hitting off
mode during idle as the latency for power off the system during
idle is long. It could also be that there's a wakeirq config
missing somewhere. Does the WLAN have a separate GPIO irq?

> and touchscreen stops working:
> 
> [99480.564910] tsc2005 spi1.0: TSC200X not responding - resetting
> [99486.995758] bq27xxx-battery 2-0055: battery is not calibrated!
> ignoring capacity values
> [99488.564147] tsc2005 spi1.0: TSC200X not responding - resetting
> [99495.550018] bq27xxx-battery 2-0055: battery is not calibrated!
> ignoring capacity values
> [99496.564208] tsc2005 spi1.0: TSC200X not responding - resetting
> [99504.129852] bq27xxx-battery 2-0055: battery is not calibrated!
> ignoring capacity values
> [99504.564208] tsc2005 spi1.0: TSC200X not responding - resetting

This could be because we're still lacking i2c-omap + pinctrl
handling for erratum 1.158. Without that, any GPIO pins not in
GPIO bank 1 used for enabling devices may have glitches during
off-mode.

The workaround for now is to mux those pins permanently with
PIN_INPUT_PULLUP | MUX_MODE7 to keep them high using the
internal pull. So in this case, maybe give a try for adding
a pinctrl entry for tsc2005 for gpio104 to have it always
in PIN_INPUT_PULLUP | MUX_MODE7.

The long term solution is to do this dynamically for each GPIO
pin.. I do have some WIP patches for that but those still need
work before I dare to post them.

> echo 0 > /sys/kernel/debug/pm_debug/enable_off_mode
> 
> Fixes both wifi and touchscreen. Is off_mode expected to break
> touchscreen? Any ideas what needs to be shut down so that the sleep
> leds go off?

Yes you can dump the idlest regs during idle and see the blockers.
Below is a hack patch I've been using, that could potentially
be turned into something we could actually merge. Needs to have
separate hooks for various SoCs though, this works only on omap3..

> Power consumption seems to be in 500mA range, regardless of
> off_mode. That would mean about 2 hours of battery life, AFAICT.

Sounds like you have USB connected and charging? You can
get into just few mW range with the mainline kernel for sure
on omap3. It's just a quetion of fixing whatever few drivers
that are still causing issues on n900.

Typically you need at least USB disconnected and LCD blanked
to start hitting the deeper idle states :)

Regards,

Tony

8< -----------
From: Tony Lindgren <tony@atomide.com>
Date: Thu, 26 Mar 2015 14:01:31 -0700
Subject: [PATCH] Test patch for dumping omap3 off idle blocking bits

Not for merging.

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

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Pavel Machek Jan. 25, 2016, 10:23 p.m. UTC | #1
Hi!

First, thanks for the help!

> > So far, the LEDs stubbornly stay on :-(. Machine is booted off
> > sd-card, and I'm connected to it over wifi. GSM is active, X is
> > running.
> 
> If LEDs stay on, you're not entering deeper idle states.

Yes... Strange thing is, I'm not entering deeper idle states, and it still breaks my wifi ;-).

> > 64 bytes from 192.168.43.15: icmp_seq=427 ttl=64 time=178 ms
> 
> Latencies of several hundred ms are expected when hitting off
> mode during idle as the latency for power off the system during
> idle is long. It could also be that there's a wakeirq config
> missing somewhere. Does the WLAN have a separate GPIO irq?

Fair enough.

        wl1251_pins: pinmux_wl1251 {
		     		   pinctrl-single,pins = < 0x0ce (PIN_OUTPUT | MUX_MODE4)
		     		   /* gpio 87 => w\ l1251 enable */
				                           0x05a (PIN_INPUT | MUX_MODE4)
		     		   /* gpio 42 => w\ l1251 irq */
				                   >;
 };

Aha. wl1251 is on the spi bus, too.

&mcspi4 {
        pinctrl-names = "default";
	        pinctrl-0 = <&mcspi4_pins>;

        wl1251@0 {
	...
	                interrupt-parent = <&gpio2>;
			                interrupts = <10 IRQ_TYPE_NONE>; /* gpio line 42 */
        };

And yes, it has a GPIO irq -- irq 42. What should be configured to
make gpio 42 wake the system from deep idle?

> > and touchscreen stops working:
> > 
> > [99480.564910] tsc2005 spi1.0: TSC200X not responding - resetting
...
> This could be because we're still lacking i2c-omap + pinctrl
> handling for erratum 1.158. Without that, any GPIO pins not in
> GPIO bank 1 used for enabling devices may have glitches during
> off-mode.
> 
> The workaround for now is to mux those pins permanently with
> PIN_INPUT_PULLUP | MUX_MODE7 to keep them high using the
> internal pull. So in this case, maybe give a try for adding
> a pinctrl entry for tsc2005 for gpio104 to have it always
> in PIN_INPUT_PULLUP | MUX_MODE7.

So the glitches on the GPIOs reset the tsc2005, even when it should be
operational? That would explain stuff.

I'll try to figure out the pinmux stuff. ... but I guess touchscreen
is not really usable with screen off.

> The long term solution is to do this dynamically for each GPIO
> pin.. I do have some WIP patches for that but those still need
> work before I dare to post them.

No patch is too ugly for testing :-).

> Yes you can dump the idlest regs during idle and see the blockers.
> Below is a hack patch I've been using, that could potentially
> be turned into something we could actually merge. Needs to have
> separate hooks for various SoCs though, this works only on omap3..

Thanks, wil try.

> > Power consumption seems to be in 500mA range, regardless of
> > off_mode. That would mean about 2 hours of battery life, AFAICT.
> 
> Sounds like you have USB connected and charging? You can
> get into just few mW range with the mainline kernel for sure
> on omap3. It's just a quetion of fixing whatever few drivers
> that are still causing issues on n900.
> 
> Typically you need at least USB disconnected and LCD blanked
> to start hitting the deeper idle states :)

Right. So I was able to get SD-card to work, so USB was disconnected,
but I was watching power consumption figures in a GTK window... on a
LCD. Ok. I guess I can monitor the power consumption over the wlan.

Thanks!
								Pavel
Tony Lindgren Jan. 25, 2016, 10:50 p.m. UTC | #2
* Pavel Machek <pavel@ucw.cz> [160125 14:24]:
> Hi!
> 
> First, thanks for the help!
> 
> > > So far, the LEDs stubbornly stay on :-(. Machine is booted off
> > > sd-card, and I'm connected to it over wifi. GSM is active, X is
> > > running.
> > 
> > If LEDs stay on, you're not entering deeper idle states.
> 
> Yes... Strange thing is, I'm not entering deeper idle states, and it still breaks my wifi ;-).
> 
> > > 64 bytes from 192.168.43.15: icmp_seq=427 ttl=64 time=178 ms
> > 
> > Latencies of several hundred ms are expected when hitting off
> > mode during idle as the latency for power off the system during
> > idle is long. It could also be that there's a wakeirq config
> > missing somewhere. Does the WLAN have a separate GPIO irq?
> 
> Fair enough.
> 
>         wl1251_pins: pinmux_wl1251 {
> 		     		   pinctrl-single,pins = < 0x0ce (PIN_OUTPUT | MUX_MODE4)
> 		     		   /* gpio 87 => w\ l1251 enable */
> 				                           0x05a (PIN_INPUT | MUX_MODE4)
> 		     		   /* gpio 42 => w\ l1251 irq */
> 				                   >;
>  };
> 
> Aha. wl1251 is on the spi bus, too.
> 
> &mcspi4 {
>         pinctrl-names = "default";
> 	        pinctrl-0 = <&mcspi4_pins>;
> 
>         wl1251@0 {
> 	...
> 	                interrupt-parent = <&gpio2>;
> 			                interrupts = <10 IRQ_TYPE_NONE>; /* gpio line 42 */
>         };
> 
> And yes, it has a GPIO irq -- irq 42. What should be configured to
> make gpio 42 wake the system from deep idle?

We should do dev_pm_set_dedicated_wake_irq() on the pin related
to gpio42 in the WLAN driver. That way the pinctrl interrupt will
wake up the system and the GPIO interrupt should show up as it
presumably is a level interrupt. The interrupt probably should be
requested by wlcore as the SDIO chips also can have a GPIO interrupt.
That's the interrupts-extended entries we already have for 8250 and
MMC etc.

> > The workaround for now is to mux those pins permanently with
> > PIN_INPUT_PULLUP | MUX_MODE7 to keep them high using the
> > internal pull. So in this case, maybe give a try for adding
> > a pinctrl entry for tsc2005 for gpio104 to have it always
> > in PIN_INPUT_PULLUP | MUX_MODE7.
> 
> So the glitches on the GPIOs reset the tsc2005, even when it should be
> operational? That would explain stuff.

Yeah.

> I'll try to figure out the pinmux stuff. ... but I guess touchscreen
> is not really usable with screen off.

Could still wake up the system I guess if configured.

> > Typically you need at least USB disconnected and LCD blanked
> > to start hitting the deeper idle states :)
> 
> Right. So I was able to get SD-card to work, so USB was disconnected,
> but I was watching power consumption figures in a GTK window... on a
> LCD. Ok. I guess I can monitor the power consumption over the wlan.

Yeah in the long run initramfs + ssh over WLAN is probably the best
to develop with if you don't have a serial console wired up. That
allows hitting idle states with mosh at least working OK as long as
the WLAN wakeirq works properly.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pavel Machek Jan. 26, 2016, 2 p.m. UTC | #3
Hi!

> > Power consumption seems to be in 500mA range, regardless of
> > off_mode. That would mean about 2 hours of battery life, AFAICT.
> 
> Sounds like you have USB connected and charging? You can
> get into just few mW range with the mainline kernel for sure
> on omap3. It's just a quetion of fixing whatever few drivers
> that are still causing issues on n900.
> 
> Typically you need at least USB disconnected and LCD blanked
> to start hitting the deeper idle states :)

Ok, no 4.4 kernel + your patch this time, USB disconnected, LCD
blanked, but wifi connected and X session running on inactive vt. GSM
connected to network.

It seems like I have rather lot of blocking bits:

usbhost_pwrdm
(ON),OFF:3321,RET:37501,INA:0,ON:40823,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0
sgx_pwrdm
(OFF),OFF:1,RET:0,INA:0,ON:1,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0
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:3321,RET:33,INA:0,ON:3355,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0
dss_pwrdm
(ON),OFF:3321,RET:19014,INA:0,ON:22336,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0
cam_pwrdm
(ON),OFF:3321,RET:37500,INA:2,ON:40824,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0
neon_pwrdm (ON),OFF:3321,RET:37501,INA:0,ON:40823,RET-LOGIC-OFF:0
mpu_pwrdm
(ON),OFF:3321,RET:37501,INA:0,ON:40823,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0
iva2_pwrdm
(OFF),OFF:1,RET:1,INA:0,ON:2,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0,RET-MEMBANK2-OFF:0,RE
T-MEMBANK3-OFF:0,RET-MEMBANK4-OFF:0
usbhost_clkdm->usbhost_pwrdm (1)
sgx_clkdm->sgx_pwrdm (0)
per_clkdm->per_pwrdm (19)
cam_clkdm->cam_pwrdm (1)
dss_clkdm->dss_pwrdm (1)
d2d_clkdm->core_pwrdm (0)
iva2_clkdm->iva2_pwrdm (0)
mpu_clkdm->mpu_pwrdm (0)
core_l4_clkdm->core_pwrdm (20)
core_l3_clkdm->core_pwrdm (2)
neon_clkdm->neon_pwrdm (0)
00001fff 48005020 (fa005020) cm_idlest_per blocking bits: 0007e000
ffdffe8d 48004a20 (fa004a20) cm_idlest1_core blocking bits: 00200072
0000000d 48004a28 (fa004a28) cm_idlest3_core

cm_idlest1_core changes periodicall often, to 00218072. The rest seems
constant.

I'm using script below:

#!/bin/bash
uarts=$(find /sys/class/tty/ttyO*/device/power/ -type d)
for uart in $uarts; do
    echo 3000 > $uart/autosuspend_delay_ms
    done
    uarts=$(find /sys/class/tty/ttyO*/power/ -type d)
    for uart in $uarts; do
        echo enabled > $uart/wakeup
	    echo auto > $uart/control
	    done
	    sudo mount /dev/zero -t debugfs /sys/kernel/debug/
	    echo 1 > /sys/kernel/debug/pm_debug/enable_off_mode

sudo cat /sys/kernel/debug/pm_debug/count

. Does it mean that more than 5 devices block the suspend?

Best regards,
								Pavel
Tony Lindgren Jan. 26, 2016, 5:25 p.m. UTC | #4
* Pavel Machek <pavel@ucw.cz> [160126 06:01]:
> 
> It seems like I have rather lot of blocking bits:
> 
> 00001fff 48005020 (fa005020) cm_idlest_per blocking bits: 0007e000

Looks like most of these are for GPIO banks, that's OK those get saved
and restored in the idle loop.

Here bit 18 UART4 is a mystery though.. It's uart4 on 36xx but reserved
on 34xx. I do have that too on my n900, but it's hitting off mode with
v4.4.

> ffdffe8d 48004a20 (fa004a20) cm_idlest1_core blocking bits: 00200072
> 0000000d 48004a28 (fa004a28) cm_idlest3_core
> 
> cm_idlest1_core changes periodicall often, to 00218072. The rest seems
> constant.

For cm_idlest1_core 42 is the answer.. Here you have bits 4 and 5
blocking which is for OTG and it's PHY. That's a known issue with
musb and setting pm_runtime_irq_safe() on the MUSB parent.

If you do rmmod omap2430 and phy-twl4030usb chances are the LEDs will
start going off assuming the McSPI bit goes low with WLAN idling.

Looks like we have some regression with v4.5-rc1 where n900 is not
hitting deeper idle states though. I'll run git bisect between
v4.4..v4.5-rc1.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tony Lindgren Jan. 26, 2016, 10:51 p.m. UTC | #5
* Tony Lindgren <tony@atomide.com> [160126 09:26]:
> 
> Looks like we have some regression with v4.5-rc1 where n900 is not
> hitting deeper idle states though. I'll run git bisect between
> v4.4..v4.5-rc1.

Sent more info about that in thread "PM regression with commit
5de85b9d57ab PM runtime re-init in v4.5-rc1" FYI.

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pavel Machek Jan. 30, 2016, 8:02 p.m. UTC | #6
Hi!

> > ffdffe8d 48004a20 (fa004a20) cm_idlest1_core blocking bits: 00200072
> > 0000000d 48004a28 (fa004a28) cm_idlest3_core
> > 
> > cm_idlest1_core changes periodicall often, to 00218072. The rest seems
> > constant.
> 
> For cm_idlest1_core 42 is the answer.. Here you have bits 4 and 5
> blocking which is for OTG and it's PHY. That's a known issue with
> musb and setting pm_runtime_irq_safe() on the MUSB parent.
> 
> If you do rmmod omap2430 and phy-twl4030usb chances are the LEDs will
> start going off assuming the McSPI bit goes low with WLAN idling.

Ok, so I tried to compile kernel without omap2430/phy-twl4030usb
. That did not help. So I thought, ok, maybe rmmod is needed to
trigger some powersaving? But that is not exactly easy to do:

pavel@n900:/my/tui/ofone$ sudo insmod /my/modules/omap2430.ko
pavel@n900:/my/tui/ofone$ sudo insmod /my/modules/phy-twl4030-usb.ko
pavel@n900:/my/tui/ofone$ sudo rmmod phy-twl4030-usb.ko
Error: Module phy_twl4030_usb is in use
pavel@n900:/my/tui/ofone$

Any ideas what jumps to use the modules? Charger code?

Thanks,
									Pavel
Pavel Machek Jan. 30, 2016, 8:14 p.m. UTC | #7
On Sat 2016-01-30 21:02:45, Pavel Machek wrote:
> Hi!
> 
> > > ffdffe8d 48004a20 (fa004a20) cm_idlest1_core blocking bits: 00200072
> > > 0000000d 48004a28 (fa004a28) cm_idlest3_core
> > > 
> > > cm_idlest1_core changes periodicall often, to 00218072. The rest seems
> > > constant.
> > 
> > For cm_idlest1_core 42 is the answer.. Here you have bits 4 and 5
> > blocking which is for OTG and it's PHY. That's a known issue with
> > musb and setting pm_runtime_irq_safe() on the MUSB parent.
> > 
> > If you do rmmod omap2430 and phy-twl4030usb chances are the LEDs will
> > start going off assuming the McSPI bit goes low with WLAN idling.
> 
> Ok, so I tried to compile kernel without omap2430/phy-twl4030usb
> . That did not help. So I thought, ok, maybe rmmod is needed to
> trigger some powersaving? But that is not exactly easy to do:
> 
> pavel@n900:/my/tui/ofone$ sudo insmod /my/modules/omap2430.ko
> pavel@n900:/my/tui/ofone$ sudo insmod /my/modules/phy-twl4030-usb.ko
> pavel@n900:/my/tui/ofone$ sudo rmmod phy-twl4030-usb.ko
> Error: Module phy_twl4030_usb is in use
> pavel@n900:/my/tui/ofone$
> 
> Any ideas what jumps to use the modules? Charger code?

I tried a kernel without charger code, and no luck, rmmod fails the
same way. dmesg says:
[  111.093078] wlan0: authenticated
[  111.097442] wlan0: associate with 06:27:22:f9:10:6a (try 1/3)
[  111.104553] wlan0: RX AssocResp from 06:27:22:f9:10:6a (capab=0x421
status=0 aid=2)
[  111.104705] wlan0: AP has invalid WMM params (AIFSN=1 for ACI 2),
will use 2
[  111.104736] wlan0: AP has invalid WMM params (AIFSN=1 for ACI 3),
will use 2
[  111.256652] wlan0: associated
[  184.681427] HS USB OTG: no transceiver configured
[  184.681488] musb-hdrc musb-hdrc.0.auto: musb_init_controller failed
with status -517
[  184.681976] HS USB OTG: no transceiver configured
[  184.682006] musb-hdrc musb-hdrc.0.auto: musb_init_controller failed
with status -517
[  187.690338] twl4030_usb 48070000.i2c:twl@48:twl4030-usb:
Initialized TWL4030 USB module
[  187.698303] musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, bulk
combine, bulk split, HB-ISO Rx, HB-ISO Tx, SoftConn)
[  187.698333] musb-hdrc: MHDRC RTL version 1.400
[  187.698333] musb-hdrc: setup fifo_mode 4
[  187.698394] musb-hdrc: 28/31 max ep, 16384/16384 memory
pavel@n900:/my/tui/ofone$

Best regards,
									Pavel
diff mbox

Patch

--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -142,10 +142,76 @@  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_show_counters(struct seq_file *s, void *unused)
 {
 	pwrdm_for_each(pwrdm_dbg_show_counter, s);
 	clkdm_for_each(clkdm_dbg_show_counter, s);
+	cm_per_dump(s);
+	cm_core_dump(s);
 
 	return 0;
 }