Skip to content

Commit f814345

Browse files
power-xsfrkhuangtao
authored andcommitted
pmic: rk808: rk816: fix up the RK816 setting voltage drop make the system crash
Before adjusting voltage, increase clk_cpu div and reduce CPU frequency Only support for RK312x chips. Change-Id: Id327da9590f7d9d383450e79acd1b309e05cd024 Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com> Signed-off-by: shengfei Xu <xsf@rock-chips.com>
1 parent 6c7c137 commit f814345

2 files changed

Lines changed: 62 additions & 1 deletion

File tree

drivers/clk/rockchip/clk-rk3128.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/clk-provider.h>
1717
#include <linux/of.h>
1818
#include <linux/of_address.h>
19+
#include <linux/rockchip/cpu.h>
1920
#include <linux/syscore_ops.h>
2021
#include <dt-bindings/clock/rk3128-cru.h>
2122
#include "clk.h"
@@ -581,6 +582,15 @@ static const char *const rk3128_critical_clocks[] __initconst = {
581582
"hclk_vio_niu",
582583
};
583584

585+
static void __iomem *rk312x_reg_base;
586+
587+
void rkclk_cpuclk_div_setting(int div)
588+
{
589+
if (cpu_is_rk312x())
590+
writel_relaxed((0x001f0000 | (div - 1)),
591+
rk312x_reg_base + RK2928_CLKSEL_CON(0));
592+
}
593+
584594
static struct rockchip_clk_provider *__init rk3128_common_clk_init(struct device_node *np)
585595
{
586596
struct rockchip_clk_provider *ctx;
@@ -592,6 +602,7 @@ static struct rockchip_clk_provider *__init rk3128_common_clk_init(struct device
592602
return ERR_PTR(-ENOMEM);
593603
}
594604

605+
rk312x_reg_base = reg_base;
595606
ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
596607
if (IS_ERR(ctx)) {
597608
pr_err("%s: rockchip clk init failed\n", __func__);

drivers/regulator/rk808-regulator.c

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,38 @@ static int rk808_buck1_2_i2c_set_voltage_sel(struct regulator_dev *rdev,
228228
return ret;
229229
}
230230

231+
extern void rkclk_cpuclk_div_setting(int div);
232+
233+
static int rk816_regulator_set_voltage_sel_regmap(struct regulator_dev *rdev,
234+
unsigned int sel)
235+
{
236+
int ret, real_sel, delay = 100;
237+
238+
sel <<= ffs(rdev->desc->vsel_mask) - 1;
239+
240+
if (sel > 23)
241+
rkclk_cpuclk_div_setting(4);
242+
else
243+
rkclk_cpuclk_div_setting(2);
244+
245+
do {
246+
ret = regmap_update_bits(rdev->regmap,
247+
rdev->desc->vsel_reg,
248+
rdev->desc->vsel_mask, sel);
249+
if (ret)
250+
return ret;
251+
252+
regmap_read(rdev->regmap,
253+
rdev->desc->vsel_reg, &real_sel);
254+
real_sel &= rdev->desc->vsel_mask;
255+
delay--;
256+
} while ((sel != real_sel) && (delay > 0));
257+
258+
rkclk_cpuclk_div_setting(1);
259+
260+
return ret;
261+
}
262+
231263
static int rk808_buck1_2_set_voltage_sel(struct regulator_dev *rdev,
232264
unsigned sel)
233265
{
@@ -553,6 +585,24 @@ static struct regulator_ops rk808_switch_ops = {
553585
.set_suspend_mode = rk8xx_set_suspend_mode,
554586
};
555587

588+
static struct regulator_ops rk816_buck_ops_range = {
589+
.list_voltage = regulator_list_voltage_linear_range,
590+
.map_voltage = regulator_map_voltage_linear_range,
591+
.get_voltage_sel = regulator_get_voltage_sel_regmap,
592+
.set_voltage_sel = rk816_regulator_set_voltage_sel_regmap,
593+
.set_voltage_time_sel = regulator_set_voltage_time_sel,
594+
.enable = regulator_enable_regmap,
595+
.disable = regulator_disable_regmap,
596+
.is_enabled = regulator_is_enabled_regmap,
597+
.set_mode = rk8xx_set_mode,
598+
.get_mode = rk8xx_get_mode,
599+
.set_suspend_mode = rk8xx_set_suspend_mode,
600+
.set_ramp_delay = rk808_set_ramp_delay,
601+
.set_suspend_voltage = rk808_set_suspend_voltage_range,
602+
.set_suspend_enable = rk808_set_suspend_enable,
603+
.set_suspend_disable = rk808_set_suspend_disable,
604+
};
605+
556606
static const struct regulator_desc rk808_reg[] = {
557607
{
558608
.name = "DCDC_REG1",
@@ -654,7 +704,7 @@ static const struct regulator_desc rk816_reg[] = {
654704
.of_match = of_match_ptr("DCDC_REG1"),
655705
.regulators_node = of_match_ptr("regulators"),
656706
.id = RK816_ID_DCDC1,
657-
.ops = &rk8xx_buck_ops_range,
707+
.ops = &rk816_buck_ops_range,
658708
.type = REGULATOR_VOLTAGE,
659709
.n_voltages = 64,
660710
.linear_ranges = rk816_buck_voltage_ranges,

0 commit comments

Comments
 (0)