Chip power down and PMIC_POWER_EN

Hey guys,

I’m trying to get the beaglebone to completely power down after a ‘poweroff’ or a ‘halt -p’.
I have added an empty pm_power_off() function to the board file and it is being called correctly.

Now I need the chip to power down and most importantly to pull the PMIC_POWER_EN low to signal to the PMIC to power down.

Taking a look at the TRM I can’t find a way to directly pull the PMIC_POWER_EN pin low and I’m a bit confused in the ‘Power Management’ section (3.1.6) on the steps for setting the registers to just turn everything off.

Any direction or pointers would be very appreciated.

Thanks,
Matt

I believe that pin is controlled via the PRCM section inside the chip. It is not connected to the ARM processor. You may need to access it via the PRCM processor.

No, I have no idea how to go about doing that.

Gerald

I am with you on this.

Gerald.

Bram, Until the board file has a pm_power_off() function it will treat a ‘poweroff’ exactly like a ‘halt’. You’ll notice it says ‘System Halted’. Halt ends with a while(1); loop so there is your power issue.

Right now I’m stuck on pulling down the PMIC(PWR_EN) line since you cant exit active mode without that. Unfortunately I can’t find any good documentation about that line anywhere.
The two directions I see is through PRCM turning off power to the chip domains (dont know how or which one yet) or with the PWR_ENABLE_EN bit enabled and then generating an ALARM2 event.

So the plan is

  1. set PWR_ENABLE_EN bit
  2. set IT_ALARM2 to enable one interrupt
  3. setup ALARM2 time registers(80h-94h) to one sec after RTC time registers (0h-14h)
    4.1 check ALARM2 in RTC_STATUS_REG to see if it ran.
    4.2 check PMIC_POWER_EN pin voltage.

These registers and bits are in 20.3.5 of the TRM for anybody that also wants to try to dig in.
I’m going to be using uboot for the bit twiddling and the offset for all the RTC registers is 0x44e3e000.

Thanks for the clarification. You obviously are multiple steps ahead.
Besides I’m afraid I’m not exactly in the right thread as I got a BeagleBone which may be a little different.
So here the PMIC_PWR_EN comes from the AM335x, and its manual simply says
“PWRONRSTn input terminal should be taken low, which stops all internal clocks before power supplies
are turned off.” but I haven’t found PWRONRSTn in the SRM so far.

Well, steps in some direction. Not sure if I’m moving ahead just yet. I am working with a BeagleBone, A5 to be specific so I think youre in the right spot.
Is PWRONRSTn the pin that’s connected to the reset button? Stopping the internal clocks, then power supplies is the way I’d like to do it in the poweroff function but I can’t follow the PRCM docs well enough to be able to do that yet.
I don’t like the ALARM2 direction I’m going because it doesnt seem like the right way to do it. And it adds up to a second to the power down. (because you have to set the ALARM2 interrupt to a second later and wait) But I’d rather have this working than nothing.

AFAIK the reset button connects to the SYS_RESETn (P9 pin 10) which I connected to an external PCF8563
to restart the 'bone at a later time. That works. I looked whether pin 9 (PWR_BUT) is connected to something useful,
but it seems to go to the PMIC, so that’s not it either. I think I saw more complete schematics somewhere, that would
help, right?
BTW it’s not clear to me yet how an ALARM2 interrupt will cause a power down, but I’m still fairly new to this stuff.

Bram

Yep, I just took a look at the schematic. Right next to the nRESET_INOUT there is PORz (POWERONRST) and RTC_PORz. It looks like the are also referred to as that in the SRM so that should help your searching.

Ultimately getting the power button to work is my goal. But responding to that is the second part of this. First I want a ‘poweroff’ to actually poweroff.

To better understand where I am and the direction Im trying take a look at the SRM section 20.3.5.34 RTC_PMIC Register, register bit PWR_ENABLE_EN

Enable for PMIC_POWER_EN signal

0x0 = Disable. When Disabled, pmic_power_en signal will always be driven as 1, ON state.

0x1 = Enable. When Enabled: pmic_power_en signal will be controlled by ext_wakeup, alarm, and alarm2.

ON → OFF (Turn OFF) only by ALARM2 event.

OFF → ON (TURN ON) only by ALARM event OR ext_wakeup event.

So the process(as i understand it) hopefully will be

  1. Tell the tps65217 status reg for off state
  2. Pull PMIC_POWER_EN line low with an alarm2
  3. This will cause the tps65217 to go into OFF state and turn off power

I’m probably not looking at the right SRM, as it doesn’t have a section 20.
Looked at the schematics too though. Indeed there is PORz at B15, connected to PMIC_PGOOD,
but the tps65217 state diagram says it goes low for 1 s on a nRESET, but that isn’t connected?
Alternatively pull the PB for 8 seconds (that’s long …), which would require something connected
to pin 9 of P9.

Bram

The power button function is indeed via the expansion header and is supported on the LCD Capes. It does power down and power up the board.

The PGOOD delay is programmable on the TPS65217B as either 20ms, 100ms, 200ms, or 400ms. The count starts once thepower rails are stable.
LDO_PGOOO is for the LDO rails, VDD_RTC. It is also user settable per the PGDLY parameter, however, the defailt is 20ms, so on power up from no power applied, it will be 20ms.

Gerald

  • Bram.
    Sorry, TRM. spruh73f.pdf at http://www.ti.com/litv/pdf/spruh73f Enjoy that pandoras box. (over 4000 pages)

  • Gerald.
    I didnt notice anything in the kernel board file pertaining to the power button. I guess ill have to look closer at the lcd daughter board code. Is this the same with the 7 and 3.5 inch capes? Because it isn’t doing anything when I pull it down on the plain board without any cape. (well not nothing, i can pull it for 8 seconds to force and then at that point will poweron)
    Is there anyone specific that might know more about the inner workings of this?

Thanks,
Matt

The power button never hits the kernel. It is all in the PMIC. The PMIC can generate the interrupt if set up propler, which I can only assume the kernel does not see because no one is looking for it. After 8s of holding the button, it powers off.

As to the inner workings, I beleive it would have to work first. AFAIK there is no support for any of this in any Kernel. Just some lonely HW looking for a master.

Gerald

That all sounds right. If the only power off that works is to hold it 8 seconds then we are both understanding it correctly. That will cause a hard power off from the pmic with no regard to the kernel. Too bad though, i was really hoping for a shortcut to what i want (the power button working to trigger a ‘halt -p’ or ‘poweroff’ that cleanly powers down the board)

I have the poweroff mostly working now at least in a way that seems hacky (PMIC_POWER_EN and ALARM2) I want to do it through the PRCM but dont know how to yet so maybe ill come back to that. Next is trying to respond to that interrupt.

The example that im starting with is drivers/input/misc/twl4030-pwrbutton.c but it might be a while since I am pretty new to this kernel thing.
http://lxr.free-electrons.com/source/drivers/input/misc/twl4030-pwrbutton.c

I have a guy looking into this and trying to find all the pieces. I am hoping Power Management support will show up soon for the Kernel types. If not, we may just provide what needs to happen and how it works and let the community get it resolved.

Gerald

I have a guy looking into this and trying to find all the pieces. I am hoping Power Management support will show up soon for the Kernel types. If not, we may just provide what needs to happen and how it works and let the community get it resolved.

Gerald

Hi Gerald,

Have a look at the Nokia N900 board implementation for Power Switch implementation. You will find this in the arch/arm/mach-omap2/board-rx51-peripherals.c file. Look at twl4030_scripts which implements wakeup and sleep. Should be easy to add this for the Beagle-xM and Beaglebone.

Regards,

John

Thanks! Looking more toward what sleep modes can be supported on t eAM335x. It does not have all the capabilities of the DM3730 device. It is a different architecture and there are several key differences. I am more looking at this from a HW support standpoint in what can be done, the supported sleep modes, and how to interact with the HW. I will leave the higher level infrastructure to others to figure out how to work it all in.

Gerald

OK, I looked in the spruh73f. Indeed one of the typical applications of the alarm2 seems to be to shut off the system.
It’s not really hacky IMHO. Yes it may take a small delay, but that’s still a lot better than not having this functionality at all.
I suppose there aren’t any conflicting uses of the alarm2 either.

Do you already have a proof of concept that could be shared, so I could measure the current drawn by the system that’s
powered down?

Cheers,

Bram

Yep, having it is better than not and that was why I went down this particular route.

The easiest way to test the current drain in OFF mode is just to hold down the power button pin to ground for 8 seconds. This will force it into OFF mode and it will act the same as the eventual method. Once in OFF mode, you can even pull that pin to ground again to trigger the board to start back up after the forced power off.

I have gotten it working with commands through uboot. Below is an example that works with the beaglebone A5 with tps65217 PMIC. Some basic register knowledge is helpful, the i2c info is from the tps65217 datasheet and the rest of the memory writes are based on information from the spruh73f sheet.

Let me know what you find for power drain in the OFF state and I have a kernel patch almost working (one bug and one race condition left to fix) and will be done with that probably this week or next. This patch allows ‘poweroff’ and ‘halt -p’ to call this process and turn off the board. Are you already setup to compile your own kernel?

Enjoy!
Matt

Uboot example:

  1. Boot to the uboot prompt by pressing any key before the kernel boots

  2. Set the PMIC i2c status register to turn OFF when EN line goes down. (i2c, memory write, device 24, address A, value 0x80)

    i2c mw 24 A 80

  3. Set the memory base to the RTC registers

    base 44e3e000

  4. Enable PWR_ENABLE_EN bit (memory write, offset address 98, value in hex 0x00010000)

    mw 98 10000

  5. Enable ALARM2 interrupt once (memory write, offset address 48, value in hex 0x00000010)

    mw 48 10

  6. Copy over RTC current time to ALARM2 times for hour/day/month/year (memory copy, from address 8, to address 88, 4 times)

    cp 8 88 4

  7. This next part is where it gets slightly more complicated because you are going to manually set the ALARM2 minutes to one or two minutes after the current time.

  8. Read the current seconds, minutes. This is easy to manually do because they are in BCD and not in hex. (memory display, address zero, 2 times)

    md 0 2
    44e3e000: 00000008 00000011 (8 seconds, 11 minutes)

  9. Write to the ALARM2 minutes (seconds should already be zero) (memory write, address 84, value 0x00000012)

    mw 84 12 (12 minutes)

  10. Wait until the current time catches up to the ALARM2 time and the system will power down. If you took too long doing step 7.2 and the time has already passed, just do step 7.2 again.

  11. While you’re waiting you can keep checking the current time ( this will show all 6 fields, second, minute, hour, day, month, year)

    md 0 6

  12. And if you think you have passed your ALARM2 time you can compare above results with ALARM2 time. If so, go to step 7.2. If you went onto a new hour, you might have to start from step 6.

Let me know what you find for power drain in the OFF state and I have a
kernel patch almost working (one bug and one race condition left to fix)
and will be done with that probably this week or next. This patch allows
'poweroff' and 'halt -p' to call this process and turn off the board.

Do you have this hosted somewhere public (like Github?)? I'm willing to
help where possible (I have a small amount of kernel experience) and
need this feature.

Uboot example:

   1. Boot to the uboot prompt by pressing any key before the kernel boots
   2. Set the PMIC i2c status register to turn OFF when EN line goes down.
   (i2c, memory write, device 24, address A, value 0x80)
   > i2c mw 24 A 80
   3. Set the memory base to the RTC registers
   > base 44e3e000
   4. Enable PWR_ENABLE_EN bit (memory write, offset address 98, value in
   hex 0x00010000)
   > mw 98 10000
   5. Enable ALARM2 interrupt once (memory write, offset address 48, value
   in hex 0x00000010)
   > mw 48 10
   6. Copy over RTC current time to ALARM2 times for hour/day/month/year
   (memory copy, from address 8, to address 88, 4 times)
   > cp 8 88 4
   7. This next part is where it gets slightly more complicated because you
   are going to manually set the ALARM2 minutes to one or two minutes after
   the current time.
      1. Read the current seconds, minutes. This is easy to manually do
      because they are in BCD and not in hex. (memory display, address zero, 2
      times)
      > md 0 2
      44e3e000: 00000008 00000011 (8 seconds, 11 minutes)
      2. Write to the ALARM2 minutes (seconds should already be zero)
      (memory write, address 84, value 0x00000012)
      > mw 84 12 (12 minutes)
      8. Wait until the current time catches up to the ALARM2 time and the
   system will power down.

I can verify that this set of steps works for powering off the board.

In u-boot, idle current of 225mA at 5V DC input.
After ALARM2 power off current of 0mA at 5V DC input. I need a meter
that can go lower than 1mA I guess... I'll work on that.

-Andrew

Using a 1 Ohm resistor inline, I read 0.5 mA (0.5 mV on meter) in "off"
mode with a 5 V DC source. If I then hot-swap to a 10 Ohm resistor
inline, I read 0.57 mA (5.7 mV on meter). My meter only has 0.1 mV
precision.

That's a bit higher than the tps65217 datasheet Ioff or Isleep
currents, which TI states with max values measured in tens or 100 uA on
page 8. I'm not sure why I'm seeing higher current draw, possibly my
measurements are to blame, my meter isn't the best.

-Andrew