* [PATCH v1 1/3] ARM: riotboard: provide standby on power off option @ 2017-07-06 14:00 Oleksij Rempel 2017-07-06 14:00 ` [PATCH v1 2/3] ARM: i.MX: provide handler for power off over standby Oleksij Rempel 2017-07-06 14:00 ` [PATCH v1 3/3] regulator: pfuze: provide power over standby handler Oleksij Rempel 0 siblings, 2 replies; 5+ messages in thread From: Oleksij Rempel @ 2017-07-06 14:00 UTC (permalink / raw) To: barebox, l.stach; +Cc: Oleksij Rempel This board, as well as some other boards with i.MX6 and a PMIC, uses a "PMIC_STBY_REQ" line to notify the PMIC about a state change. The PMIC is programmed for a specific state change before triggering the line. In this case, PMIC_STBY_REQ can be used for stand by, sleep and power off modes. Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> --- arch/arm/dts/imx6s-riotboard.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/dts/imx6s-riotboard.dts b/arch/arm/dts/imx6s-riotboard.dts index 575887267e..ddd0d5ba2d 100644 --- a/arch/arm/dts/imx6s-riotboard.dts +++ b/arch/arm/dts/imx6s-riotboard.dts @@ -42,3 +42,10 @@ barebox,provide-mac-address = <&fec 0x620>; }; +&clks { + fsl,pmic-stby-poweroff; +}; + +&pmic { + fsl,pmic-stby-poweroff; +}; -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v1 2/3] ARM: i.MX: provide handler for power off over standby 2017-07-06 14:00 [PATCH v1 1/3] ARM: riotboard: provide standby on power off option Oleksij Rempel @ 2017-07-06 14:00 ` Oleksij Rempel 2017-07-06 14:00 ` [PATCH v1 3/3] regulator: pfuze: provide power over standby handler Oleksij Rempel 1 sibling, 0 replies; 5+ messages in thread From: Oleksij Rempel @ 2017-07-06 14:00 UTC (permalink / raw) To: barebox, l.stach; +Cc: Oleksij Rempel One of the Freescale recommended sequences for power off with external PMIC is the following: ... 3. SoC is programming PMIC for power off when standby is asserted. 4. In CCM STOP mode, Standby is asserted, PMIC gates SoC supplies. See: http://www.nxp.com/assets/documents/data/en/reference-manuals/IMX6DQRM.pdf page 5083 This patch implements step 4. of this sequence. Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> --- arch/arm/mach-imx/imx6.c | 49 +++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/include/mach/imx6.h | 1 + 2 files changed, 50 insertions(+) diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c index 5afbf6b30f..96c1f64093 100644 --- a/arch/arm/mach-imx/imx6.c +++ b/arch/arm/mach-imx/imx6.c @@ -25,6 +25,19 @@ #include <asm/mmu.h> #include <asm/cache-l2x0.h> +#include <poweroff.h> +#include <mach/imx6-regs.h> +#include <io.h> + +#define CLPCR 0x54 +#define BP_CLPCR_LPM(mode) ((mode) & 0x3) +#define BM_CLPCR_LPM (0x3 << 0) +#define BM_CLPCR_SBYOS (0x1 << 6) +#define BM_CLPCR_VSTBY (0x1 << 8) +#define BP_CLPCR_STBY_COUNT 9 +#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11) +#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21) + void imx6_init_lowlevel(void) { void __iomem *aips1 = (void *)MX6_AIPS1_ON_BASE_ADDR; @@ -296,3 +309,39 @@ static int imx6_fixup_cpus_register(void) return of_register_fixup(imx6_fixup_cpus, NULL); } device_initcall(imx6_fixup_cpus_register); + +void __noreturn imx6_pm_stby_poweroff(void) +{ + void *ccm_base = IOMEM(MX6_CCM_BASE_ADDR); + void *gpc_base = IOMEM(MX6_GPC_BASE_ADDR); + u32 val; + + /* + * All this is done to get the PMIC_STBY_REQ line high which will + * cause the PMIC to turn off the i.MX6. + */ + + /* + * First mask all interrupts in the GPC. This is necessary for + * unknown reasons + */ + writel(0xffffffff, gpc_base + 0x8); + writel(0xffffffff, gpc_base + 0xc); + writel(0xffffffff, gpc_base + 0x10); + writel(0xffffffff, gpc_base + 0x14); + + val = readl(ccm_base + CLPCR); + + val &= ~BM_CLPCR_LPM; + val |= BP_CLPCR_LPM(2); + val |= 0x3 << BP_CLPCR_STBY_COUNT; + val |= BM_CLPCR_VSTBY; + val |= BM_CLPCR_SBYOS; + val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; + + writel(val, ccm_base + CLPCR); + + asm("wfi"); + + while(1); +} diff --git a/arch/arm/mach-imx/include/mach/imx6.h b/arch/arm/mach-imx/include/mach/imx6.h index 6ad53433cb..e4633ed5f2 100644 --- a/arch/arm/mach-imx/include/mach/imx6.h +++ b/arch/arm/mach-imx/include/mach/imx6.h @@ -7,6 +7,7 @@ #include <mach/revision.h> void imx6_init_lowlevel(void); +void __noreturn imx6_pm_stby_poweroff(void); #define IMX6_ANATOP_SI_REV 0x260 #define IMX6SL_ANATOP_SI_REV 0x280 -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v1 3/3] regulator: pfuze: provide power over standby handler 2017-07-06 14:00 [PATCH v1 1/3] ARM: riotboard: provide standby on power off option Oleksij Rempel 2017-07-06 14:00 ` [PATCH v1 2/3] ARM: i.MX: provide handler for power off over standby Oleksij Rempel @ 2017-07-06 14:00 ` Oleksij Rempel 2017-07-06 14:12 ` Lucas Stach 1 sibling, 1 reply; 5+ messages in thread From: Oleksij Rempel @ 2017-07-06 14:00 UTC (permalink / raw) To: barebox, l.stach; +Cc: Oleksij Rempel This patch is providing an optional power off handler which will configure standby state of the PMIC to disable all power lines. In my power consumption test on RIoTBoard, I got the following results: power off without this patch: 320 mA power off with this patch: 2 mA suspend to ram: 40 mA Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> --- drivers/regulator/pfuze.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/drivers/regulator/pfuze.c b/drivers/regulator/pfuze.c index 2a5fb715ce..94fa03ff15 100644 --- a/drivers/regulator/pfuze.c +++ b/drivers/regulator/pfuze.c @@ -26,10 +26,53 @@ #include <i2c/i2c.h> +#include <poweroff.h> +#include <mach/imx6.h> + #define DRIVERNAME "pfuze" #define MC13XXX_NUMREGS 0x3f +#define PFUZE_NUMREGS 128 +#define PFUZE100_VOL_OFFSET 0 +#define PFUZE100_STANDBY_OFFSET 1 +#define PFUZE100_MODE_OFFSET 3 +#define PFUZE100_CONF_OFFSET 4 + +#define PFUZE100_DEVICEID 0x0 +#define PFUZE100_REVID 0x3 +#define PFUZE100_FABID 0x4 + +#define PFUZE100_COINVOL 0x1a +#define PFUZE100_SW1ABVOL 0x20 +#define PFUZE100_SW1ABMODE 0x23 +#define PFUZE100_SW1CVOL 0x2e +#define PFUZE100_SW1CMODE 0x31 +#define PFUZE100_SW2VOL 0x35 +#define PFUZE100_SW2MODE 0x38 +#define PFUZE100_SW3AVOL 0x3c +#define PFUZE100_SW3AMODE 0x3f +#define PFUZE100_SW3BVOL 0x43 +#define PFUZE100_SW3BMODE 0x46 +#define PFUZE100_SW4VOL 0x4a +#define PFUZE100_SW4MODE 0x4d +#define PFUZE100_SWBSTCON1 0x66 +#define PFUZE100_VREFDDRCON 0x6a +#define PFUZE100_VSNVSVOL 0x6b +#define PFUZE100_VGEN1VOL 0x6c +#define PFUZE100_VGEN2VOL 0x6d +#define PFUZE100_VGEN3VOL 0x6e +#define PFUZE100_VGEN4VOL 0x6f +#define PFUZE100_VGEN5VOL 0x70 +#define PFUZE100_VGEN6VOL 0x71 + +#define PFUZE100_SWxMODE_MASK 0xf +#define PFUZE100_SWxMODE_APS_APS 0x8 +#define PFUZE100_SWxMODE_APS_OFF 0x4 + +#define PFUZE100_VGENxLPWR BIT(6) +#define PFUZE100_VGENxSTBY BIT(5) + struct pfuze { struct device_d *dev; struct regmap *map; @@ -85,6 +128,46 @@ static int pfuze_i2c_reg_write(void *ctx, unsigned int reg, unsigned int val) return ret == 1 ? 0 : ret; } +static void pfuze_power_off_prepare(struct poweroff_handler *handler) +{ + dev_info(pfuze_dev->dev, "Configure standy mode for power off"); + + /* Switch from default mode: APS/APS to APS/Off */ + regmap_write_bits(pfuze_dev->map, PFUZE100_SW1ABMODE, + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); + regmap_write_bits(pfuze_dev->map, PFUZE100_SW1CMODE, + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); + regmap_write_bits(pfuze_dev->map, PFUZE100_SW2MODE, + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); + regmap_write_bits(pfuze_dev->map, PFUZE100_SW3AMODE, + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); + regmap_write_bits(pfuze_dev->map, PFUZE100_SW3BMODE, + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); + regmap_write_bits(pfuze_dev->map, PFUZE100_SW4MODE, + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); + + regmap_write_bits(pfuze_dev->map, PFUZE100_VGEN1VOL, + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, + PFUZE100_VGENxSTBY); + regmap_write_bits(pfuze_dev->map, PFUZE100_VGEN2VOL, + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, + PFUZE100_VGENxSTBY); + regmap_write_bits(pfuze_dev->map, PFUZE100_VGEN3VOL, + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, + PFUZE100_VGENxSTBY); + regmap_write_bits(pfuze_dev->map, PFUZE100_VGEN4VOL, + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, + PFUZE100_VGENxSTBY); + regmap_write_bits(pfuze_dev->map, PFUZE100_VGEN5VOL, + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, + PFUZE100_VGENxSTBY); + regmap_write_bits(pfuze_dev->map, PFUZE100_VGEN6VOL, + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, + PFUZE100_VGENxSTBY); + + imx6_pm_stby_poweroff(); +} + static struct regmap_bus regmap_pfuze_i2c_bus = { .reg_write = pfuze_i2c_reg_write, .reg_read = pfuze_i2c_reg_read, @@ -122,6 +205,10 @@ static int __init pfuze_probe(struct device_d *dev) if (pfuze_init_callback) pfuze_init_callback(pfuze_dev->map); + if (of_property_read_bool(dev->device_node, + "fsl,pmic-stby-poweroff")) + return poweroff_handler_register_fn(pfuze_power_off_prepare); + return 0; } -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1 3/3] regulator: pfuze: provide power over standby handler 2017-07-06 14:00 ` [PATCH v1 3/3] regulator: pfuze: provide power over standby handler Oleksij Rempel @ 2017-07-06 14:12 ` Lucas Stach 2017-07-06 16:34 ` Oleksij Rempel 0 siblings, 1 reply; 5+ messages in thread From: Lucas Stach @ 2017-07-06 14:12 UTC (permalink / raw) To: Oleksij Rempel; +Cc: barebox Am Donnerstag, den 06.07.2017, 16:00 +0200 schrieb Oleksij Rempel: > This patch is providing an optional power off handler > which will configure standby state of the PMIC to disable all power lines. > > In my power consumption test on RIoTBoard, I got the following results: > power off without this patch: 320 mA > power off with this patch: 2 mA > suspend to ram: 40 mA You probably haven't measured suspend to ram with barebox, right? ;) > > Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> > --- > drivers/regulator/pfuze.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 87 insertions(+) > > diff --git a/drivers/regulator/pfuze.c b/drivers/regulator/pfuze.c > index 2a5fb715ce..94fa03ff15 100644 > --- a/drivers/regulator/pfuze.c > +++ b/drivers/regulator/pfuze.c > @@ -26,10 +26,53 @@ > > #include <i2c/i2c.h> > > +#include <poweroff.h> > +#include <mach/imx6.h> > + This introduces a build dependency of the PFUZE driver to the i.MX6 architecture. While I think this is fine, as it keeps things straight-forward and the PFUZE is unlikely to be used on other SoCs, this needs at least a "depends on ARCH_IMX6" in the Kconfig entry. Regards, Lucas > #define DRIVERNAME "pfuze" > > #define MC13XXX_NUMREGS 0x3f > > +#define PFUZE_NUMREGS 128 > +#define PFUZE100_VOL_OFFSET 0 > +#define PFUZE100_STANDBY_OFFSET 1 > +#define PFUZE100_MODE_OFFSET 3 > +#define PFUZE100_CONF_OFFSET 4 > + > +#define PFUZE100_DEVICEID 0x0 > +#define PFUZE100_REVID 0x3 > +#define PFUZE100_FABID 0x4 > + > +#define PFUZE100_COINVOL 0x1a > +#define PFUZE100_SW1ABVOL 0x20 > +#define PFUZE100_SW1ABMODE 0x23 > +#define PFUZE100_SW1CVOL 0x2e > +#define PFUZE100_SW1CMODE 0x31 > +#define PFUZE100_SW2VOL 0x35 > +#define PFUZE100_SW2MODE 0x38 > +#define PFUZE100_SW3AVOL 0x3c > +#define PFUZE100_SW3AMODE 0x3f > +#define PFUZE100_SW3BVOL 0x43 > +#define PFUZE100_SW3BMODE 0x46 > +#define PFUZE100_SW4VOL 0x4a > +#define PFUZE100_SW4MODE 0x4d > +#define PFUZE100_SWBSTCON1 0x66 > +#define PFUZE100_VREFDDRCON 0x6a > +#define PFUZE100_VSNVSVOL 0x6b > +#define PFUZE100_VGEN1VOL 0x6c > +#define PFUZE100_VGEN2VOL 0x6d > +#define PFUZE100_VGEN3VOL 0x6e > +#define PFUZE100_VGEN4VOL 0x6f > +#define PFUZE100_VGEN5VOL 0x70 > +#define PFUZE100_VGEN6VOL 0x71 > + > +#define PFUZE100_SWxMODE_MASK 0xf > +#define PFUZE100_SWxMODE_APS_APS 0x8 > +#define PFUZE100_SWxMODE_APS_OFF 0x4 > + > +#define PFUZE100_VGENxLPWR BIT(6) > +#define PFUZE100_VGENxSTBY BIT(5) > + > struct pfuze { > struct device_d *dev; > struct regmap *map; > @@ -85,6 +128,46 @@ static int pfuze_i2c_reg_write(void *ctx, unsigned int reg, unsigned int val) > return ret == 1 ? 0 : ret; > } > > +static void pfuze_power_off_prepare(struct poweroff_handler *handler) > +{ > + dev_info(pfuze_dev->dev, "Configure standy mode for power off"); > + > + /* Switch from default mode: APS/APS to APS/Off */ > + regmap_write_bits(pfuze_dev->map, PFUZE100_SW1ABMODE, > + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); > + regmap_write_bits(pfuze_dev->map, PFUZE100_SW1CMODE, > + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); > + regmap_write_bits(pfuze_dev->map, PFUZE100_SW2MODE, > + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); > + regmap_write_bits(pfuze_dev->map, PFUZE100_SW3AMODE, > + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); > + regmap_write_bits(pfuze_dev->map, PFUZE100_SW3BMODE, > + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); > + regmap_write_bits(pfuze_dev->map, PFUZE100_SW4MODE, > + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); > + > + regmap_write_bits(pfuze_dev->map, PFUZE100_VGEN1VOL, > + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, > + PFUZE100_VGENxSTBY); > + regmap_write_bits(pfuze_dev->map, PFUZE100_VGEN2VOL, > + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, > + PFUZE100_VGENxSTBY); > + regmap_write_bits(pfuze_dev->map, PFUZE100_VGEN3VOL, > + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, > + PFUZE100_VGENxSTBY); > + regmap_write_bits(pfuze_dev->map, PFUZE100_VGEN4VOL, > + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, > + PFUZE100_VGENxSTBY); > + regmap_write_bits(pfuze_dev->map, PFUZE100_VGEN5VOL, > + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, > + PFUZE100_VGENxSTBY); > + regmap_write_bits(pfuze_dev->map, PFUZE100_VGEN6VOL, > + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, > + PFUZE100_VGENxSTBY); > + > + imx6_pm_stby_poweroff(); > +} > + > static struct regmap_bus regmap_pfuze_i2c_bus = { > .reg_write = pfuze_i2c_reg_write, > .reg_read = pfuze_i2c_reg_read, > @@ -122,6 +205,10 @@ static int __init pfuze_probe(struct device_d *dev) > if (pfuze_init_callback) > pfuze_init_callback(pfuze_dev->map); > > + if (of_property_read_bool(dev->device_node, > + "fsl,pmic-stby-poweroff")) > + return poweroff_handler_register_fn(pfuze_power_off_prepare); > + > return 0; > } > _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1 3/3] regulator: pfuze: provide power over standby handler 2017-07-06 14:12 ` Lucas Stach @ 2017-07-06 16:34 ` Oleksij Rempel 0 siblings, 0 replies; 5+ messages in thread From: Oleksij Rempel @ 2017-07-06 16:34 UTC (permalink / raw) To: barebox [-- Attachment #1.1.1: Type: text/plain, Size: 1372 bytes --] Am 06.07.2017 um 16:12 schrieb Lucas Stach: > Am Donnerstag, den 06.07.2017, 16:00 +0200 schrieb Oleksij Rempel: >> This patch is providing an optional power off handler >> which will configure standby state of the PMIC to disable all power lines. >> >> In my power consumption test on RIoTBoard, I got the following results: >> power off without this patch: 320 mA >> power off with this patch: 2 mA >> suspend to ram: 40 mA > > You probably haven't measured suspend to ram with barebox, right? ;) Oops... yeas :) >> >> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> >> --- >> drivers/regulator/pfuze.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 87 insertions(+) >> >> diff --git a/drivers/regulator/pfuze.c b/drivers/regulator/pfuze.c >> index 2a5fb715ce..94fa03ff15 100644 >> --- a/drivers/regulator/pfuze.c >> +++ b/drivers/regulator/pfuze.c >> @@ -26,10 +26,53 @@ >> >> #include <i2c/i2c.h> >> >> +#include <poweroff.h> >> +#include <mach/imx6.h> >> + > This introduces a build dependency of the PFUZE driver to the i.MX6 > architecture. While I think this is fine, as it keeps things > straight-forward and the PFUZE is unlikely to be used on other SoCs, > this needs at least a "depends on ARCH_IMX6" in the Kconfig entry. Ok. -- Regards, Oleksij [-- Attachment #1.2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 213 bytes --] [-- Attachment #2: Type: text/plain, Size: 149 bytes --] _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-07-06 16:35 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-07-06 14:00 [PATCH v1 1/3] ARM: riotboard: provide standby on power off option Oleksij Rempel 2017-07-06 14:00 ` [PATCH v1 2/3] ARM: i.MX: provide handler for power off over standby Oleksij Rempel 2017-07-06 14:00 ` [PATCH v1 3/3] regulator: pfuze: provide power over standby handler Oleksij Rempel 2017-07-06 14:12 ` Lucas Stach 2017-07-06 16:34 ` Oleksij Rempel
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox