diff options
| -rw-r--r-- | Documentation/devicetree/bindings/power/omap-prm-voltsetup.txt | 6 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 4 | ||||
| -rw-r--r-- | drivers/power/avs/omap3_prm_voltsetup.c | 310 | ||||
| -rw-r--r-- | drivers/power/avs/omap_prm_voltsetup.h | 8 | ||||
| -rw-r--r-- | drivers/power/avs/omap_vc.c | 15 | ||||
| -rw-r--r-- | drivers/power/avs/omap_vc.h | 1 | ||||
| -rw-r--r-- | include/linux/power/omap_prm.h | 16 |
7 files changed, 161 insertions, 199 deletions
diff --git a/Documentation/devicetree/bindings/power/omap-prm-voltsetup.txt b/Documentation/devicetree/bindings/power/omap-prm-voltsetup.txt index 67c5024b86e..b80602e223a 100644 --- a/Documentation/devicetree/bindings/power/omap-prm-voltsetup.txt +++ b/Documentation/devicetree/bindings/power/omap-prm-voltsetup.txt @@ -27,12 +27,6 @@ Optional Properties: defined, then time is calculated based on PMIC slew rate and voltage level will be used. Claculated time is used also if value in device tree less then calculated. -- setup_time1: VDD1 voltage setup time in micro seconds when the device exits - the off mode. It used only if sys_off_mode is false. If this value is not - defined, then time is calculated based on PMIC slew rate and voltage level - will be used. Claculated time is used also if value in device tree less then - calculated. -- setup_time2: same as above only for VDD2. Example: glbl_prm: glbl_prm@48307250 { diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 939e92c11db..65f4a7f8185 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -315,7 +315,9 @@ void omap_sram_idle(bool in_suspend) omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, PM_WKEN); - } + omap_prm_configure(true); + } else + omap_prm_configure(false); } omap3_intc_prepare_idle(); diff --git a/drivers/power/avs/omap3_prm_voltsetup.c b/drivers/power/avs/omap3_prm_voltsetup.c index 97951060df5..40113655aa0 100644 --- a/drivers/power/avs/omap3_prm_voltsetup.c +++ b/drivers/power/avs/omap3_prm_voltsetup.c @@ -28,6 +28,7 @@ #include <linux/err.h> #include <linux/power/omap_prm.h> #include <linux/regulator/omap-pmic-regulator.h> +#include "omap_vc.h" #include "omap_prm_voltsetup.h" #define DRIVER_NAME "omap3-glbl-prm" @@ -56,16 +57,20 @@ #define VOLTOFFSET_MASK 0xffff #define VOLTSETUP1_TIME1_MASK 0x0000ffff #define VOLTSETUP1_TIME2_MASK 0xffff0000 +#define VOLTSETUP1_TIME1_2_MASK 0xffffffff struct omap_prm_voltsetup_data { struct device *dev; - struct regmap *regmap; + struct regmap *rmap; const struct omap_vc_common_reg *regs; bool sys_off_mode; bool auto_retention; bool auto_off; - u32 clksetup_time; /* uSec */ + u32 retsetup1_2; /* sys_clk ticks for time1 and time2*/ + u32 offsetup1_2; /* sys_clk ticks for time1 and time2*/ + u32 offmodesetup_cnt; /* 32K ticks */ + u32 offoffset_cnt; /* 32K ticks */ u32 sys_clk_rate; /* Hz */ }; @@ -83,102 +88,95 @@ static const struct of_device_id omap3_prm_voltsetup_match_tbl[] __initdata = { }; MODULE_DEVICE_TABLE(of, omap3_prm_voltsetup_match_tbl); -int omap_prm_voltsetup(struct device *dev, struct omap_pmic *pmic, u32 uv) +int omap_prm_configure(bool off) { - struct regmap *regmap; - const char *str; - int ret = 0, val; - u32 v1, v2, v2_old, msk; - struct device *prm_dev = prm_voltsetup_data->dev; + u32 val, msk; + int ret = 0; + struct omap_prm_voltsetup_data *pd = prm_voltsetup_data; - if (!dev || !dev->of_node || !pmic || uv == 0) { - dev_err(prm_dev, "Invalid parameters\n"); - return -EINVAL; - } - if (IS_ERR_OR_NULL(prm_voltsetup_data)) { - dev_err(prm_dev, "Device is not initialized\n"); + if (!pd || !pd->dev) { + pr_err("PRM voltsetup device is not initialized\n"); return -ENODEV; } - regmap = prm_voltsetup_data->regmap; - if (prm_voltsetup_data->sys_off_mode) { - ret = regmap_read(regmap, PRM_VOLTSETUP2_OFFS, &v2_old); - if (ret) - goto fail_reg; - v2_old &= OFFMODESETUPTIME_MASK; - v2_old >>= __ffs(OFFMODESETUPTIME_MASK); + /* set auto bit exclusive */ + regmap_update_bits(pd->rmap, PRM_VOLTCTRL_OFFS, VOLTCTRL_AUTO_MASK, 0); + msk = off ? VOLTCTRL_AUTO_OFF_MASK : VOLTCTRL_AUTO_RET_MASK; + val = off ? (pd->auto_off ? 1 : 0) : (pd->auto_retention ? 1 : 0); + regmap_update_bits(pd->rmap, PRM_VOLTCTRL_OFFS, msk, val << __ffs(msk)); - v2_old = DIV_ROUND_CLOSEST(v2_old * 1000000, 32768); - - /* voltage / slew_rate, 2uS added as buffer */ - val = DIV_ROUND_UP(uv, pmic->info->slew_rate_uV) + 2; - - /* - * Update v2 if higher than current value (needed because - * we have multiple channels with different ramp times), also - * update voltoffset always to value recommended by TRM - */ - if (val > v2_old) { - dev_dbg(prm_dev, "voltsetup2 is set to %d uS\n", val); - v2 = DIV_ROUND_UP(val * 32768, 1000000); - ret = regmap_update_bits(regmap, PRM_VOLTSETUP2_OFFS, + if (off && pd->auto_off) { + if (pd->sys_off_mode) { + val = pd->offmodesetup_cnt; + ret = regmap_update_bits(pd->rmap, PRM_VOLTSETUP2_OFFS, OFFMODESETUPTIME_MASK, - v2 << __ffs(OFFMODESETUPTIME_MASK)); + val << __ffs(OFFMODESETUPTIME_MASK)); if (ret) goto fail_reg; - } else - val = v2_old; - - if (prm_voltsetup_data->clksetup_time > val) - val = prm_voltsetup_data->clksetup_time - val; - else - val = 30; - - dev_dbg(prm_dev, "voltoffset is set to %d uS\n", val); - val = DIV_ROUND_UP(val * 32768, 1000000); - ret = regmap_update_bits(regmap, PRM_VOLTOFFSET_OFFS, + val = pd->offoffset_cnt; + ret = regmap_update_bits(pd->rmap, PRM_VOLTOFFSET_OFFS, VOLTOFFSET_MASK, val << __ffs(VOLTOFFSET_MASK)); + } else + ret = regmap_update_bits(pd->rmap, PRM_VOLTSETUP1_OFFS, + VOLTSETUP1_TIME1_2_MASK, pd->offsetup1_2); if (ret) goto fail_reg; - } else { - ret = of_property_read_string(dev->of_node, "compatible", &str); - if (ret) { - dev_err(prm_dev, - "No compatible property in channel (%d)\n", ret); - return ret; - } - val = strlen(str); - if (str[val - 1] == '0') - msk = VOLTSETUP1_TIME1_MASK; - else if (str[val - 1] == '1') - msk = VOLTSETUP1_TIME2_MASK; - else { - pr_err("Unable to identify vc channel\n"); - return -EINVAL; - } - ret = regmap_read(regmap, PRM_VOLTSETUP1_OFFS, &val); + } else if (!off && pd->auto_retention) { + ret = regmap_update_bits(pd->rmap, PRM_VOLTSETUP1_OFFS, + VOLTSETUP1_TIME1_2_MASK, pd->retsetup1_2); if (ret) goto fail_reg; - val &= msk; - val >>= __ffs(msk); - - /* voltage / slew_rate */ - v1 = DIV_ROUND_UP(uv, pmic->info->slew_rate_uV); - v1 = DIV_ROUND_UP_ULL( - (u64)v1 * prm_voltsetup_data->sys_clk_rate, 8000000); - if (val > v1) - v1 = val; - v1 <<= __ffs(msk); - ret = regmap_update_bits(regmap, PRM_VOLTSETUP1_OFFS, msk, v1); + ret = regmap_update_bits(pd->rmap, PRM_VOLTSETUP2_OFFS, + OFFMODESETUPTIME_MASK, + 0 << __ffs(OFFMODESETUPTIME_MASK)); + if (ret) + goto fail_reg; + ret = regmap_update_bits(pd->rmap, PRM_VOLTOFFSET_OFFS, + VOLTOFFSET_MASK, 0 << __ffs(VOLTOFFSET_MASK)); if (ret) goto fail_reg; } - return ret; - + return 0; fail_reg: - dev_err(dev, "%s: Register operation failed with %d\n", __func__, ret); + dev_err(pd->dev, "%s: Register operation failed (%d)\n", __func__, ret); return ret; } +EXPORT_SYMBOL_GPL(omap_prm_configure); + +int omap_prm_voltsetup(struct omap_vc_channel_info *inf, struct omap_pmic *pmic, + u32 uv) +{ + u32 uv_diff, val, msk; + struct omap_prm_voltsetup_data *pd = prm_voltsetup_data; + + if (!pd || !pd->dev) { + pr_err("PRM voltsetup device is not initialized\n"); + return -ENODEV; + } + if (!inf || !pmic || uv == 0 || pmic->info->slew_rate_uV == 0 || + inf->retention_uV > uv) { + dev_err(pd->dev, "Invalid parameters\n"); + return -EINVAL; + } + if (inf->ch_num != 0 && inf->ch_num != 1) { + dev_err(pd->dev, "Unable to identify vc channel\n"); + return -EINVAL; + } + msk = inf->ch_num == 0 ? VOLTSETUP1_TIME1_MASK : VOLTSETUP1_TIME2_MASK; + uv_diff = uv - inf->retention_uV; + val = DIV_ROUND_UP(uv_diff, pmic->info->slew_rate_uV); + val = DIV_ROUND_UP_ULL((u64)val * pd->sys_clk_rate, 8000000); + pd->retsetup1_2 &= ~msk; + pd->retsetup1_2 |= val << __ffs(msk); + if (!pd->sys_off_mode) { + uv_diff = uv - inf->off_uV; + val = DIV_ROUND_UP(uv_diff, pmic->info->slew_rate_uV); + val = DIV_ROUND_UP_ULL((u64)val * pd->sys_clk_rate, 8000000); + pd->offsetup1_2 &= ~msk; + pd->retsetup1_2 |= val << __ffs(msk); + } + return 0; +} EXPORT_SYMBOL_GPL(omap_prm_voltsetup); /** * omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled @@ -215,44 +213,6 @@ bool omap_pm_get_off_mode(void) } EXPORT_SYMBOL_GPL(omap_pm_get_off_mode); -static int omap3_prm_suspend_noirq(struct device *dev) -{ - u32 msk = VOLTCTRL_AUTO_MASK, val = 0; - struct platform_device *pdev = to_platform_device(dev); - struct omap_prm_voltsetup_data *data = platform_get_drvdata(pdev); - - /* clean all auto bits */ - regmap_update_bits(data->regmap, PRM_VOLTCTRL_OFFS, msk, val); - /* set auto mode exclusively wiht "off" as priority*/ - if (data->auto_off) { - msk = VOLTCTRL_AUTO_OFF_MASK; - val = 1; - } else if (data->auto_retention) { - msk = VOLTCTRL_AUTO_RET_MASK; - val = 1; - } - return regmap_update_bits(data->regmap, PRM_VOLTCTRL_OFFS, msk, - val << __ffs(msk)); -} - -static int omap3_prm_resume_noirq(struct device *dev) -{ - u32 msk = VOLTCTRL_AUTO_MASK, val = 0; - struct platform_device *pdev = to_platform_device(dev); - struct omap_prm_voltsetup_data *data = platform_get_drvdata(pdev); - - /* clean all auto bits */ - regmap_update_bits(data->regmap, PRM_VOLTCTRL_OFFS, msk, val); - /* restore mode to retention by default if defined */ - if (data->auto_retention) { - msk = VOLTCTRL_AUTO_RET_MASK; - val = 1; - } - return regmap_update_bits(data->regmap, PRM_VOLTCTRL_OFFS, msk, - val << __ffs(msk)); -} - - static int omap3_prm_voltsetup_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -262,9 +222,10 @@ static int omap3_prm_voltsetup_probe(struct platform_device *pdev) char *pname; const char *clk_name = NULL; void __iomem *base; - struct regmap *regmap; + struct regmap *rmap; struct omap_prm_voltsetup_data *data; - u32 clkmode, val = 0; + u32 clksetup_time; /* uSec */ + u32 val = 0; struct clk *sys_clk; if (!nd) { @@ -283,9 +244,9 @@ static int omap3_prm_voltsetup_probe(struct platform_device *pdev) dev_err(dev, "Unable to map registers\n"); return -EADDRNOTAVAIL; } - regmap = devm_regmap_init_mmio(dev, base, ®map_cfg); - if (IS_ERR(regmap)) { - ret = PTR_ERR(regmap); + rmap = devm_regmap_init_mmio(dev, base, ®map_cfg); + if (IS_ERR(rmap)) { + ret = PTR_ERR(rmap); dev_err(dev, "regmap init failed(%d)\n", ret); return ret; } @@ -294,7 +255,23 @@ static int omap3_prm_voltsetup_probe(struct platform_device *pdev) dev_err(dev, "%s: Unable to allocate data\n", __func__); return -ENOMEM; } - data->regmap = regmap; + data->rmap = rmap; + + pname = "auto_off"; + data->auto_off = of_property_read_bool(nd, pname); + pname = "auto_retention"; + data->auto_retention = of_property_read_bool(nd, pname); + + if (!data->auto_off && !data->auto_retention) { + dev_warn(dev, "WARNING: No auto_retention nor auto_off\n"); + return -EINVAL; + } + /* clean all auto bits */ + regmap_update_bits(rmap, PRM_VOLTCTRL_OFFS, VOLTCTRL_AUTO_MASK, 0); + /* set to retention if enabled by default, off mode is set on demand */ + val = data->auto_retention ? 1 : 0; + regmap_update_bits(rmap, PRM_VOLTCTRL_OFFS, VOLTCTRL_AUTO_RET_MASK, + val << __ffs(VOLTCTRL_AUTO_RET_MASK)); pname = "sys_clk"; ret = of_property_read_string(nd, pname, &clk_name); @@ -309,75 +286,38 @@ static int omap3_prm_voltsetup_probe(struct platform_device *pdev) data->sys_clk_rate = clk_get_rate(sys_clk); clk_put(sys_clk); - pname = "autoextclkmode"; - of_property_read_u32(nd, pname, &clkmode); - pname = "clksetup_time"; - ret = of_property_read_u32(nd, pname, &data->clksetup_time); - if (ret || !data->clksetup_time) + ret = of_property_read_u32(nd, pname, &clksetup_time); + if (ret || !clksetup_time) goto property_err; - - pname = "auto_off"; - data->auto_off = of_property_read_bool(nd, pname); - pname = "auto_retention"; - data->auto_retention = of_property_read_bool(nd, pname); - - /* clean all auto bits */ - regmap_update_bits(regmap, PRM_VOLTCTRL_OFFS, VOLTCTRL_AUTO_MASK, 0); - /* set to retention if enabled by default */ - val = data->auto_retention ? 1 : 0; - regmap_update_bits(regmap, PRM_VOLTCTRL_OFFS, - VOLTCTRL_AUTO_RET_MASK, - val << __ffs(VOLTCTRL_AUTO_RET_MASK)); + val = DIV_ROUND_UP(clksetup_time * 32768, 1000000); + ret = regmap_update_bits(rmap, PRM_CLKSETUP_OFFS, CLKSETUP_MASK, + val << __ffs(CLKSETUP_MASK)); + if (ret) + goto fail_reg; pname = "sys_off_mode"; - if (of_property_read_bool(nd, pname)) { - data->sys_off_mode = true; - regmap_update_bits(regmap, PRM_VOLTCTRL_OFFS, - VOLTCTRL_SEL_OFF_MASK, - 1 << __ffs(VOLTCTRL_SEL_OFF_MASK)); + data->sys_off_mode = of_property_read_bool(nd, pname); + val = data->sys_off_mode ? 1 : 0; + regmap_update_bits(rmap, PRM_VOLTCTRL_OFFS, VOLTCTRL_SEL_OFF_MASK, + val << __ffs(VOLTCTRL_SEL_OFF_MASK)); + if (data->sys_off_mode) { pname = "offmodesetup_time"; - val = 0; - of_property_read_u32(nd, pname, &val); - /* set value in register even if it is 0 */ - val = DIV_ROUND_UP(val * 32768, 1000000); - ret = regmap_update_bits(regmap, PRM_VOLTSETUP2_OFFS, - OFFMODESETUPTIME_MASK, - val << __ffs(OFFMODESETUPTIME_MASK)); - if (ret) - goto fail_reg; - } else { - data->sys_off_mode = false; - /* set value in register even if it is 0 */ - pname = "setup_time1"; - val = 0; - of_property_read_u32(nd, pname, &val); - val = DIV_ROUND_UP_ULL((u64)val * data->sys_clk_rate, 8000000); - ret = regmap_update_bits(regmap, PRM_VOLTSETUP1_OFFS, - VOLTSETUP1_TIME1_MASK, - val << __ffs(VOLTSETUP1_TIME1_MASK)); - pname = "setup_time2"; - val = 0; - of_property_read_u32(nd, pname, &val); - val = DIV_ROUND_UP_ULL((u64)val * data->sys_clk_rate, 8000000); - ret = regmap_update_bits(regmap, PRM_VOLTSETUP1_OFFS, - VOLTSETUP1_TIME2_MASK, - val << __ffs(VOLTSETUP1_TIME2_MASK)); + ret = of_property_read_u32(nd, pname, &val); + if (ret || !val) + goto property_err; + data->offmodesetup_cnt = DIV_ROUND_UP(val * 32768, 1000000); + /* ~1 32K tick by default */ + val = clksetup_time > val ? clksetup_time - val : 30; + data->offoffset_cnt = DIV_ROUND_UP(val * 32768, 1000000); } - if (ret) - goto fail_reg; - - ret = regmap_update_bits(regmap, PRM_CLKSRC_CTRL_OFFS, + pname = "autoextclkmode"; + of_property_read_u32(nd, pname, &val); + ret = regmap_update_bits(rmap, PRM_CLKSRC_CTRL_OFFS, CLKSRC_CTRL_AUTOEXTCLKMODE_MASK, - clkmode << __ffs(CLKSRC_CTRL_AUTOEXTCLKMODE_MASK)); - if (ret) - goto fail_reg; - - val = DIV_ROUND_UP(data->clksetup_time * 32768, 1000000); - ret = regmap_update_bits(regmap, PRM_CLKSETUP_OFFS, CLKSETUP_MASK, - val << __ffs(CLKSETUP_MASK)); + val << __ffs(CLKSRC_CTRL_AUTOEXTCLKMODE_MASK)); if (ret) goto fail_reg; @@ -400,17 +340,11 @@ fail_reg: return ret; } -static const struct dev_pm_ops omap3_prm_dev_pm_ops = { - .suspend_noirq = omap3_prm_suspend_noirq, - .resume_noirq = omap3_prm_resume_noirq, -}; - static struct platform_driver omap3_prm_voltsetup_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, .of_match_table = of_match_ptr(omap3_prm_voltsetup_match_tbl), - .pm = &omap3_prm_dev_pm_ops, }, .probe = omap3_prm_voltsetup_probe, }; diff --git a/drivers/power/avs/omap_prm_voltsetup.h b/drivers/power/avs/omap_prm_voltsetup.h index 75d709623cf..0a3acca6d05 100644 --- a/drivers/power/avs/omap_prm_voltsetup.h +++ b/drivers/power/avs/omap_prm_voltsetup.h @@ -20,12 +20,14 @@ #define _POWER_OMAP_PRM_VOLTSETUP_H struct omap_pmic; +struct omap_vc_channel_info; #if IS_ENABLED(CONFIG_POWER_TI_HARDWARE_VOLTAGE_CONTROL) -int omap_prm_voltsetup(struct device *dev, struct omap_pmic *pmic, u32 uv); +int omap_prm_voltsetup(struct omap_vc_channel_info *inf, struct omap_pmic *pmic, + u32 uv); #else -static inline int omap_prm_voltsetup(struct device *dev, struct omap_pmic *pmic, - u32 uv) +static inline int omap_prm_voltsetup(struct omap_vc_channel_info *inf, + struct omap_pmic *pmic, u32 uv) { return -ENODEV; } diff --git a/drivers/power/avs/omap_vc.c b/drivers/power/avs/omap_vc.c index d5a4bdbfe9c..98b01e65ef7 100644 --- a/drivers/power/avs/omap_vc.c +++ b/drivers/power/avs/omap_vc.c @@ -75,6 +75,8 @@ struct vc_channel_regs { u32 command_val_onlp_mask; u32 command_val_ret_mask; u32 command_val_off_mask; + /* channel number */ + u32 ch_num; }; /** @@ -182,6 +184,8 @@ static const struct vc_channel_regs omap3_ch_1_regs = { .command_val_onlp_mask = 0xFF0000, .command_val_ret_mask = 0xFF00, .command_val_off_mask = 0xFF, + + .ch_num = 1, }; static const struct vc_channel_regs omap3_ch_0_regs = { @@ -206,6 +210,8 @@ static const struct vc_channel_regs omap3_ch_0_regs = { .command_val_onlp_mask = 0xFF0000, .command_val_ret_mask = 0xFF00, .command_val_off_mask = 0xFF, + + .ch_num = 0, }; static const struct vc_channel_regs omap4_ch_mpu_regs = { @@ -230,6 +236,7 @@ static const struct vc_channel_regs omap4_ch_mpu_regs = { .command_val_onlp_mask = 0xFF0000, .command_val_ret_mask = 0xFF00, .command_val_off_mask = 0xFF, + .ch_num = 2, }; static const struct vc_channel_regs omap4_ch_iva_regs = { @@ -254,6 +261,7 @@ static const struct vc_channel_regs omap4_ch_iva_regs = { .command_val_onlp_mask = 0xFF0000, .command_val_ret_mask = 0xFF00, .command_val_off_mask = 0xFF, + .ch_num = 1, }; static const struct vc_channel_regs omap4_ch_core_regs = { @@ -278,6 +286,7 @@ static const struct vc_channel_regs omap4_ch_core_regs = { .command_val_onlp_mask = 0xFF0000, .command_val_ret_mask = 0xFF00, .command_val_off_mask = 0xFF, + .ch_num = 0, }; static const struct vc_channel_regs omap5_ch_core_regs = { @@ -302,6 +311,7 @@ static const struct vc_channel_regs omap5_ch_core_regs = { .command_val_onlp_mask = 0xFF0000, .command_val_ret_mask = 0xFF00, .command_val_off_mask = 0x00, /* Reserved */ + .ch_num = 0, }; static const struct vc_channel_regs omap5_ch_mm_regs = { @@ -326,6 +336,7 @@ static const struct vc_channel_regs omap5_ch_mm_regs = { .command_val_onlp_mask = 0xFF0000, .command_val_ret_mask = 0xFF00, .command_val_off_mask = 0x00, /* Reserved */ + .ch_num = 1, }; static const struct vc_channel_regs omap5_ch_mpu_regs = { @@ -350,6 +361,7 @@ static const struct vc_channel_regs omap5_ch_mpu_regs = { .command_val_onlp_mask = 0xFF0000, .command_val_ret_mask = 0xFF00, .command_val_off_mask = 0x00, /* Reserved */ + .ch_num = 2, }; /* VC Generic register configurations */ @@ -471,7 +483,7 @@ int omap_vc_channel_set_on_voltage(struct omap_vc_channel_info *info, u32 uv) if (ret) goto fail_reg; - ret = omap_prm_voltsetup(dev, pmic, uv); + ret = omap_prm_voltsetup(info, pmic, uv); if (ret) { dev_err(dev, "Unable to set voltsetup parameters %d\n", ret); goto out; @@ -1083,6 +1095,7 @@ static int omap_vc_channel_probe(struct platform_device *pdev) vc_channel->ch_regs = match->data; info = &vc_channel->info; info->ch = vc_channel; + info->ch_num = vc_channel->ch_regs->ch_num; /* Pick up optional parameters */ of_property_read_u32(node, "ti,retention-micro-volts", diff --git a/drivers/power/avs/omap_vc.h b/drivers/power/avs/omap_vc.h index 11503b0ad3f..ae300f3fb97 100644 --- a/drivers/power/avs/omap_vc.h +++ b/drivers/power/avs/omap_vc.h @@ -38,6 +38,7 @@ struct omap_vc_channel; * @off_uV: OFF voltage in micro volts */ struct omap_vc_channel_info { + u32 ch_num; struct omap_pmic *pmic; u32 retention_uV; u32 off_uV; diff --git a/include/linux/power/omap_prm.h b/include/linux/power/omap_prm.h index 7ce0dbabe3a..b5dde83da27 100644 --- a/include/linux/power/omap_prm.h +++ b/include/linux/power/omap_prm.h @@ -20,10 +20,26 @@ #define _POWER_OMAP_PRM_H #if IS_ENABLED(CONFIG_POWER_TI_HARDWARE_VOLTAGE_CONTROL) +/* + * omap_prm_configure - Will configure global PRM register to low power values + * for voltage setup timings and state according device + * device tree properties. + * bool off: If true then OFF state will be configured, otherwise + * retention state. At least one of these state has to be + * enabled in device tree with auto_off or auto_retention + * flags&pointer + * Returns 0 if success, otherwise error code. + */ +int omap_prm_configure(bool off); + void omap_pm_enable_off_mode(void); void omap_pm_disable_off_mode(void); bool omap_pm_get_off_mode(void); #else +static inline int omap_prm_configure(bool off) +{ + return -ENODEV; +} static inline void omap_pm_enable_off_mode(void) { } |