aboutsummaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorTom Rini2017-05-10 17:40:11 -0400
committerTom Rini2017-05-10 17:40:11 -0400
commit1f5541c8818d3ecd243f9bbf58db9ea5f55a3195 (patch)
tree83053c0f224f8fe641550492e95818033e5af7e2 /drivers/power
parent102d86552abc82818c22b39fdef4b3a280a60643 (diff)
parent2085de57f3928d72b27338f68d4250d1fb302d04 (diff)
Merge git://git.denx.de/u-boot-rockchip
This adds a new firefly-rk3399 board, MIPI support for rk3399 and rk3288, rk818 pmic support, mkimage improvements for rockchip and a few other things.
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/pmic/Kconfig6
-rw-r--r--drivers/power/pmic/Makefile2
-rw-r--r--drivers/power/pmic/rk8xx.c (renamed from drivers/power/pmic/rk808.c)52
-rw-r--r--drivers/power/regulator/Kconfig8
-rw-r--r--drivers/power/regulator/Makefile2
-rw-r--r--drivers/power/regulator/pwm_regulator.c16
-rw-r--r--drivers/power/regulator/rk8xx.c (renamed from drivers/power/regulator/rk808.c)142
7 files changed, 154 insertions, 74 deletions
diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
index 4891b1704e8..3f50c121571 100644
--- a/drivers/power/pmic/Kconfig
+++ b/drivers/power/pmic/Kconfig
@@ -28,7 +28,7 @@ config SPL_PMIC_CHILDREN
This allows PMICs to support child devices (such as regulators) in
SPL. This adds quite a bit of code so if you are not using this
feature you can turn it off. In this case you may need a 'back door'
- to call your regulator code (e.g. see rk808.c for direct functions
+ to call your regulator code (e.g. see rk8xx.c for direct functions
for use in SPL).
config PMIC_ACT8846
@@ -100,8 +100,8 @@ config PMIC_PM8916
Driver binding info: doc/device-tree-bindings/pmic/pm8916.txt
-config PMIC_RK808
- bool "Enable support for Rockchip PMIC RK808"
+config PMIC_RK8XX
+ bool "Enable support for Rockchip PMIC RK8XX"
depends on DM_PMIC
---help---
The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs,
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
index 5f1bef33cdd..f409e3a0b36 100644
--- a/drivers/power/pmic/Makefile
+++ b/drivers/power/pmic/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_PMIC_ACT8846) += act8846.o
obj-$(CONFIG_PMIC_AS3722) += as3722.o
obj-$(CONFIG_PMIC_MAX8997) += max8997.o
obj-$(CONFIG_PMIC_PM8916) += pm8916.o
-obj-$(CONFIG_PMIC_RK808) += rk808.o
+obj-$(CONFIG_PMIC_RK8XX) += rk8xx.o
obj-$(CONFIG_PMIC_RN5T567) += rn5t567.o
obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o
diff --git a/drivers/power/pmic/rk808.c b/drivers/power/pmic/rk8xx.c
index 3f5f316b56f..394e2ff9db3 100644
--- a/drivers/power/pmic/rk808.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -10,24 +10,24 @@
#include <errno.h>
#include <fdtdec.h>
#include <libfdt.h>
-#include <power/rk808_pmic.h>
+#include <power/rk8xx_pmic.h>
#include <power/pmic.h>
DECLARE_GLOBAL_DATA_PTR;
static const struct pmic_child_info pmic_children_info[] = {
- { .prefix = "DCDC_REG", .driver = "rk808_buck"},
- { .prefix = "LDO_REG", .driver = "rk808_ldo"},
- { .prefix = "SWITCH_REG", .driver = "rk808_switch"},
+ { .prefix = "DCDC_REG", .driver = "rk8xx_buck"},
+ { .prefix = "LDO_REG", .driver = "rk8xx_ldo"},
+ { .prefix = "SWITCH_REG", .driver = "rk8xx_switch"},
{ },
};
-static int rk808_reg_count(struct udevice *dev)
+static int rk8xx_reg_count(struct udevice *dev)
{
return RK808_NUM_OF_REGS;
}
-static int rk808_write(struct udevice *dev, uint reg, const uint8_t *buff,
+static int rk8xx_write(struct udevice *dev, uint reg, const uint8_t *buff,
int len)
{
int ret;
@@ -41,7 +41,7 @@ static int rk808_write(struct udevice *dev, uint reg, const uint8_t *buff,
return 0;
}
-static int rk808_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
{
int ret;
@@ -55,7 +55,7 @@ static int rk808_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
}
#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
-static int rk808_bind(struct udevice *dev)
+static int rk8xx_bind(struct udevice *dev)
{
const void *blob = gd->fdt_blob;
int regulators_node;
@@ -80,23 +80,39 @@ static int rk808_bind(struct udevice *dev)
}
#endif
-static struct dm_pmic_ops rk808_ops = {
- .reg_count = rk808_reg_count,
- .read = rk808_read,
- .write = rk808_write,
+static int rk8xx_probe(struct udevice *dev)
+{
+ struct rk8xx_priv *priv = dev_get_priv(dev);
+ uint8_t msb, lsb;
+
+ /* read Chip variant */
+ rk8xx_read(dev, ID_MSB, &msb, 1);
+ rk8xx_read(dev, ID_LSB, &lsb, 1);
+
+ priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
+
+ return 0;
+}
+
+static struct dm_pmic_ops rk8xx_ops = {
+ .reg_count = rk8xx_reg_count,
+ .read = rk8xx_read,
+ .write = rk8xx_write,
};
-static const struct udevice_id rk808_ids[] = {
+static const struct udevice_id rk8xx_ids[] = {
{ .compatible = "rockchip,rk808" },
+ { .compatible = "rockchip,rk818" },
{ }
};
-U_BOOT_DRIVER(pmic_rk808) = {
- .name = "rk808 pmic",
+U_BOOT_DRIVER(pmic_rk8xx) = {
+ .name = "rk8xx pmic",
.id = UCLASS_PMIC,
- .of_match = rk808_ids,
+ .of_match = rk8xx_ids,
#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
- .bind = rk808_bind,
+ .bind = rk8xx_bind,
#endif
- .ops = &rk808_ops,
+ .probe = rk8xx_probe,
+ .ops = &rk8xx_ops,
};
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index f870e8bcc9f..ef057e0e2fb 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -76,11 +76,11 @@ config DM_REGULATOR_GPIO
features for gpio regulators. The driver implements get/set for
voltage value.
-config REGULATOR_RK808
- bool "Enable driver for RK808 regulators"
- depends on DM_REGULATOR && PMIC_RK808
+config REGULATOR_RK8XX
+ bool "Enable driver for RK8XX regulators"
+ depends on DM_REGULATOR && PMIC_RK8XX
---help---
- Enable support for the regulator functions of the RK808 PMIC. The
+ Enable support for the regulator functions of the RK8XX PMIC. The
driver implements get/set api for the various BUCKS and LDOs supported
by the PMIC device. This driver is controlled by a device tree node
which includes voltage limits.
diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile
index 6002c88a6c1..3e01021b76a 100644
--- a/drivers/power/regulator/Makefile
+++ b/drivers/power/regulator/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_DM_REGULATOR_PFUZE100) += pfuze100.o
obj-$(CONFIG_REGULATOR_PWM) += pwm_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_FIXED) += fixed.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_GPIO) += gpio-regulator.o
-obj-$(CONFIG_REGULATOR_RK808) += rk808.o
+obj-$(CONFIG_REGULATOR_RK8XX) += rk8xx.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o
obj-$(CONFIG_REGULATOR_TPS65090) += tps65090_regulator.o
diff --git a/drivers/power/regulator/pwm_regulator.c b/drivers/power/regulator/pwm_regulator.c
index 4875238e43d..a6c9fccd68e 100644
--- a/drivers/power/regulator/pwm_regulator.c
+++ b/drivers/power/regulator/pwm_regulator.c
@@ -24,6 +24,12 @@ struct pwm_regulator_info {
int pwm_id;
/* the period of one PWM cycle */
int period_ns;
+ /*
+ * the polarity of one PWM
+ * 0: normal polarity
+ * 1: inverted polarity
+ */
+ bool polarity;
struct udevice *pwm;
/* initialize voltage of regulator */
unsigned int init_voltage;
@@ -49,7 +55,7 @@ static int pwm_voltage_to_duty_cycle_percentage(struct udevice *dev, int req_uV)
int max_uV = priv->max_voltage;
int diff = max_uV - min_uV;
- return 100 - (((req_uV * 100) - (min_uV * 100)) / diff);
+ return ((req_uV * 100) - (min_uV * 100)) / diff;
}
static int pwm_regulator_get_voltage(struct udevice *dev)
@@ -67,6 +73,12 @@ static int pwm_regulator_set_voltage(struct udevice *dev, int uvolt)
duty_cycle = pwm_voltage_to_duty_cycle_percentage(dev, uvolt);
+ ret = pwm_set_invert(priv->pwm, priv->pwm_id, priv->polarity);
+ if (ret) {
+ dev_err(dev, "Failed to init PWM\n");
+ return ret;
+ }
+
ret = pwm_set_config(priv->pwm, priv->pwm_id,
(priv->period_ns / 100) * duty_cycle, priv->period_ns);
if (ret) {
@@ -97,9 +109,9 @@ static int pwm_regulator_ofdata_to_platdata(struct udevice *dev)
debug("%s: Cannot get PWM phandle: ret=%d\n", __func__, ret);
return ret;
}
- /* TODO: pwm_id here from device tree if needed */
priv->period_ns = args.args[1];
+ priv->polarity = args.args[2];
priv->init_voltage = fdtdec_get_int(blob, node,
"regulator-init-microvolt", -1);
diff --git a/drivers/power/regulator/rk808.c b/drivers/power/regulator/rk8xx.c
index adef8f57f27..e655c2d91f5 100644
--- a/drivers/power/regulator/rk808.c
+++ b/drivers/power/regulator/rk8xx.c
@@ -12,7 +12,7 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
-#include <power/rk808_pmic.h>
+#include <power/rk8xx_pmic.h>
#include <power/pmic.h>
#include <power/regulator.h>
@@ -20,36 +20,88 @@
#define ENABLE_DRIVER
#endif
-struct rk808_reg_info {
+/* Field Definitions */
+#define RK808_BUCK_VSEL_MASK 0x3f
+#define RK808_BUCK4_VSEL_MASK 0xf
+#define RK808_LDO_VSEL_MASK 0x1f
+
+#define RK818_BUCK_VSEL_MASK 0x3f
+#define RK818_BUCK4_VSEL_MASK 0x1f
+#define RK818_LDO_VSEL_MASK 0x1f
+#define RK818_LDO3_ON_VSEL_MASK 0xf
+#define RK818_BOOST_ON_VSEL_MASK 0xe0
+
+struct rk8xx_reg_info {
uint min_uv;
uint step_uv;
s8 vsel_reg;
- u8 vsel_bits;
+ u8 vsel_mask;
+};
+
+static const struct rk8xx_reg_info rk808_buck[] = {
+ { 712500, 12500, REG_BUCK1_ON_VSEL, RK808_BUCK_VSEL_MASK, },
+ { 712500, 12500, REG_BUCK2_ON_VSEL, RK808_BUCK_VSEL_MASK, },
+ { 712500, 12500, -1, RK808_BUCK_VSEL_MASK, },
+ { 1800000, 100000, REG_BUCK4_ON_VSEL, RK808_BUCK4_VSEL_MASK, },
};
-static const struct rk808_reg_info rk808_buck[] = {
- { 712500, 12500, REG_BUCK1_ON_VSEL, 6, },
- { 712500, 12500, REG_BUCK2_ON_VSEL, 6, },
- { 712500, 12500, -1, 6, },
- { 1800000, 100000, REG_BUCK4_ON_VSEL, 4, },
+static const struct rk8xx_reg_info rk808_ldo[] = {
+ { 1800000, 100000, REG_LDO1_ON_VSEL, RK808_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO2_ON_VSEL, RK808_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO3_ON_VSEL, RK808_BUCK4_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO4_ON_VSEL, RK808_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO5_ON_VSEL, RK808_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO6_ON_VSEL, RK808_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO7_ON_VSEL, RK808_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO8_ON_VSEL, RK808_LDO_VSEL_MASK, },
};
-static const struct rk808_reg_info rk808_ldo[] = {
- { 1800000, 100000, LDO1_ON_VSEL, 5, },
- { 1800000, 100000, LDO2_ON_VSEL, 5, },
- { 800000, 100000, LDO3_ON_VSEL, 4, },
- { 1800000, 100000, LDO4_ON_VSEL, 5, },
- { 1800000, 100000, LDO5_ON_VSEL, 5, },
- { 800000, 100000, LDO6_ON_VSEL, 5, },
- { 800000, 100000, LDO7_ON_VSEL, 5, },
- { 1800000, 100000, LDO8_ON_VSEL, 5, },
+static const struct rk8xx_reg_info rk818_buck[] = {
+ { 712500, 12500, REG_BUCK1_ON_VSEL, RK818_BUCK_VSEL_MASK, },
+ { 712500, 12500, REG_BUCK2_ON_VSEL, RK818_BUCK_VSEL_MASK, },
+ { 712500, 12500, -1, RK818_BUCK_VSEL_MASK, },
+ { 1800000, 100000, REG_BUCK4_ON_VSEL, RK818_BUCK4_VSEL_MASK, },
};
+static const struct rk8xx_reg_info rk818_ldo[] = {
+ { 1800000, 100000, REG_LDO1_ON_VSEL, RK818_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO2_ON_VSEL, RK818_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO3_ON_VSEL, RK818_LDO3_ON_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO4_ON_VSEL, RK818_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO5_ON_VSEL, RK818_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO6_ON_VSEL, RK818_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO7_ON_VSEL, RK818_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO8_ON_VSEL, RK818_LDO_VSEL_MASK, },
+};
+
+static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
+ int num)
+{
+ struct rk8xx_priv *priv = dev_get_priv(pmic);
+ switch (priv->variant) {
+ case RK818_ID:
+ return &rk818_buck[num];
+ default:
+ return &rk808_buck[num];
+ }
+}
+
+static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
+ int num)
+{
+ struct rk8xx_priv *priv = dev_get_priv(pmic);
+ switch (priv->variant) {
+ case RK818_ID:
+ return &rk818_ldo[num - 1];
+ default:
+ return &rk808_ldo[num - 1];
+ }
+}
static int _buck_set_value(struct udevice *pmic, int buck, int uvolt)
{
- const struct rk808_reg_info *info = &rk808_buck[buck - 1];
- int mask = (1 << info->vsel_bits) - 1;
+ const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck - 1);
+ int mask = info->vsel_mask;
int val;
if (info->vsel_reg == -1)
@@ -69,7 +121,7 @@ static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
buck--;
mask = 1 << buck;
if (enable) {
- ret = pmic_clrsetbits(pmic, DCDC_ILMAX, 0, 3 << (buck * 2));
+ ret = pmic_clrsetbits(pmic, REG_DCDC_ILMAX, 0, 3 << (buck * 2));
if (ret)
return ret;
ret = pmic_clrsetbits(pmic, REG_DCDC_UV_ACT, 1 << buck, 0);
@@ -84,8 +136,8 @@ static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
static int buck_get_value(struct udevice *dev)
{
int buck = dev->driver_data - 1;
- const struct rk808_reg_info *info = &rk808_buck[buck];
- int mask = (1 << info->vsel_bits) - 1;
+ const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck);
+ int mask = info->vsel_mask;
int ret, val;
if (info->vsel_reg == -1)
@@ -130,8 +182,8 @@ static bool buck_get_enable(struct udevice *dev)
static int ldo_get_value(struct udevice *dev)
{
int ldo = dev->driver_data - 1;
- const struct rk808_reg_info *info = &rk808_ldo[ldo];
- int mask = (1 << info->vsel_bits) - 1;
+ const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
+ int mask = info->vsel_mask;
int ret, val;
if (info->vsel_reg == -1)
@@ -147,8 +199,8 @@ static int ldo_get_value(struct udevice *dev)
static int ldo_set_value(struct udevice *dev, int uvolt)
{
int ldo = dev->driver_data - 1;
- const struct rk808_reg_info *info = &rk808_ldo[ldo];
- int mask = (1 << info->vsel_bits) - 1;
+ const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
+ int mask = info->vsel_mask;
int val;
if (info->vsel_reg == -1)
@@ -212,7 +264,7 @@ static bool switch_get_enable(struct udevice *dev)
return ret & mask ? true : false;
}
-static int rk808_buck_probe(struct udevice *dev)
+static int rk8xx_buck_probe(struct udevice *dev)
{
struct dm_regulator_uclass_platdata *uc_pdata;
@@ -224,7 +276,7 @@ static int rk808_buck_probe(struct udevice *dev)
return 0;
}
-static int rk808_ldo_probe(struct udevice *dev)
+static int rk8xx_ldo_probe(struct udevice *dev)
{
struct dm_regulator_uclass_platdata *uc_pdata;
@@ -236,7 +288,7 @@ static int rk808_ldo_probe(struct udevice *dev)
return 0;
}
-static int rk808_switch_probe(struct udevice *dev)
+static int rk8xx_switch_probe(struct udevice *dev)
{
struct dm_regulator_uclass_platdata *uc_pdata;
@@ -248,48 +300,48 @@ static int rk808_switch_probe(struct udevice *dev)
return 0;
}
-static const struct dm_regulator_ops rk808_buck_ops = {
+static const struct dm_regulator_ops rk8xx_buck_ops = {
.get_value = buck_get_value,
.set_value = buck_set_value,
.get_enable = buck_get_enable,
.set_enable = buck_set_enable,
};
-static const struct dm_regulator_ops rk808_ldo_ops = {
+static const struct dm_regulator_ops rk8xx_ldo_ops = {
.get_value = ldo_get_value,
.set_value = ldo_set_value,
.get_enable = ldo_get_enable,
.set_enable = ldo_set_enable,
};
-static const struct dm_regulator_ops rk808_switch_ops = {
+static const struct dm_regulator_ops rk8xx_switch_ops = {
.get_enable = switch_get_enable,
.set_enable = switch_set_enable,
};
-U_BOOT_DRIVER(rk808_buck) = {
- .name = "rk808_buck",
+U_BOOT_DRIVER(rk8xx_buck) = {
+ .name = "rk8xx_buck",
.id = UCLASS_REGULATOR,
- .ops = &rk808_buck_ops,
- .probe = rk808_buck_probe,
+ .ops = &rk8xx_buck_ops,
+ .probe = rk8xx_buck_probe,
};
-U_BOOT_DRIVER(rk808_ldo) = {
- .name = "rk808_ldo",
+U_BOOT_DRIVER(rk8xx_ldo) = {
+ .name = "rk8xx_ldo",
.id = UCLASS_REGULATOR,
- .ops = &rk808_ldo_ops,
- .probe = rk808_ldo_probe,
+ .ops = &rk8xx_ldo_ops,
+ .probe = rk8xx_ldo_probe,
};
-U_BOOT_DRIVER(rk808_switch) = {
- .name = "rk808_switch",
+U_BOOT_DRIVER(rk8xx_switch) = {
+ .name = "rk8xx_switch",
.id = UCLASS_REGULATOR,
- .ops = &rk808_switch_ops,
- .probe = rk808_switch_probe,
+ .ops = &rk8xx_switch_ops,
+ .probe = rk8xx_switch_probe,
};
#endif
-int rk808_spl_configure_buck(struct udevice *pmic, int buck, int uvolt)
+int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt)
{
int ret;