cancel
Showing results for 
Search instead for 
Did you mean: 

Linux "gpio-poweroff" won't load

allard
Senior

I'm trying to add the linux "gpio-poweroff" function to the distribution package. I've added the following to my device tree:

gpio-poweroff {
	compatible = "gpio-poweroff";
	gpios = <&gpioe 1 GPIO_ACTIVE_HIGH>;
	timeout-ms = <3000>;
};

The kernel/device tree compiles OK, but the poweroff function does not work. The logs give the following lines about the poweroff:

[    1.482136] poweroff-gpio gpio-poweroff: gpio_poweroff_probe: pm_power_off function already registered
[    1.482174] poweroff-gpio: probe of gpio-poweroff failed with error -16

So I guess openSTLinux already has some handler attached? How do I disable this?

1 ACCEPTED SOLUTION

Accepted Solutions
Emma
Associate II

Hi @allard​ ,

gpio-poweroff is registered to psci_sys_poweroff in firmware/psci.c which invokes a PSCI (Power State Coordination Interface

) function which is implemented in TF-A.

I added code to set my poweroff gpio in TF-A. Not sure if this is the correct way to do it. If you do this, also note that the system_off_mode is defined to STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF in the CubeMX-generated device tree for TF-A; I changed it to STM32_PM_SHUTDOWN.

View solution in original post

8 REPLIES 8
Christophe Guibout
ST Employee

Hi @allard​ ,

gpio-poweroff is not loadable because STM32MP supports power domains.

pm_power_off is already registered in stm32_pm_domain_add function (drivers/soc/st/stm32_pm_domain.c) :

domain->genpd.power_off = stm32_pd_power_off;

This feature is under CONFIG_STM32_PM_DOMAINS switch, but I don't recommand to disable it as it's part of SoC.

BR,

Christophe

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Emma
Associate II

Hi @allard​ ,

gpio-poweroff is registered to psci_sys_poweroff in firmware/psci.c which invokes a PSCI (Power State Coordination Interface

) function which is implemented in TF-A.

I added code to set my poweroff gpio in TF-A. Not sure if this is the correct way to do it. If you do this, also note that the system_off_mode is defined to STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF in the CubeMX-generated device tree for TF-A; I changed it to STM32_PM_SHUTDOWN.

allard
Senior

@Emma​ @Christophe Guibout​ 

This should be enough info to get me going, thanks both.

hi, can you sow me some example of how to add gpio in tf-a to power off my board?

In file plat/st/stm32mp1/stm32mp1_low_power.c, function enter_shutdown(void) I put the following code after the DDR has been set in self-refresh:

/* Activate the poweroff GPIO (active low) */

uint32_t poweroff_gpio_clk = GPIOB;

uintptr_t poweroff_gpio_port = GPIOB_BASE;

uint32_t poweroff_gpio_pin = 10;

stm32mp_clk_enable(poweroff_gpio_clk);

/* Bit Reset Register (BRR): Set bit to set low output value */

mmio_setbits_32(poweroff_gpio_port + 0x28, 1 << poweroff_gpio_pin);

/* Output Type Register (OTYPER): Clear bit to configure push-pull */

mmio_clrbits_32(poweroff_gpio_port + 0x04, 1 << poweroff_gpio_pin);

/* Mode Register (MODER): 01 for GPIO output */

mmio_clrsetbits_32(poweroff_gpio_port, 1 << (poweroff_gpio_pin*2 +1),

                  1 << (poweroff_gpio_pin*2));

udelay(100);

/* If that didn't work, switch off the PMIC */

If your GPIO is active high, use BSRR (offset 0x18) instead of BRR.

Also set system_off_soc_mode to <STM32_PM_SHUTDOWN> in your device tree.

Tnx Emma, it power off the pmic immediately ? there is a way to make some delay of couple of seconds you think?

Hi there, 

I know that this reply was posted 3 years ago, but I'm facing the same problem right now. 

Your solution seems the best around the internet, but I have a question: I can't see the enter_shutdown() function in my distribution! In stm32mp1_low_power.c file, I Have enter_cstop() and enter_csleep() functions...    

I also can see these pretty interesting lines: 

void stm32_enter_low_power(uint32_t mode, uint32_t nsec_addr)
{
	switch (mode) {
	case STM32_PM_SHUTDOWN:
		break;

	case STM32_PM_CSLEEP_RUN:
		enter_csleep();
		break;

	default:
		enter_cstop(mode, nsec_addr);
		break;
	}
}

Did you create the function yourself?  If yes, how did you write that? 
I think that is a pretty big feature setting a gpio-poweroff for a Linux-embedded board, I don't know why ST doesn't give any documentation about that... 
Thanks a lot! 

Rflor
Associate II

Hi everyone,

I’m facing the same issue described by SScar.2 and I would like to ask for confirmation that I’m modifying the correct place.My goal is to generate an active-HIGH GPIO signal after the system power-off sequence, to act as a PS_HOLD signal that cuts the external power supply.I tried to implement the code shared by Emma in the past, but the original function she mentioned (enter_shutdown()) no longer exists in the current TF-A sources.
So I attempted to adapt it to the current code structure.

I modified TF-A in the following way: myir-st-tfa/plat/st/stm32mp1/stm32mp1_pm.c

I added this code inside the stm32_system_off() path to force an active-HIGH GPIO (PE4):

/* --- POWER OFF GPIO (active HIGH) --- */

uint32_t poweroff_gpio_clk = GPIOE;
uintptr_t poweroff_gpio_port = GPIOE_BASE;
uint32_t poweroff_gpio_pin = 4;

/* Enable GPIO clock */
stm32mp_clk_enable(poweroff_gpio_clk);

/* Configure output push-pull */
mmio_clrbits_32(poweroff_gpio_port + 0x04, 1 << poweroff_gpio_pin);

/* Configure as output (MODER = 01) */
mmio_clrsetbits_32(poweroff_gpio_port + 0x00,
                   3U << (poweroff_gpio_pin * 2),
                   1U << (poweroff_gpio_pin * 2));

/* Set pin HIGH using BSRR */
mmio_write_32(poweroff_gpio_port + 0x18,
              1U << poweroff_gpio_pin);

udelay(100);

I also modified the TF-A fw-config DTS: myir-st-tfa/fdts/myb-stm32mp135x-512m-fw-config.dts

&{/} {
system_off_soc_mode = <STM32_PM_SHUTDOWN>;
};

Then I rebuilt TF-A

The firmware builds correctly, but when I shut down the system (using shutdown -h now or from my application), I do not see any change on the GPIO when measuring with an oscilloscope.

Is this code placed in the correct location for a PSCI SYSTEM_OFF sequence on STM32MP13x? 

Or is the power-off flow handled by OP-TEE, meaning the GPIO should be toggled somewhere else?

Am I missing a required pinctrl or secure configuration for GPIO usage in TF-A/OP-TEE?

Any guidance would be very appreciated.
Thanks in advance.