Controlling SATA Power Rail


aprayoga

Recommended Posts

To continue discussion from Helios64 Support

 

On 11/9/2020 at 11:39 PM, ebin-dev said:

 

@aprayoga I am still interested in controlling the power of rail A and B. You mentioned that the power is controlled by the bootloader, but that the delay would be user configurable sometime.

 

I would like to almost always power off rail A: In my use case rail A contains two hard disks supposed to alternatively back up the content of the SSDs in rail B - i.e once a day or even only once a week. The remaining time it would be beneficial to power off the hard drives in order to eliminate start/stop cycles and to make those drives inaccessible (protection against malware).

 

Would there be a solution to make this user configurable - i.e by setting the delay to a very large number ? 

Currently there is no plan to support to disable the power but it's interesting to know such use case.

If we implemented this feature, you would need to go u-boot prompt to enable and disable the power. would this acceptable for you?

 

Under Linux device tree, the power rail declared as regulator node with regulator-always-on property. This prevent kernel (and user) to turn off the regulator.

Unless we are able to create device node for the SATA port, to act as consumer of the regulator, we can't remove the regulator-always-on property.

Link to post
Share on other sites
Armbian is a community driven open source project. Do you like to contribute your code?

7 hours ago, aprayoga said:

Currently there is no plan to support to disable the power but it's interesting to know such use case.

If we implemented this feature, you would need to go u-boot prompt to enable and disable the power. would this acceptable for you?

 

Actually I just picked up a suggestion to completely power off rails A and/or B by @gprovost three months ago ( see here ).

 

It would be really appeciated if you implemented this feature. Once it is implemented I would try to seek a way to configure u-boot from linux such that the power to rails A and/or B is enabled/disabled upon the next reboot.

Link to post
Share on other sites

@ebin-dev I notice that the effects of the advertisement are let to the free interpretation of the clients, but it is always instructive. :D

 

The same configuration as you

I use 3 SSD for separate services (Sync, Cloud, Server) and two hard disks for archiving.

My two disks are both 10 years old and make a shitty noise but it's still spinning for the moment.
I put and remove the disk from unit to avoid the noise of the whole house, if I can let the disks in the unit and just run a special reboot for maintenance this is not a problem for me.

I'm planning on redundancy for the server service with another ARM card later on.

 

@aprayoga if you can create a parameter on the boot loader to choose the option like power rails I will be the happiest of your customers,

but if I can learn how to do it myself I will be the happiest user :)

Link to post
Share on other sites

 

I'm missing a universe of understanding

I lack knowledge

Please what am I missing?

Can i have pin 32 & 33 HW schematic?

 

Spoiler

cat /sys/kernel/debug/regulator/regulator_summary

vcc12v_dcin 3 2 0 unknown 12000mV 0mA 12000mV 12000mV

   f8000000.pcie-vpcie12v 1 0mA 0mV 0mV

   vcc12v_dcin_bkup 5 4 0 unknown 12000mV 0mA 12000mV 12000mV

       vcc12v_hdd 1 0 0 unknown 12000mV 0mA 12000mV 12000mV

       vcc5v0_hdd 1 0 0 unknown 5000mV 0mA 5000mV 5000mV

power_hdd_a 1 0 0 unknown 0mV 0mA 0mV 0mV

power_hdd_b 1 0 0 unknown 0mV 0mA 0mV 0mV

 

Reading

 Kernel User

cat /sys/kernel/debug/regulator/regulator_summary

cat /sys/kernel/debug/pinctrl/*/gpio-ranges

cat /sys/kernel/debug/pinctrl/*/pinmux-pins

cat /sys/kernel/debug/pinctrl/*/pinmux-functions

cat /sys/kernel/debug/pinctrl/*/pingroups

cat /sys/kernel/debug/pinctrl/*/pinconf-pins

cat /sys/kernel/debug/pinctrl/*/pinconf-groups

 

Reading

 U-boot

u-boot-helios64/doc/README.gpio

u-boot-helios64/doc/README.bootmenu

u-boot-helios64/drivers/power/regulator/regulator_common.c

u-boot-helios64/include/power/regulator.h

 

u-boot-helios64/arch/arm/dts/rk3399-helios.dts

// SPDX-License-Identifier: (GPL-2.0+ OR MIT)

/*

* Copyright (c) 2020 Aditya Prayoga (aditya@kobol.io)

*/

 

/dts-v1/;

#include <dt-bindings/input/linux-event-codes.h>

#include <dt-bindings/pwm/pwm.h>

#include <dt-bindings/input/input.h>

#include <dt-bindings/usb/pd.h>

#include "rk3399.dtsi"

#include "rk3399-opp.dtsi"

 

/ {

model = "Helios64";

compatible = "kobol,helios64", "rockchip,rk3399";

<...>

/* Rail A Disk Down 1-3 */

 power_hdd_a: power-hdd-a {

 compatible = "regulator-fixed";

 enable-active-high;

 gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>; /* gpio 1-0 pin 32 */

 pinctrl-names = "default";

 pinctrl-0 = <&hdd_a_power>;

 regulator-name = "power_hdd_a";

 regulator-always-on;

 regulator-boot-on;

 startup-delay-us = <2500000>;

 };

/* Rail B Disk Up 4-5 */

 power_hdd_b: power-hdd-b {

 compatible = "regulator-fixed";

 enable-active-high;

 gpio = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>; /* gpio 1-1 pin 33 */

 pinctrl-names = "default";

 pinctrl-0 = <&hdd_b_power>;

 regulator-name = "power_hdd_b";

 regulator-always-on;

 regulator-boot-on;

 startup-delay-us = <2500000>;

};

<...>

gpio-keys {

 compatible = "gpio-keys";

 autorepeat;

 pinctrl-names = "default";

 pinctrl-0 = <&pwrbtn>, <&user1btn>, <&wake_on_lan>;

/*

 wol {

 debounce-interval = <100>;

 gpios = <&gpio0 RK_PB0 GPIO_ACTIVE_LOW>;

 label = "Wake-On-LAN";

 linux,code = <KEY_WAKEUP>;

 wakeup-source;

 };

*/

<...>

};

};

&pinctrl {

<...>

 power {

  hdd_a_power: hdd-a-power {

  rockchip,pins =

  <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;

 };

 

 hdd_b_power: hdd-b-power {

  rockchip,pins =

  <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;

 };

<...>

};

};

<..end>

 

Path : /u-boot-helios64/board/kobol/helios64/helios64.c

<...>

#ifdef CONFIG_LAST_STAGE_INIT

static void auto_power_enable(void)

{

struct gpio_desc *enable, *clock;

if (gpio_hog_lookup_name("AUTO_ON_EN_D", &enable)) {

debug("Fail to get AUTO_ON_EN_D\n");

return;

}

if (gpio_hog_lookup_name("AUTO_ON_EN_CLK", &clock)) {

debug("Fail to get AUTO_ON_EN_CLK\n");

return;

}

dm_gpio_set_value(enable, 1);

dm_gpio_set_value(clock, 1);

mdelay(10);

dm_gpio_set_value(clock, 0);

}

static void pcie_reset(void)

{

ofnode node;

struct gpio_desc reset_gpio;

node = ofnode_path("/pcie@f8000000");

if (!ofnode_valid(node)) {

debug("%s: no /pcie@f8000000 node\n", __func__);

return;

}

if (gpio_request_by_name_nodev(node, "ep-gpios", 0,

&reset_gpio, GPIOD_IS_OUT)) {

debug("%s: could not find a /config/sysreset-gpio\n", __func__);

return;

}

m_gpio_set_value(&reset_gpio, 0);

mdelay(1000);

//dm_gpio_set_value(&reset_gpio, 1);

gpio_free_list_nodev(&reset_gpio, 1);

}

int last_stage_init(void)

{

auto_power_enable();

/* Give some extra time for HDD to spin up */

//mdelay(6000);

//pcie_reset();

#ifdef CONFIG_PCI

//pci_init();

//mdelay(2000);

scsi_scan(true);

//mdelay(2000);

#endif

return 0;

}

#endif

<...end>

 

 

Link to post
Share on other sites

@allen--smithee

if you need to modify the bootloader, you can start from these lines

https://github.com/armbian/build/blob/master/patch/u-boot/u-boot-rockchip64-mainline/add-board-helios64.patch#L1671-L1687

You can add parameter checking there. Maybe check certain U-Boot environment variable, maybe check for certain file in the filesystem.

You could also remove it completely and modify /boot/boot.scr instead, to enable/disable the HDD power.

 

Another thing to explore, you could remove the afromentioned u-boot function and also remove the power rail nodes from linux device tree

https://github.com/armbian/build/blob/master/patch/kernel/rockchip64-current/add-board-helios64.patch#L239-L259

and then when you need to enable it, just access the gpio from sysfs.

 

Edited by aprayoga
Link to post
Share on other sites