diff mbox

[U-Boot,6/8] power: axp209: Add support for voltage rate control on LDO3

Message ID 20170301125224.25994-7-oliver@schinagl.nl
State Changes Requested
Delegated to: Jaehoon Chung
Headers show

Commit Message

Olliver Schinagl March 1, 2017, 12:52 p.m. UTC
The AXP209 has voltage rate control, or can set a slew rate, for LDO3.
This allows for the power to gradually rise to the desired voltage,
instead of spiking up quickly. Reason to have this can be to reduce the
inrush currents for example.

There are 3 slopes to choose from, the default, 'none' is a voltage rise
of 0.0167 V/uS, a 1.6 mV/uS and a 0.8 mV/uS voltage rise.

Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
---
 drivers/power/Kconfig  | 33 +++++++++++++++++++++++++++++++++
 drivers/power/axp209.c | 24 ++++++++++++++++++++++++
 include/axp209.h       | 16 ++++++++++++++++
 3 files changed, 73 insertions(+)

Comments

Marcus Weseloh March 1, 2017, 3:10 p.m. UTC | #1
Hi Oliver,

2017-03-01 13:52 GMT+01:00 Olliver Schinagl <oliver@schinagl.nl>:

> +#define AXP209_VRC_LDO3_EN             BIT(3)
> +#define AXP209_VRC_DCDC2_EN            BIT(2)
> +#define AXP209_VRC_LDO3_800uV_uS       (BIT(1) | AXP209_VRC_LDO3_EN)
> +#define AXP209_VRC_LDO3_1600uV_uS      AXP209_VRC_LDO3_EN
>

Does that mean that the description of the LDO3/DCDC2 VRC control on the
linux-sunxi wiki [1] and the PDF datasheet [2] are wrong? They say that VRC
for LDO3 is enabled if the bit is 0, disabled when the bit is 1. And that
the default value is enabled.

[1]
http://linux-sunxi.org/AXP209#REG_25H:_DC-DC2.2FLDO3_dynamic_voltage_scaling_parameter_settings
[2] http://dl.linux-sunxi.org/AXP/AXP209_Datasheet_v1.0en.pdf

Cheers,

  Marcus
Olliver Schinagl March 1, 2017, 4:02 p.m. UTC | #2
Hey Marcus,

On 01-03-17 16:10, Marcus Weseloh wrote:
> Hi Oliver,
>
> 2017-03-01 13:52 GMT+01:00 Olliver Schinagl <oliver@schinagl.nl
> <mailto:oliver@schinagl.nl>>:
>
>     +#define AXP209_VRC_LDO3_EN             BIT(3)
>     +#define AXP209_VRC_DCDC2_EN            BIT(2)
>     +#define AXP209_VRC_LDO3_800uV_uS       (BIT(1) | AXP209_VRC_LDO3_EN)
>     +#define AXP209_VRC_LDO3_1600uV_uS      AXP209_VRC_LDO3_EN
>
>
> Does that mean that the description of the LDO3/DCDC2 VRC control on the
> linux-sunxi wiki [1] and the PDF datasheet [2] are wrong? They say that
> VRC for LDO3 is enabled if the bit is 0, disabled when the bit is 1. And
> that the default value is enabled.

Yes you are correct (and well spotted) that the datasheet is wrong. It 
took us some time to figure out why it wasn't working :)

I thought I updated the wiki, but I must have done it incorrectly. I 
will fix it immediatly.

olliver


>
> [1]
> http://linux-sunxi.org/AXP209#REG_25H:_DC-DC2.2FLDO3_dynamic_voltage_scaling_parameter_settings
> [2] http://dl.linux-sunxi.org/AXP/AXP209_Datasheet_v1.0en.pdf
>
> Cheers,
>
>   Marcus
Chen-Yu Tsai March 1, 2017, 4:19 p.m. UTC | #3
On Thu, Mar 2, 2017 at 12:02 AM, Olliver Schinagl
<o.schinagl@ultimaker.com> wrote:
> Hey Marcus,
>
> On 01-03-17 16:10, Marcus Weseloh wrote:
>>
>> Hi Oliver,
>>
>> 2017-03-01 13:52 GMT+01:00 Olliver Schinagl <oliver@schinagl.nl
>> <mailto:oliver@schinagl.nl>>:
>>
>>     +#define AXP209_VRC_LDO3_EN             BIT(3)
>>     +#define AXP209_VRC_DCDC2_EN            BIT(2)
>>     +#define AXP209_VRC_LDO3_800uV_uS       (BIT(1) | AXP209_VRC_LDO3_EN)
>>     +#define AXP209_VRC_LDO3_1600uV_uS      AXP209_VRC_LDO3_EN
>>
>>
>> Does that mean that the description of the LDO3/DCDC2 VRC control on the
>> linux-sunxi wiki [1] and the PDF datasheet [2] are wrong? They say that
>> VRC for LDO3 is enabled if the bit is 0, disabled when the bit is 1. And
>> that the default value is enabled.
>
>
> Yes you are correct (and well spotted) that the datasheet is wrong. It took
> us some time to figure out why it wasn't working :)
>
> I thought I updated the wiki, but I must have done it incorrectly. I will
> fix it immediatly.

Please also leave a note there saying the datasheet is wrong.

Thanks
ChenYu

>
> olliver
>
>
>
>>
>> [1]
>>
>> http://linux-sunxi.org/AXP209#REG_25H:_DC-DC2.2FLDO3_dynamic_voltage_scaling_parameter_settings
>> [2] http://dl.linux-sunxi.org/AXP/AXP209_Datasheet_v1.0en.pdf
>>
>> Cheers,
>>
>>   Marcus
diff mbox

Patch

diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index f2c5629be2..3f10f84a89 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -188,6 +188,39 @@  config AXP_ALDO3_VOLT
 	On A83T / H8 boards aldo3 is AVCC, VCC-PL, and VCC-LED, and should be
 	3.0V.
 
+choice
+	prompt "axp pmic (a)ldo3 voltage rate control"
+	depends on AXP209_POWER && (AXP_ALDO3_VOLT != 0)
+	default AXP_ALDO3_VOLT_SLOPE_NONE
+	---help---
+	The AXP can slowly ramp up voltage to reduce the inrush current when
+	changing voltages.
+	Note, this does not apply when enabeling/disableing LDO3. See
+	"axp pmic (a)ldo3 inrush quirk" below to enable a slew rate to limit
+	inrush current on broken board designs.
+
+config AXP_ALDO3_VOLT_SLOPE_NONE
+	bool "No voltage slope"
+	---help---
+	Tries to reach the next voltage setting near instantaneous. Measurements
+	indicate that this is about 0.0167 V/uS.
+
+config AXP_ALDO3_VOLT_SLOPE_16
+	bool "1.6 mV per uS"
+	---help---
+	Increases the voltage by 1.6 mV per uS until the final voltage has
+	been reached. Note that the scaling is in 25 mV steps however and thus
+	the slew rate is 25 mV/31.250 uS in reality.
+
+config AXP_ALDO3_VOLT_SLOPE_08
+	bool "0.8 mV per uS"
+	---help---
+	Increases the voltage by 0.8 mV per uS until the final voltage has
+	been reached. Note that the scaling is in 25 mV steps however and thus
+	the slew rate is 25 mV/15.625 uS in reality. This is the slowest rate.
+
+endchoice
+
 config AXP_ALDO4_VOLT
 	int "axp pmic (a)ldo4 voltage"
 	depends on AXP209_POWER
diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c
index a5d38cdf76..8f9269cb40 100644
--- a/drivers/power/axp209.c
+++ b/drivers/power/axp209.c
@@ -10,6 +10,16 @@ 
 #include <asm/arch/pmic_bus.h>
 #include <axp_pmic.h>
 
+#ifdef CONFIG_AXP_ALDO3_VOLT_SLOPE_08
+#  define AXP209_VRC_SLOPE AXP209_VRC_LDO3_800uV_uS
+#endif
+#ifdef CONFIG_AXP_ALDO3_VOLT_SLOPE_16
+#  define AXP209_VRC_SLOPE AXP209_VRC_LDO3_1600uV_uS
+#endif
+#if defined CONFIG_AXP_ALDO3_VOLT_SLOPE_NONE || !defined AXP209_VRC_SLOPE
+#  define AXP209_VRC_SLOPE 0x00
+#endif
+
 static u8 axp209_mvolt_to_cfg(int mvolt, int min, int max, int div)
 {
 	if (mvolt < min)
@@ -99,6 +109,20 @@  int axp_set_aldo3(unsigned int mvolt)
 		return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
 					AXP209_OUTPUT_CTRL_LDO3);
 
+	/*
+	 * Some boards have trouble reaching the target voltage without causing
+	 * great inrush currents. To prevent this, boards can enable a certain
+	 * slope to ramp up voltage. Note, this only works when changing an
+	 * already active power rail. When toggling power on, the AXP ramps up
+	 * steeply at 0.0167 V/uS.
+	 */
+	rc = pmic_bus_read(AXP209_VRC_DCDC2_LDO3, &cfg);
+	cfg = AXP209_VRC_LDO3_SLOPE_SET(cfg, AXP209_VRC_SLOPE);
+	rc |= pmic_bus_write(AXP209_VRC_DCDC2_LDO3, cfg);
+
+	if (rc)
+		return rc;
+
 	if (mvolt == -1)
 		cfg = AXP209_LDO3_VOLTAGE_FROM_LDO3IN;
 	else
diff --git a/include/axp209.h b/include/axp209.h
index e4210eca00..62be93b806 100644
--- a/include/axp209.h
+++ b/include/axp209.h
@@ -11,6 +11,7 @@  enum axp209_reg {
 	AXP209_CHIP_VERSION = 0x03,
 	AXP209_OUTPUT_CTRL = 0x12,
 	AXP209_DCDC2_VOLTAGE = 0x23,
+	AXP209_VRC_DCDC2_LDO3 = 0x25,
 	AXP209_DCDC3_VOLTAGE = 0x27,
 	AXP209_LDO24_VOLTAGE = 0x28,
 	AXP209_LDO3_VOLTAGE = 0x29,
@@ -35,6 +36,21 @@  enum axp209_reg {
 #define AXP209_OUTPUT_CTRL_DCDC2	BIT(4)
 #define AXP209_OUTPUT_CTRL_LDO3		BIT(6)
 
+#define AXP209_VRC_LDO3_EN		BIT(3)
+#define AXP209_VRC_DCDC2_EN		BIT(2)
+#define AXP209_VRC_LDO3_800uV_uS	(BIT(1) | AXP209_VRC_LDO3_EN)
+#define AXP209_VRC_LDO3_1600uV_uS	AXP209_VRC_LDO3_EN
+#define AXP209_VRC_DCDC2_800uV_uS	(BIT(0) | AXP209_VRC_DCDC2_EN)
+#define AXP209_VRC_DCDC2_1600uV_uS	AXP209_VRC_DCDC2_EN
+#define AXP209_VRC_LDO3_MASK		0xa
+#define AXP209_VRC_DCDC2_MASK		0x5
+#define AXP209_VRC_DCDC2_SLOPE_SET(reg, cfg) \
+	(((reg) & ~AXP209_VRC_DCDC2_MASK) | \
+	((cfg) & AXP209_VRC_DCDC2_MASK))
+#define AXP209_VRC_LDO3_SLOPE_SET(reg, cfg) \
+	(((reg) & ~AXP209_VRC_LDO3_MASK) | \
+	((cfg) & AXP209_VRC_LDO3_MASK))
+
 #define AXP209_LDO24_LDO2_MASK		0xf0
 #define AXP209_LDO24_LDO4_MASK		0x0f
 #define AXP209_LDO24_LDO2_SET(reg, cfg)	\