From e7cd1d1eb16fcdf53001b926187a82f1f3e1a7e6 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 20 May 2014 11:17:54 -0700 Subject: mfd: twl4030-power: Add generic reset configuration The twl4030 PMIC needs to be configured properly for things like warm reset and deeper idle states so the PMIC manages the regulators properly based on the hardware triggers from the SoC. Earlier we have configured twl4030 using platform data, but we want to do it for device tree based booting also. In some cases configuring twl4030 is needed for things to work. For example, when rebooting an OMAP3530 at 125 MHz, it hangs. With this patch, TWL4030 will be reset when a warm reset occures, and OMAP3530 does not hang on reboot. Let's add device tree support and configure things for warm reset as the default when compatible = "ti,twl4030-power". More complicated configurations can be added to the driver based on other compatible flags. Note we now also make the pdata const like it should be. This allows use it for match->data with the device tree related functions. Based on earlier patch by Matthias Brugger and Lesly A M . Signed-off-by: Tony Lindgren Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/twl4030-power.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mfd/twl4030-power.txt b/Documentation/devicetree/bindings/mfd/twl4030-power.txt index 8e15ec35ac99..b90611650cd9 100644 --- a/Documentation/devicetree/bindings/mfd/twl4030-power.txt +++ b/Documentation/devicetree/bindings/mfd/twl4030-power.txt @@ -5,7 +5,12 @@ to control the power resources, including power scripts. For now, the binding only supports the complete shutdown of the system after poweroff. Required properties: -- compatible : must be "ti,twl4030-power" +- compatible : must be one of the following + "ti,twl4030-power" + "ti,twl4030-power-reset" + +The use of ti,twl4030-power-reset is recommended at least on +3530 that needs a special configuration for warm reset to work. Optional properties: - ti,use_poweroff: With this flag, the chip will initiates an ACTIVE-to-OFF or -- cgit v1.2.3 From 76714d2c090f836fe005008116075a7b5bfde852 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 20 May 2014 11:17:54 -0700 Subject: mfd: twl4030-power: Add recommended idle configuration These settings are based on the "Recommended Sleep Sequences for the Zoom Platform". The settings assume most of the regulators are under control of Linux, and twl4030 only cuts off VDD1 and VDD2 during off-idle as Linux cannot do it. For any board specific changes to these, let's patch them in as changes to the generic data in the follow-up patches. This keeps the board specific changes small. Note that this does not consider the twl5030 errata 27 and 28. That can be added later on after it has been tested. For more information about errata 27 and 28. Signed-off-by: Tony Lindgren Signed-off-by: Lee Jones --- .../devicetree/bindings/mfd/twl4030-power.txt | 4 + drivers/mfd/twl4030-power.c | 106 +++++++++++++++++++++ 2 files changed, 110 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mfd/twl4030-power.txt b/Documentation/devicetree/bindings/mfd/twl4030-power.txt index b90611650cd9..bbd66039202a 100644 --- a/Documentation/devicetree/bindings/mfd/twl4030-power.txt +++ b/Documentation/devicetree/bindings/mfd/twl4030-power.txt @@ -8,10 +8,14 @@ Required properties: - compatible : must be one of the following "ti,twl4030-power" "ti,twl4030-power-reset" + "ti,twl4030-power-idle" The use of ti,twl4030-power-reset is recommended at least on 3530 that needs a special configuration for warm reset to work. +When using ti,twl4030-power-idle, the TI recommended configuration +for idle modes is loaded to the tlw4030 PMIC. + Optional properties: - ti,use_poweroff: With this flag, the chip will initiates an ACTIVE-to-OFF or SLEEP-to-OFF transition when the system poweroffs. diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c index cb5b0cb8f933..2bfbb40ca9d2 100644 --- a/drivers/mfd/twl4030-power.c +++ b/drivers/mfd/twl4030-power.c @@ -145,6 +145,7 @@ enum { * omap3 has been made DT only. */ #define TWL_DFLT_DELAY 2 /* typically 2 32 KiHz cycles */ +#define TWL_DEV_GRP_P123 (DEV_GRP_P1 | DEV_GRP_P2 | DEV_GRP_P3) #define TWL_RESOURCE_SET(res, state) \ { MSG_SINGULAR(DEV_GRP_NULL, (res), (state)), TWL_DFLT_DELAY } #define TWL_RESOURCE_ON(res) TWL_RESOURCE_SET(res, RES_STATE_ACTIVE) @@ -154,14 +155,26 @@ enum { * It seems that type1 and type2 is just the resource init order * number for the type1 and type2 group. */ +#define TWL_RESOURCE_SET_ACTIVE(res, state) \ + { MSG_SINGULAR(DEV_GRP_NULL, (res), RES_STATE_ACTIVE), (state) } #define TWL_RESOURCE_GROUP_RESET(group, type1, type2) \ { MSG_BROADCAST(DEV_GRP_NULL, (group), (type1), (type2), \ RES_STATE_WRST), TWL_DFLT_DELAY } +#define TWL_RESOURCE_GROUP_SLEEP(group, type, type2) \ + { MSG_BROADCAST(DEV_GRP_NULL, (group), (type), (type2), \ + RES_STATE_SLEEP), TWL_DFLT_DELAY } +#define TWL_RESOURCE_GROUP_ACTIVE(group, type, type2) \ + { MSG_BROADCAST(DEV_GRP_NULL, (group), (type), (type2), \ + RES_STATE_ACTIVE), TWL_DFLT_DELAY } #define TWL_REMAP_SLEEP(res, devgrp, typ, typ2) \ { .resource = (res), .devgroup = (devgrp), \ .type = (typ), .type2 = (typ2), \ .remap_off = TWL_REMAP_OFF, \ .remap_sleep = TWL_REMAP_SLEEP, } +#define TWL_REMAP_OFF(res, devgrp, typ, typ2) \ + { .resource = (res), .devgroup = (devgrp), \ + .type = (typ), .type2 = (typ2), \ + .remap_off = TWL_REMAP_OFF, .remap_sleep = TWL_REMAP_OFF, } static int twl4030_write_script_byte(u8 address, u8 byte) { @@ -638,11 +651,104 @@ static struct twl4030_power_data omap3_reset = { .resource_config = omap3_rconfig, }; +/* Recommended generic default idle configuration for off-idle */ + +/* Broadcast message to put res to sleep */ +static struct twl4030_ins omap3_idle_sleep_on_seq[] = { + TWL_RESOURCE_GROUP_SLEEP(RES_GRP_ALL, RES_TYPE_ALL, 0), +}; + +static struct twl4030_script omap3_idle_sleep_on_script = { + .script = omap3_idle_sleep_on_seq, + .size = ARRAY_SIZE(omap3_idle_sleep_on_seq), + .flags = TWL4030_SLEEP_SCRIPT, +}; + +/* Broadcast message to put res to active */ +static struct twl4030_ins omap3_idle_wakeup_p12_seq[] = { + TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0), +}; + +static struct twl4030_script omap3_idle_wakeup_p12_script = { + .script = omap3_idle_wakeup_p12_seq, + .size = ARRAY_SIZE(omap3_idle_wakeup_p12_seq), + .flags = TWL4030_WAKEUP12_SCRIPT, +}; + +/* Broadcast message to put res to active */ +static struct twl4030_ins omap3_idle_wakeup_p3_seq[] = { + TWL_RESOURCE_SET_ACTIVE(RES_CLKEN, 0x37), + TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0), +}; + +static struct twl4030_script omap3_idle_wakeup_p3_script = { + .script = omap3_idle_wakeup_p3_seq, + .size = ARRAY_SIZE(omap3_idle_wakeup_p3_seq), + .flags = TWL4030_WAKEUP3_SCRIPT, +}; + +static struct twl4030_script *omap3_idle_scripts[] = { + &omap3_idle_wakeup_p12_script, + &omap3_idle_wakeup_p3_script, + &omap3_wrst_script, + &omap3_idle_sleep_on_script, +}; + +/* + * Recommended configuration based on "Recommended Sleep + * Sequences for the Zoom Platform": + * http://omappedia.com/wiki/File:Recommended_Sleep_Sequences_Zoom.pdf + * Note that the type1 and type2 seem to be just the init order number + * for type1 and type2 groups as specified in the document mentioned + * above. + */ +static struct twl4030_resconfig omap3_idle_rconfig[] = { + TWL_REMAP_SLEEP(RES_VAUX1, DEV_GRP_NULL, 0, 0), + TWL_REMAP_SLEEP(RES_VAUX2, DEV_GRP_NULL, 0, 0), + TWL_REMAP_SLEEP(RES_VAUX3, DEV_GRP_NULL, 0, 0), + TWL_REMAP_SLEEP(RES_VAUX4, DEV_GRP_NULL, 0, 0), + TWL_REMAP_SLEEP(RES_VMMC1, DEV_GRP_NULL, 0, 0), + TWL_REMAP_SLEEP(RES_VMMC2, DEV_GRP_NULL, 0, 0), + TWL_REMAP_OFF(RES_VPLL1, DEV_GRP_P1, 3, 1), + TWL_REMAP_SLEEP(RES_VPLL2, DEV_GRP_P1, 0, 0), + TWL_REMAP_SLEEP(RES_VSIM, DEV_GRP_NULL, 0, 0), + TWL_REMAP_SLEEP(RES_VDAC, DEV_GRP_NULL, 0, 0), + TWL_REMAP_SLEEP(RES_VINTANA1, TWL_DEV_GRP_P123, 1, 2), + TWL_REMAP_SLEEP(RES_VINTANA2, TWL_DEV_GRP_P123, 0, 2), + TWL_REMAP_SLEEP(RES_VINTDIG, TWL_DEV_GRP_P123, 1, 2), + TWL_REMAP_SLEEP(RES_VIO, TWL_DEV_GRP_P123, 2, 2), + TWL_REMAP_OFF(RES_VDD1, DEV_GRP_P1, 4, 1), + TWL_REMAP_OFF(RES_VDD2, DEV_GRP_P1, 3, 1), + TWL_REMAP_SLEEP(RES_VUSB_1V5, DEV_GRP_NULL, 0, 0), + TWL_REMAP_SLEEP(RES_VUSB_1V8, DEV_GRP_NULL, 0, 0), + TWL_REMAP_SLEEP(RES_VUSB_3V1, TWL_DEV_GRP_P123, 0, 0), + /* Resource #20 USB charge pump skipped */ + TWL_REMAP_SLEEP(RES_REGEN, TWL_DEV_GRP_P123, 2, 1), + TWL_REMAP_SLEEP(RES_NRES_PWRON, TWL_DEV_GRP_P123, 0, 1), + TWL_REMAP_SLEEP(RES_CLKEN, TWL_DEV_GRP_P123, 3, 2), + TWL_REMAP_SLEEP(RES_SYSEN, TWL_DEV_GRP_P123, 6, 1), + TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, 0, 2), + TWL_REMAP_SLEEP(RES_32KCLKOUT, TWL_DEV_GRP_P123, 0, 0), + TWL_REMAP_SLEEP(RES_RESET, TWL_DEV_GRP_P123, 6, 0), + TWL_REMAP_SLEEP(RES_MAIN_REF, TWL_DEV_GRP_P123, 0, 0), + { /* Terminator */ }, +}; + +static struct twl4030_power_data omap3_idle = { + .scripts = omap3_idle_scripts, + .num = ARRAY_SIZE(omap3_idle_scripts), + .resource_config = omap3_idle_rconfig, +}; + static struct of_device_id twl4030_power_of_match[] = { { .compatible = "ti,twl4030-power-reset", .data = &omap3_reset, }, + { + .compatible = "ti,twl4030-power-idle", + .data = &omap3_idle, + }, { }, }; MODULE_DEVICE_TABLE(of, twl4030_power_of_match); -- cgit v1.2.3 From 43fef47f94a1ae46fb2720dada32fa3b5547bee2 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 13 May 2014 18:34:09 -0700 Subject: mfd: twl4030-power: Add a configuration to turn off oscillator during off-idle Some oscillators can be turned off during off-idle saving few a little bit power at the cost of the oscillator start up latency. If you board can do this, you can now enable it by using the ti,twl4030-power-idle-osc-off compatible flag. Signed-off-by: Tony Lindgren Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/twl4030-power.txt | 6 ++++++ drivers/mfd/twl4030-power.c | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mfd/twl4030-power.txt b/Documentation/devicetree/bindings/mfd/twl4030-power.txt index bbd66039202a..b9ee7b98d3e2 100644 --- a/Documentation/devicetree/bindings/mfd/twl4030-power.txt +++ b/Documentation/devicetree/bindings/mfd/twl4030-power.txt @@ -9,6 +9,7 @@ Required properties: "ti,twl4030-power" "ti,twl4030-power-reset" "ti,twl4030-power-idle" + "ti,twl4030-power-idle-osc-off" The use of ti,twl4030-power-reset is recommended at least on 3530 that needs a special configuration for warm reset to work. @@ -16,6 +17,11 @@ The use of ti,twl4030-power-reset is recommended at least on When using ti,twl4030-power-idle, the TI recommended configuration for idle modes is loaded to the tlw4030 PMIC. +When using ti,twl4030-power-idle-osc-off, the TI recommended +configuration is used with the external oscillator being shut +down during off-idle. Note that this does not work on all boards +depending on how the external oscillator is wired. + Optional properties: - ti,use_poweroff: With this flag, the chip will initiates an ACTIVE-to-OFF or SLEEP-to-OFF transition when the system poweroffs. diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c index 4846c7b48ebb..3bc969a5916b 100644 --- a/drivers/mfd/twl4030-power.c +++ b/drivers/mfd/twl4030-power.c @@ -761,6 +761,19 @@ static struct twl4030_power_data omap3_idle = { .resource_config = omap3_idle_rconfig, }; +/* Disable 32 KiHz oscillator during idle */ +static struct twl4030_resconfig osc_off_rconfig[] = { + TWL_REMAP_OFF(RES_CLKEN, DEV_GRP_P1 | DEV_GRP_P3, 3, 2), + { /* Terminator */ }, +}; + +static struct twl4030_power_data osc_off_idle = { + .scripts = omap3_idle_scripts, + .num = ARRAY_SIZE(omap3_idle_scripts), + .resource_config = omap3_idle_rconfig, + .board_config = osc_off_rconfig, +}; + static struct of_device_id twl4030_power_of_match[] = { { .compatible = "ti,twl4030-power-reset", @@ -770,6 +783,10 @@ static struct of_device_id twl4030_power_of_match[] = { .compatible = "ti,twl4030-power-idle", .data = &omap3_idle, }, + { + .compatible = "ti,twl4030-power-idle-osc-off", + .data = &osc_off_idle, + }, { }, }; MODULE_DEVICE_TABLE(of, twl4030_power_of_match); -- cgit v1.2.3