From 9d233b4e3ed675561c4e3bd904e0a314f20dbe82 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 24 Oct 2019 15:00:46 +0530 Subject: [PATCH 01/25] misc: k3_avs: add driver for K3 Adaptive Voltage Scaling Class 0 Adaptive Voltage Scaling is a technology used in TI SoCs to optimize the operating voltage based on characterization data written to efuse during production. Add a driver to support this feature for K3 line of SoCs, initially for AM65x. Signed-off-by: Tero Kristo Signed-off-by: Keerthy --- drivers/misc/Kconfig | 9 ++ drivers/misc/Makefile | 1 + drivers/misc/k3_avs.c | 366 ++++++++++++++++++++++++++++++++++++++++++ include/k3-avs.h | 28 ++++ 4 files changed, 404 insertions(+) create mode 100644 drivers/misc/k3_avs.c create mode 100644 include/k3-avs.h diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 4985ea033b..7a8ba587da 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -421,4 +421,13 @@ config MICROCHIP_FLEXCOM Only one function can be used at a time and is chosen at boot time according to the device tree. +config K3_AVS0 + depends on ARCH_K3 && SPL_DM_REGULATOR + bool "AVS class 0 support for K3 devices" + help + K3 devices have the optimized voltage values for the main voltage + domains stored in efuse within the VTM IP. This driver reads the + optimized voltage from the efuse, so that it can be programmed + to the PMIC on board. + endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index f61263640b..870655e802 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -66,3 +66,4 @@ obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress_config.o obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o obj-$(CONFIG_JZ4780_EFUSE) += jz4780_efuse.o obj-$(CONFIG_MICROCHIP_FLEXCOM) += microchip_flexcom.o +obj-$(CONFIG_K3_AVS0) += k3_avs.o diff --git a/drivers/misc/k3_avs.c b/drivers/misc/k3_avs.c new file mode 100644 index 0000000000..dd7fc3d585 --- /dev/null +++ b/drivers/misc/k3_avs.c @@ -0,0 +1,366 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Texas Instruments' K3 Clas 0 Adaptive Voltage Scaling driver + * + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ + * Tero Kristo + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#define AM6_VTM_DEVINFO(i) (priv->base + 0x100 + 0x20 * (i)) +#define AM6_VTM_OPPVID_VD(i) (priv->base + 0x104 + 0x20 * (i)) + +#define AM6_VTM_AVS0_SUPPORTED BIT(12) + +#define AM6_VTM_OPP_SHIFT(opp) (8 * (opp)) +#define AM6_VTM_OPP_MASK 0xff + +#define VD_FLAG_INIT_DONE BIT(0) + +struct k3_avs_privdata { + void *base; + struct vd_config *vd_config; +}; + +struct opp { + u32 freq; + u32 volt; +}; + +struct vd_data { + int id; + u8 opp; + u8 flags; + int dev_id; + int clk_id; + struct opp opps[NUM_OPPS]; + struct udevice *supply; +}; + +struct vd_config { + struct vd_data *vds; + u32 (*efuse_xlate)(struct k3_avs_privdata *priv, int idx, int opp); +}; + +static struct k3_avs_privdata *k3_avs_priv; + +/** + * am6_efuse_voltage: read efuse voltage from VTM + * @priv: driver private data + * @idx: VD to read efuse for + * @opp: opp id to read + * + * Reads efuse value for the specified OPP, and converts the register + * value to a voltage. Returns the voltage in uV, or 0 if nominal voltage + * should be used. + * + * Efuse val to volt conversion logic: + * + * val > 171 volt increments in 20mV steps with base 171 => 1.66V + * val between 115 to 11 increments in 10mV steps with base 115 => 1.1V + * val between 15 to 115 increments in 5mV steps with base 15 => .6V + * val between 1 to 15 increments in 20mv steps with base 0 => .3V + * val 0 is invalid + */ +static u32 am6_efuse_xlate(struct k3_avs_privdata *priv, int idx, int opp) +{ + u32 val = readl(AM6_VTM_OPPVID_VD(idx)); + + val >>= AM6_VTM_OPP_SHIFT(opp); + val &= AM6_VTM_OPP_MASK; + + if (!val) + return 0; + + if (val > 171) + return 1660000 + 20000 * (val - 171); + + if (val > 115) + return 1100000 + 10000 * (val - 115); + + if (val > 15) + return 600000 + 5000 * (val - 15); + + return 300000 + 20000 * val; +} + +static int k3_avs_program_voltage(struct k3_avs_privdata *priv, + struct vd_data *vd, + int opp_id) +{ + u32 volt = vd->opps[opp_id].volt; + struct vd_data *vd2; + + if (!vd->supply) + return -ENODEV; + + vd->opp = opp_id; + vd->flags |= VD_FLAG_INIT_DONE; + + /* Take care of ganged rails and pick the Max amongst them*/ + for (vd2 = priv->vd_config->vds; vd2->id >= 0; vd2++) { + if (vd == vd2) + continue; + + if (vd2->supply != vd->supply) + continue; + + if (vd2->opps[vd2->opp].volt > volt) + volt = vd2->opps[vd2->opp].volt; + + vd2->flags |= VD_FLAG_INIT_DONE; + } + + return regulator_set_value(vd->supply, volt); +} + +static struct vd_data *get_vd(struct k3_avs_privdata *priv, int idx) +{ + struct vd_data *vd; + + for (vd = priv->vd_config->vds; vd->id >= 0 && vd->id != idx; vd++) + ; + + if (vd->id < 0) + return NULL; + + return vd; +} + +/** + * k3_avs_set_opp: Sets the voltage for an arbitrary VD rail + * @dev: AVS device + * @vdd_id: voltage domain ID + * @opp_id: OPP ID + * + * Programs the desired OPP value for the defined voltage rail. This + * should be called from board files if reconfiguration is desired. + * Returns 0 on success, negative error value on failure. + */ +int k3_avs_set_opp(struct udevice *dev, int vdd_id, int opp_id) +{ + struct k3_avs_privdata *priv = dev_get_priv(dev); + struct vd_data *vd; + + vd = get_vd(priv, vdd_id); + if (!vd) + return -EINVAL; + + return k3_avs_program_voltage(priv, vd, opp_id); +} + +static int match_opp(struct vd_data *vd, u32 freq) +{ + struct opp *opp; + int opp_id; + + for (opp_id = 0; opp_id < NUM_OPPS; opp_id++) { + opp = &vd->opps[opp_id]; + if (opp->freq == freq) + return opp_id; + } + + printf("No matching OPP found for freq %d.\n", freq); + + return -EINVAL; +} + +/** + * k3_avs_notify_freq: Notify clock rate change towards AVS subsystem + * @dev_id: Device ID for the clock to be changed + * @clk_id: Clock ID for the clock to be changed + * @freq: New frequency for clock + * + * Checks if the provided clock is the MPU clock or not, if not, return + * immediately. If MPU clock is provided, maps the provided MPU frequency + * towards an MPU OPP, and programs the voltage to the regulator. Return 0 + * on success, negative error value on failure. + */ +int k3_avs_notify_freq(int dev_id, int clk_id, u32 freq) +{ + int opp_id; + struct k3_avs_privdata *priv = k3_avs_priv; + struct vd_data *vd; + + for (vd = priv->vd_config->vds; vd->id >= 0; vd++) { + if (vd->dev_id != dev_id || vd->clk_id != clk_id) + continue; + + opp_id = match_opp(vd, freq); + if (opp_id < 0) + return opp_id; + + vd->opp = opp_id; + return k3_avs_program_voltage(priv, vd, opp_id); + } + + return -EINVAL; +} + +static int k3_avs_configure(struct udevice *dev, struct k3_avs_privdata *priv) +{ + struct vd_config *conf; + int ret; + char pname[20]; + struct vd_data *vd; + + conf = (void *)dev_get_driver_data(dev); + + priv->vd_config = conf; + + for (vd = conf->vds; vd->id >= 0; vd++) { + sprintf(pname, "vdd-supply-%d", vd->id); + ret = device_get_supply_regulator(dev, pname, &vd->supply); + if (ret) + dev_warn(dev, "supply not found for VD%d.\n", vd->id); + + sprintf(pname, "ti,default-opp-%d", vd->id); + ret = dev_read_u32_default(dev, pname, -1); + if (ret != -1) + vd->opp = ret; + } + + return 0; +} + +/** + * k3_avs_probe: parses VD info from VTM, and re-configures the OPP data + * + * Parses all VDs on a device calculating the AVS class-0 voltages for them, + * and updates the vd_data based on this. The vd_data itself shall be used + * to program the required OPPs later on. Returns 0 on success, negative + * error value on failure. + */ +static int k3_avs_probe(struct udevice *dev) +{ + int opp_id; + u32 volt; + struct opp *opp; + struct k3_avs_privdata *priv; + struct vd_data *vd; + int ret; + + priv = dev_get_priv(dev); + + k3_avs_priv = priv; + + ret = k3_avs_configure(dev, priv); + if (ret) + return ret; + + priv->base = dev_read_addr_ptr(dev); + if (!priv->base) + return -ENODEV; + + for (vd = priv->vd_config->vds; vd->id >= 0; vd++) { + if (!(readl(AM6_VTM_DEVINFO(vd->id)) & + AM6_VTM_AVS0_SUPPORTED)) { + dev_warn(dev, "AVS-class 0 not supported for VD%d\n", + vd->id); + continue; + } + + for (opp_id = 0; opp_id < NUM_OPPS; opp_id++) { + opp = &vd->opps[opp_id]; + + if (!opp->freq) + continue; + + volt = priv->vd_config->efuse_xlate(priv, vd->id, + opp_id); + if (volt) + opp->volt = volt; + } + } + + for (vd = priv->vd_config->vds; vd->id >= 0; vd++) { + if (vd->flags & VD_FLAG_INIT_DONE) + continue; + + k3_avs_program_voltage(priv, vd, vd->opp); + } + + return 0; +} + +static struct vd_data am654_vd_data[] = { + { + .id = AM6_VDD_CORE, + .dev_id = 82, /* AM6_DEV_CBASS0 */ + .clk_id = 0, /* main sysclk0 */ + .opp = AM6_OPP_NOM, + .opps = { + [AM6_OPP_NOM] = { + .volt = 1000000, + .freq = 250000000, /* CBASS0 */ + }, + }, + }, + { + .id = AM6_VDD_MPU0, + .dev_id = 202, /* AM6_DEV_COMPUTE_CLUSTER_A53_0 */ + .clk_id = 0, /* ARM clock */ + .opp = AM6_OPP_NOM, + .opps = { + [AM6_OPP_NOM] = { + .volt = 1000000, + .freq = 800000000, + }, + [AM6_OPP_OD] = { + .volt = 1100000, + .freq = 1000000000, + }, + [AM6_OPP_TURBO] = { + .volt = 1220000, + .freq = 1100000000, + }, + }, + }, + { + .id = AM6_VDD_MPU1, + .opp = AM6_OPP_NOM, + .dev_id = 204, /* AM6_DEV_COMPUTE_CLUSTER_A53_2 */ + .clk_id = 0, /* ARM clock */ + .opps = { + [AM6_OPP_NOM] = { + .volt = 1000000, + .freq = 800000000, + }, + [AM6_OPP_OD] = { + .volt = 1100000, + .freq = 1000000000, + }, + [AM6_OPP_TURBO] = { + .volt = 1220000, + .freq = 1100000000, + }, + }, + }, + { .id = -1 }, +}; + +static struct vd_config am654_vd_config = { + .efuse_xlate = am6_efuse_xlate, + .vds = am654_vd_data, +}; + +static const struct udevice_id k3_avs_ids[] = { + { .compatible = "ti,am654-avs", .data = (ulong)&am654_vd_config }, + {} +}; + +U_BOOT_DRIVER(k3_avs) = { + .name = "k3_avs", + .of_match = k3_avs_ids, + .id = UCLASS_MISC, + .probe = k3_avs_probe, + .priv_auto_alloc_size = sizeof(struct k3_avs_privdata), +}; diff --git a/include/k3-avs.h b/include/k3-avs.h new file mode 100644 index 0000000000..9867481617 --- /dev/null +++ b/include/k3-avs.h @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Texas Instruments' K3 Adaptive Voltage Scaling driver + * + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ + * Tero Kristo + * + */ + +#ifndef _K3_AVS0_ +#define _K3_AVS0_ + +#define AM6_VDD_WKUP 0 +#define AM6_VDD_MCU 1 +#define AM6_VDD_CORE 2 +#define AM6_VDD_MPU0 3 +#define AM6_VDD_MPU1 4 + +#define NUM_OPPS 4 + +#define AM6_OPP_NOM 1 +#define AM6_OPP_OD 2 +#define AM6_OPP_TURBO 3 + +int k3_avs_set_opp(struct udevice *dev, int vdd_id, int opp_id); +int k3_avs_notify_freq(int dev_id, int clk_id, u32 freq); + +#endif From e0aa873bc7cd38d802cfdbe186fbbbafb9f6691e Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 24 Oct 2019 15:00:47 +0530 Subject: [PATCH 02/25] clk: clk-ti-sci: Notify AVS driver upon setting clock rate Notify AVS driver upon setting clock rate so that voltage is changed accordingly. Signed-off-by: Keerthy --- drivers/clk/clk-ti-sci.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/clk/clk-ti-sci.c b/drivers/clk/clk-ti-sci.c index c25415d410..478349f22f 100644 --- a/drivers/clk/clk-ti-sci.c +++ b/drivers/clk/clk-ti-sci.c @@ -13,6 +13,7 @@ #include #include #include +#include /** * struct ti_sci_clk_data - clock controller information structure @@ -101,6 +102,10 @@ static ulong ti_sci_clk_set_rate(struct clk *clk, ulong rate) debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate); +#ifdef CONFIG_K3_AVS0 + k3_avs_notify_freq(clk->id, clk->data, rate); +#endif + /* Ask for exact frequency by using same value for min/target/max */ ret = cops->set_freq(sci, clk->id, clk->data, rate, rate, rate); if (ret) From 22e8f18980d645f2489fa3f9cb034e416940df66 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 24 Oct 2019 15:00:48 +0530 Subject: [PATCH 03/25] power: regulator: tps6236x: add support for tps6236x regulators TPS6236x is a family of step down DC-DC converters optimized for battery powered portable applications for a small solution size. Add a regulator driver for supporting these devices. Signed-off-by: Tero Kristo Signed-off-by: Keerthy --- drivers/power/regulator/Kconfig | 10 ++ drivers/power/regulator/Makefile | 1 + drivers/power/regulator/tps62360_regulator.c | 123 +++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 drivers/power/regulator/tps62360_regulator.c diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index 9aa00fad42..56d68ee40e 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -273,6 +273,16 @@ config DM_REGULATOR_TPS65910 regulator types of the TPS65910 (BUCK, BOOST and LDO). It implements the get/set api for value and enable. +config DM_REGULATOR_TPS62360 + bool "Enable driver for TPS6236x Power Regulator" + depends on DM_REGULATOR + help + The TPS6236X DC/DC step down converter provides a single output + power line peaking at 3A current. This driver supports all four + variants of the chip (TPS62360, TPS62361, TPS62362, TPS62363). It + implements the get/set api for value only, as the power line is + always on. + config DM_REGULATOR_STPMIC1 bool "Enable driver for STPMIC1 regulators" depends on DM_REGULATOR && PMIC_STPMIC1 diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index 6a3d4bbee4..9198841b4f 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -26,4 +26,5 @@ obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP87565) += lp87565_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o obj-$(CONFIG_DM_REGULATOR_TPS65910) += tps65910_regulator.o +obj-$(CONFIG_DM_REGULATOR_TPS62360) += tps62360_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMIC1) += stpmic1.o diff --git a/drivers/power/regulator/tps62360_regulator.c b/drivers/power/regulator/tps62360_regulator.c new file mode 100644 index 0000000000..3b123f503c --- /dev/null +++ b/drivers/power/regulator/tps62360_regulator.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ + * Tero Kristo + */ + +#include +#include +#include +#include + +#define TPS62360_REG_SET0 0 + +#define TPS62360_I2C_CHIP 0x60 + +#define TPS62360_VSEL_STEPSIZE 10000 /* In uV */ + +struct tps62360_regulator_config { + u32 vmin; + u32 vmax; +}; + +struct tps62360_regulator_pdata { + u8 vsel_offset; + struct udevice *i2c; + struct tps62360_regulator_config *config; +}; + +/* + * TPS62362/TPS62363 are just re-using these values for now, their preset + * voltage values are just different compared to TPS62360/TPS62361. + */ +static struct tps62360_regulator_config tps62360_data = { + .vmin = 770000, + .vmax = 1400000, +}; + +static struct tps62360_regulator_config tps62361_data = { + .vmin = 500000, + .vmax = 1770000, +}; + +static int tps62360_regulator_set_value(struct udevice *dev, int uV) +{ + struct tps62360_regulator_pdata *pdata = dev_get_platdata(dev); + u8 regval; + + if (uV < pdata->config->vmin || uV > pdata->config->vmax) + return -EINVAL; + + uV -= pdata->config->vmin; + + uV = DIV_ROUND_UP(uV, TPS62360_VSEL_STEPSIZE); + + if (uV > U8_MAX) + return -EINVAL; + + regval = (u8)uV; + + return dm_i2c_write(pdata->i2c, TPS62360_REG_SET0 + pdata->vsel_offset, + ®val, 1); +} + +static int tps62360_regulator_get_value(struct udevice *dev) +{ + u8 regval; + int ret; + struct tps62360_regulator_pdata *pdata = dev_get_platdata(dev); + + ret = dm_i2c_read(pdata->i2c, TPS62360_REG_SET0 + pdata->vsel_offset, + ®val, 1); + if (ret) { + dev_err(dev, "i2c read failed: %d\n", ret); + return ret; + } + + return (u32)regval * TPS62360_VSEL_STEPSIZE + pdata->config->vmin; +} + +static int tps62360_regulator_ofdata_to_platdata(struct udevice *dev) +{ + struct tps62360_regulator_pdata *pdata = dev_get_platdata(dev); + u8 vsel0; + u8 vsel1; + int ret; + + pdata->config = (void *)dev_get_driver_data(dev); + + vsel0 = dev_read_bool(dev, "ti,vsel0-state-high"); + vsel1 = dev_read_bool(dev, "ti,vsel1-state-high"); + + pdata->vsel_offset = vsel0 + vsel1 * 2; + + ret = i2c_get_chip(dev->parent, TPS62360_I2C_CHIP, 1, &pdata->i2c); + if (ret) { + dev_err(dev, "i2c dev get failed.\n"); + return ret; + } + + return 0; +} + +static const struct dm_regulator_ops tps62360_regulator_ops = { + .get_value = tps62360_regulator_get_value, + .set_value = tps62360_regulator_set_value, +}; + +static const struct udevice_id tps62360_regulator_ids[] = { + { .compatible = "ti,tps62360", .data = (ulong)&tps62360_data }, + { .compatible = "ti,tps62361", .data = (ulong)&tps62361_data }, + { .compatible = "ti,tps62362", .data = (ulong)&tps62360_data }, + { .compatible = "ti,tps62363", .data = (ulong)&tps62361_data }, + { }, +}; + +U_BOOT_DRIVER(tps62360_regulator) = { + .name = "tps62360_regulator", + .id = UCLASS_REGULATOR, + .ops = &tps62360_regulator_ops, + .of_match = tps62360_regulator_ids, + .platdata_auto_alloc_size = sizeof(struct tps62360_regulator_pdata), + .ofdata_to_platdata = tps62360_regulator_ofdata_to_platdata, +}; From 9a03e50c5fad1daff7335dafa5b8b7e2a66ce6c9 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 24 Oct 2019 15:00:49 +0530 Subject: [PATCH 04/25] misc: k3_avs: Add j721e support j721e SoCs have different OPP tables. Add support for the same. Note: DM Still has lot of voltages TBD hence the correct values need to be programmed once they are published. Signed-off-by: Keerthy --- drivers/misc/k3_avs.c | 22 ++++++++++++++++++++++ include/k3-avs.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/misc/k3_avs.c b/drivers/misc/k3_avs.c index dd7fc3d585..c19c3c0646 100644 --- a/drivers/misc/k3_avs.c +++ b/drivers/misc/k3_avs.c @@ -347,6 +347,27 @@ static struct vd_data am654_vd_data[] = { { .id = -1 }, }; +static struct vd_data j721e_vd_data[] = { + { + .id = J721E_VDD_MPU, + .opp = AM6_OPP_NOM, + .dev_id = 202, /* J721E_DEV_A72SS0_CORE0 */ + .clk_id = 2, /* ARM clock */ + .opps = { + [AM6_OPP_NOM] = { + .volt = 880000, /* TBD in DM */ + .freq = 2000000000, + }, + }, + }, + { .id = -1 }, +}; + +static struct vd_config j721e_vd_config = { + .efuse_xlate = am6_efuse_xlate, + .vds = j721e_vd_data, +}; + static struct vd_config am654_vd_config = { .efuse_xlate = am6_efuse_xlate, .vds = am654_vd_data, @@ -354,6 +375,7 @@ static struct vd_config am654_vd_config = { static const struct udevice_id k3_avs_ids[] = { { .compatible = "ti,am654-avs", .data = (ulong)&am654_vd_config }, + { .compatible = "ti,j721e-avs", .data = (ulong)&j721e_vd_config }, {} }; diff --git a/include/k3-avs.h b/include/k3-avs.h index 9867481617..e3c3cafbb9 100644 --- a/include/k3-avs.h +++ b/include/k3-avs.h @@ -16,6 +16,8 @@ #define AM6_VDD_MPU0 3 #define AM6_VDD_MPU1 4 +#define J721E_VDD_MPU 2 + #define NUM_OPPS 4 #define AM6_OPP_NOM 1 From 6b86dd0c1eadab4382c394d2c17379f5c762f210 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 24 Oct 2019 15:00:50 +0530 Subject: [PATCH 05/25] power: pmic: tps65941: Add support for tps65941 family of PMICs Add support to bind the regulators/child nodes with the pmic. Signed-off-by: Keerthy --- drivers/power/pmic/Kconfig | 7 +++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/tps65941.c | 83 +++++++++++++++++++++++++++++++++++ include/power/tps65941.h | 26 +++++++++++ 4 files changed, 117 insertions(+) create mode 100644 drivers/power/pmic/tps65941.c create mode 100644 include/power/tps65941.h diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 4718dc700c..b4bf018674 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -275,3 +275,10 @@ config SPL_PMIC_LP87565 help The LP87565 is a PMIC containing a bunch of SMPS. This driver binds the pmic children in SPL. + +config PMIC_TPS65941 + bool "Enable driver for Texas Instruments TPS65941 PMIC" + depends on DM_PMIC + help + The TPS65941 is a PMIC containing a bunch of SMPS & LDOs. + This driver binds the pmic children. diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 888dbb2857..ec64327805 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -39,3 +39,4 @@ obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o obj-$(CONFIG_POWER_TPS65910) += pmic_tps65910.o obj-$(CONFIG_POWER_HI6553) += pmic_hi6553.o obj-$(CONFIG_POWER_MC34VR500) += pmic_mc34vr500.o +obj-$(CONFIG_PMIC_TPS65941) += tps65941.o diff --git a/drivers/power/pmic/tps65941.c b/drivers/power/pmic/tps65941.c new file mode 100644 index 0000000000..e8f3c950bd --- /dev/null +++ b/drivers/power/pmic/tps65941.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2019 Texas Instruments Incorporated, + * Keerthy + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct pmic_child_info pmic_children_info[] = { + { .prefix = "ldo", .driver = TPS65941_LDO_DRIVER }, + { .prefix = "buck", .driver = TPS65941_BUCK_DRIVER }, + { }, +}; + +static int tps65941_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) +{ + if (dm_i2c_write(dev, reg, buff, len)) { + pr_err("write error to device: %p register: %#x!\n", dev, reg); + return -EIO; + } + + return 0; +} + +static int tps65941_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + if (dm_i2c_read(dev, reg, buff, len)) { + pr_err("read error from device: %p register: %#x!\n", dev, reg); + return -EIO; + } + + return 0; +} + +static int tps65941_bind(struct udevice *dev) +{ + ofnode regulators_node; + int children; + + regulators_node = dev_read_subnode(dev, "regulators"); + if (!ofnode_valid(regulators_node)) { + debug("%s: %s regulators subnode not found!\n", __func__, + dev->name); + return -ENXIO; + } + + debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); + + children = pmic_bind_children(dev, regulators_node, pmic_children_info); + if (!children) + printf("%s: %s - no child found\n", __func__, dev->name); + + /* Always return success for this device */ + return 0; +} + +static struct dm_pmic_ops tps65941_ops = { + .read = tps65941_read, + .write = tps65941_write, +}; + +static const struct udevice_id tps65941_ids[] = { + { .compatible = "ti,tps659411", .data = TPS659411 }, + { .compatible = "ti,tps659413", .data = TPS659413 }, + { } +}; + +U_BOOT_DRIVER(pmic_tps65941) = { + .name = "tps65941_pmic", + .id = UCLASS_PMIC, + .of_match = tps65941_ids, + .bind = tps65941_bind, + .ops = &tps65941_ops, +}; diff --git a/include/power/tps65941.h b/include/power/tps65941.h new file mode 100644 index 0000000000..2d48b31ae3 --- /dev/null +++ b/include/power/tps65941.h @@ -0,0 +1,26 @@ +#define TPS659411 0x0 +#define TPS659412 0x1 +#define TPS659413 0x2 +#define TPS659414 0x3 + +/* I2C device address for pmic tps65941 */ +#define TPS65941_I2C_ADDR (0x12 >> 1) +#define TPS65941_LDO_NUM 4 +#define TPS65941_BUCK_NUM 5 + +/* Drivers name */ +#define TPS65941_LDO_DRIVER "tps65941_ldo" +#define TPS65941_BUCK_DRIVER "tps65941_buck" + +#define TPS65941_BUCK_VOLT_MASK 0xFF +#define TPS65941_BUCK_VOLT_MAX_HEX 0xFF +#define TPS65941_BUCK_VOLT_MAX 3340000 +#define TPS65941_BUCK_MODE_MASK 0x1 + +#define TPS65941_LDO_VOLT_MASK 0x3E +#define TPS65941_LDO_VOLT_MAX_HEX 0x3A +#define TPS65941_LDO_VOLT_MIN_HEX 0x4 +#define TPS65941_LDO_VOLT_MAX 3300000 +#define TPS65941_LDO_MODE_MASK 0x1 +#define TPS65941_LDO_BYPASS_EN 0x80 +#define TP65941_BUCK_CONF_SLEW_MASK 0x7 From 065a452ae6a11dd9aa3cd0ba185f580c0c81ae2c Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 24 Oct 2019 15:00:51 +0530 Subject: [PATCH 06/25] power: regulator: tps65941: add regulator support The driver provides regulator set/get voltage enable/disable functions for tps65941 family of PMICs. Signed-off-by: Keerthy --- drivers/power/regulator/Kconfig | 10 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/tps65941_regulator.c | 407 +++++++++++++++++++ 3 files changed, 418 insertions(+) create mode 100644 drivers/power/regulator/tps65941_regulator.c diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index 56d68ee40e..25fc787a29 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -323,3 +323,13 @@ config SPL_DM_REGULATOR_LP873X This enables implementation of driver-model regulator uclass features for REGULATOR LP873X and the family of LP873X PMICs. The driver implements get/set api for: value and enable in SPL. + +config DM_REGULATOR_TPS65941 + bool "Enable driver for TPS65941 PMIC regulators" + depends on PMIC_TPS65941 + help + This enables implementation of driver-model regulator uclass + features for REGULATOR TPS65941 and the family of TPS65941 PMICs. + TPS65941 series of PMICs have 5 single phase BUCKs that can also + be configured in multi phase modes & 4 LDOs. The driver implements + get/set api for value and enable. diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index 9198841b4f..b611c901ba 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -28,3 +28,4 @@ obj-$(CONFIG_$(SPL_)DM_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o obj-$(CONFIG_DM_REGULATOR_TPS65910) += tps65910_regulator.o obj-$(CONFIG_DM_REGULATOR_TPS62360) += tps62360_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMIC1) += stpmic1.o +obj-$(CONFIG_DM_REGULATOR_TPS65941) += tps65941_regulator.o diff --git a/drivers/power/regulator/tps65941_regulator.c b/drivers/power/regulator/tps65941_regulator.c new file mode 100644 index 0000000000..a00ef58129 --- /dev/null +++ b/drivers/power/regulator/tps65941_regulator.c @@ -0,0 +1,407 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2019 + * Texas Instruments Incorporated, + * + * Keerthy + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA, + 0xC}; +static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12, + 0x14, 0x16}; +static const char tps65941_ldo_ctrl[TPS65941_BUCK_NUM] = {0x1D, 0x1E, 0x1F, + 0x20}; +static const char tps65941_ldo_vout[TPS65941_BUCK_NUM] = {0x23, 0x24, 0x25, + 0x26}; + +static int tps65941_buck_enable(struct udevice *dev, int op, bool *enable) +{ + int ret; + unsigned int adr; + struct dm_regulator_uclass_platdata *uc_pdata; + + uc_pdata = dev_get_uclass_platdata(dev); + adr = uc_pdata->ctrl_reg; + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + ret &= TPS65941_BUCK_MODE_MASK; + + if (ret) + *enable = true; + else + *enable = false; + + return 0; + } else if (op == PMIC_OP_SET) { + if (*enable) + ret |= TPS65941_BUCK_MODE_MASK; + else + ret &= ~TPS65941_BUCK_MODE_MASK; + ret = pmic_reg_write(dev->parent, adr, ret); + if (ret) + return ret; + } + + return 0; +} + +static int tps65941_buck_volt2val(int uV) +{ + if (uV > TPS65941_BUCK_VOLT_MAX) + return -EINVAL; + else if (uV > 1650000) + return (uV - 1660000) / 20000 + 0xAB; + else if (uV > 1110000) + return (uV - 1110000) / 10000 + 0x73; + else if (uV > 600000) + return (uV - 600000) / 5000 + 0x0F; + else if (uV >= 300000) + return (uV - 300000) / 20000 + 0x00; + else + return -EINVAL; +} + +static int tps65941_buck_val2volt(int val) +{ + if (val > TPS65941_BUCK_VOLT_MAX_HEX) + return -EINVAL; + else if (val > 0xAB) + return 1660000 + (val - 0xAB) * 20000; + else if (val > 0x73) + return 1100000 + (val - 0x73) * 10000; + else if (val > 0xF) + return 600000 + (val - 0xF) * 5000; + else if (val >= 0x0) + return 300000 + val * 5000; + else + return -EINVAL; +} + +int tps65941_lookup_slew(int id) +{ + switch (id) { + case 0: + return 33000; + case 1: + return 20000; + case 2: + return 10000; + case 3: + return 5000; + case 4: + return 2500; + case 5: + return 1300; + case 6: + return 630; + case 7: + return 310; + default: + return -1; + } +} + +static int tps65941_buck_val(struct udevice *dev, int op, int *uV) +{ + unsigned int hex, adr; + int ret, delta, uwait, slew; + struct dm_regulator_uclass_platdata *uc_pdata; + + uc_pdata = dev_get_uclass_platdata(dev); + + if (op == PMIC_OP_GET) + *uV = 0; + + adr = uc_pdata->volt_reg; + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + ret &= TPS65941_BUCK_VOLT_MASK; + ret = tps65941_buck_val2volt(ret); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + *uV = ret; + return 0; + } + + /* + * Compute the delta voltage, find the slew rate and wait + * for the appropriate amount of time after voltage switch + */ + if (*uV > ret) + delta = *uV - ret; + else + delta = ret - *uV; + + slew = pmic_reg_read(dev->parent, uc_pdata->ctrl_reg + 1); + if (slew < 0) + return ret; + + slew &= TP65941_BUCK_CONF_SLEW_MASK; + slew = tps65941_lookup_slew(slew); + if (slew <= 0) + return ret; + + uwait = delta / slew; + + hex = tps65941_buck_volt2val(*uV); + if (hex < 0) + return hex; + + ret &= 0x0; + ret = hex; + + ret = pmic_reg_write(dev->parent, adr, ret); + + udelay(uwait); + + return ret; +} + +static int tps65941_ldo_enable(struct udevice *dev, int op, bool *enable) +{ + int ret; + unsigned int adr; + struct dm_regulator_uclass_platdata *uc_pdata; + + uc_pdata = dev_get_uclass_platdata(dev); + adr = uc_pdata->ctrl_reg; + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + ret &= TPS65941_LDO_MODE_MASK; + + if (ret) + *enable = true; + else + *enable = false; + + return 0; + } else if (op == PMIC_OP_SET) { + if (*enable) + ret |= TPS65941_LDO_MODE_MASK; + else + ret &= ~TPS65941_LDO_MODE_MASK; + ret = pmic_reg_write(dev->parent, adr, ret); + if (ret) + return ret; + } + + return 0; +} + +static int tps65941_ldo_val2volt(int val) +{ + if (val > TPS65941_LDO_VOLT_MAX_HEX || val < TPS65941_LDO_VOLT_MIN_HEX) + return -EINVAL; + else if (val >= TPS65941_LDO_VOLT_MIN_HEX) + return 600000 + (val - TPS65941_LDO_VOLT_MIN_HEX) * 50000; + else + return -EINVAL; +} + +static int tps65941_ldo_val(struct udevice *dev, int op, int *uV) +{ + unsigned int hex, adr; + int ret; + struct dm_regulator_uclass_platdata *uc_pdata; + + uc_pdata = dev_get_uclass_platdata(dev); + + if (op == PMIC_OP_GET) + *uV = 0; + + adr = uc_pdata->volt_reg; + + ret = pmic_reg_read(dev->parent, adr); + if (ret < 0) + return ret; + + ret &= TPS65941_LDO_VOLT_MASK; + ret = tps65941_ldo_val2volt(ret); + if (ret < 0) + return ret; + + if (op == PMIC_OP_GET) { + *uV = ret; + return 0; + } + + hex = tps65941_buck_volt2val(*uV); + if (hex < 0) + return hex; + + ret &= 0x0; + ret = hex; + + ret = pmic_reg_write(dev->parent, adr, ret); + + return ret; +} + +static int tps65941_ldo_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + int idx; + + uc_pdata = dev_get_uclass_platdata(dev); + uc_pdata->type = REGULATOR_TYPE_LDO; + + idx = dev->driver_data; + if (idx == 1 || idx == 2 || idx == 3 || idx == 4) { + debug("Single phase regulator\n"); + } else { + printf("Wrong ID for regulator\n"); + return -EINVAL; + } + + uc_pdata->ctrl_reg = tps65941_ldo_ctrl[idx - 1]; + uc_pdata->volt_reg = tps65941_ldo_vout[idx - 1]; + + return 0; +} + +static int tps65941_buck_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + int idx; + + uc_pdata = dev_get_uclass_platdata(dev); + uc_pdata->type = REGULATOR_TYPE_BUCK; + + idx = dev->driver_data; + if (idx == 1 || idx == 2 || idx == 3 || idx == 4 || idx == 5) { + debug("Single phase regulator\n"); + } else if (idx == 12) { + idx = 1; + } else if (idx == 34) { + idx = 3; + } else if (idx == 1234) { + idx = 1; + } else { + printf("Wrong ID for regulator\n"); + return -EINVAL; + } + + uc_pdata->ctrl_reg = tps65941_buck_ctrl[idx - 1]; + uc_pdata->volt_reg = tps65941_buck_vout[idx - 1]; + + return 0; +} + +static int ldo_get_value(struct udevice *dev) +{ + int uV; + int ret; + + ret = tps65941_ldo_val(dev, PMIC_OP_GET, &uV); + if (ret) + return ret; + + return uV; +} + +static int ldo_set_value(struct udevice *dev, int uV) +{ + return tps65941_ldo_val(dev, PMIC_OP_SET, &uV); +} + +static int ldo_get_enable(struct udevice *dev) +{ + bool enable = false; + int ret; + + ret = tps65941_ldo_enable(dev, PMIC_OP_GET, &enable); + if (ret) + return ret; + + return enable; +} + +static int ldo_set_enable(struct udevice *dev, bool enable) +{ + return tps65941_ldo_enable(dev, PMIC_OP_SET, &enable); +} + +static int buck_get_value(struct udevice *dev) +{ + int uV; + int ret; + + ret = tps65941_buck_val(dev, PMIC_OP_GET, &uV); + if (ret) + return ret; + + return uV; +} + +static int buck_set_value(struct udevice *dev, int uV) +{ + return tps65941_buck_val(dev, PMIC_OP_SET, &uV); +} + +static int buck_get_enable(struct udevice *dev) +{ + bool enable = false; + int ret; + + ret = tps65941_buck_enable(dev, PMIC_OP_GET, &enable); + if (ret) + return ret; + + return enable; +} + +static int buck_set_enable(struct udevice *dev, bool enable) +{ + return tps65941_buck_enable(dev, PMIC_OP_SET, &enable); +} + +static const struct dm_regulator_ops tps65941_ldo_ops = { + .get_value = ldo_get_value, + .set_value = ldo_set_value, + .get_enable = ldo_get_enable, + .set_enable = ldo_set_enable, +}; + +U_BOOT_DRIVER(tps65941_ldo) = { + .name = TPS65941_LDO_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &tps65941_ldo_ops, + .probe = tps65941_ldo_probe, +}; + +static const struct dm_regulator_ops tps65941_buck_ops = { + .get_value = buck_get_value, + .set_value = buck_set_value, + .get_enable = buck_get_enable, + .set_enable = buck_set_enable, +}; + +U_BOOT_DRIVER(tps65941_buck) = { + .name = TPS65941_BUCK_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &tps65941_buck_ops, + .probe = tps65941_buck_probe, +}; From 27380cb7e966f779f52d13f394d7aaeed9acbe44 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 24 Oct 2019 15:00:52 +0530 Subject: [PATCH 07/25] arm: mach-k3: am6_init: Initialize AVS class 0 Initialize AVS class 0 so that mpu voltage rail is programmed to the AVS class 0 compensated value. Signed-off-by: Keerthy --- arch/arm/mach-k3/am6_init.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c index 0b564f7bd1..99edcd9a24 100644 --- a/arch/arm/mach-k3/am6_init.c +++ b/arch/arm/mach-k3/am6_init.c @@ -116,6 +116,13 @@ void board_init_f(ulong dummy) /* Perform EEPROM-based board detection */ do_board_detect(); +#if defined(CONFIG_CPU_V7R) && defined(CONFIG_K3_AVS0) + ret = uclass_get_device_by_driver(UCLASS_MISC, DM_GET_DRIVER(k3_avs), + &dev); + if (ret) + printf("AVS init failed: %d\n", ret); +#endif + #ifdef CONFIG_K3_AM654_DDRSS ret = uclass_get_device(UCLASS_RAM, 0, &dev); if (ret) From 7b134930888ffc07500026b752ce922a3fdcaf28 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 24 Oct 2019 15:00:53 +0530 Subject: [PATCH 08/25] arm: mach-k3: j721e_init: Initialize avs class 0 Initialize avs class 0 Signed-off-by: Keerthy --- arch/arm/mach-k3/j721e_init.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-k3/j721e_init.c b/arch/arm/mach-k3/j721e_init.c index 5e3813252b..d0bf86abeb 100644 --- a/arch/arm/mach-k3/j721e_init.c +++ b/arch/arm/mach-k3/j721e_init.c @@ -118,6 +118,13 @@ void board_init_f(ulong dummy) preloader_console_init(); #endif +#if defined(CONFIG_CPU_V7R) && defined(CONFIG_K3_AVS0) + ret = uclass_get_device_by_driver(UCLASS_MISC, DM_GET_DRIVER(k3_avs), + &dev); + if (ret) + printf("AVS init failed: %d\n", ret); +#endif + #if defined(CONFIG_K3_J721E_DDRSS) ret = uclass_get_device(UCLASS_RAM, 0, &dev); if (ret) From cfa6bd549c4f7045b756fbd76c75425166fc7366 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 24 Oct 2019 15:00:54 +0530 Subject: [PATCH 09/25] arm: dts: k3-am654-r5-base-board: Add VTM node Add VTM node for voltage and thermal management. For u-boot, this is needed for supporting AVS class 0, as the efuse values for the OPPs are stored under the VTM. Signed-off-by: Tero Kristo Signed-off-by: Keerthy --- arch/arm/dts/k3-am654-r5-base-board.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/dts/k3-am654-r5-base-board.dts b/arch/arm/dts/k3-am654-r5-base-board.dts index 174d202306..6ab0f4af10 100644 --- a/arch/arm/dts/k3-am654-r5-base-board.dts +++ b/arch/arm/dts/k3-am654-r5-base-board.dts @@ -97,6 +97,13 @@ u-boot,dm-spl; }; + wkup_vtm0: wkup_vtm@42050000 { + compatible = "ti,am654-vtm", "ti,am654-avs"; + reg = <0x42050000 0x25c>; + power-domains = <&k3_pds 80>; + #thermal-sensor-cells = <1>; + }; + clk_200mhz: dummy_clock { compatible = "fixed-clock"; #clock-cells = <0>; From 4bbb3849aa75bcaedca168d29ff57e20714ad04a Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 24 Oct 2019 15:00:55 +0530 Subject: [PATCH 10/25] arm: dts: k3-am654-r5-base-board: enable wkup_i2c0 driver for spl Enable wkup_i2c0 as this is needed for voltage control. Signed-off-by: Tero Kristo Signed-off-by: Keerthy --- arch/arm/dts/k3-am654-r5-base-board.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/dts/k3-am654-r5-base-board.dts b/arch/arm/dts/k3-am654-r5-base-board.dts index 6ab0f4af10..98868afd9c 100644 --- a/arch/arm/dts/k3-am654-r5-base-board.dts +++ b/arch/arm/dts/k3-am654-r5-base-board.dts @@ -218,4 +218,5 @@ pinctrl-names = "default"; pinctrl-0 = <&wkup_i2c0_pins_default>; clock-frequency = <400000>; + u-boot,dm-spl; }; From c5f73d1c9f62d1c704f0fe09ce0505591f6709e9 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 24 Oct 2019 15:00:56 +0530 Subject: [PATCH 11/25] arm: dts: k3-am654-r5-base-board: add supply rail for MPU MPU voltage on AM65x-evm is controlled via the TPS62363 chip attached to i2c0 bus. Add device node for this so that it can be controlled via a regulator driver. Signed-off-by: Tero Kristo Signed-off-by: Keerthy --- arch/arm/dts/k3-am654-r5-base-board.dts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/dts/k3-am654-r5-base-board.dts b/arch/arm/dts/k3-am654-r5-base-board.dts index 98868afd9c..baa3a2c9e7 100644 --- a/arch/arm/dts/k3-am654-r5-base-board.dts +++ b/arch/arm/dts/k3-am654-r5-base-board.dts @@ -219,4 +219,17 @@ pinctrl-0 = <&wkup_i2c0_pins_default>; clock-frequency = <400000>; u-boot,dm-spl; + + vdd_mpu: tps62363@60 { + compatible = "ti,tps62363"; + reg = <0x60>; + regulator-name = "VDD_MPU"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1770000>; + regulator-always-on; + regulator-boot-on; + ti,vsel0-state-high; + ti,vsel1-state-high; + u-boot,dm-spl; + }; }; From 56adc6615f32691fb745266cbfb7a06eea1a0935 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 24 Oct 2019 15:00:57 +0530 Subject: [PATCH 12/25] arm: dts: k3-am654-r5-base-board: enable wkup_vtm0 node and link in supplies Link the vdd-supplies for the voltage domains under the VTM node. Also, enable the node under SPL. This will enable the AVS class 0 support on am65x-evm board. Signed-off-by: Tero Kristo Signed-off-by: Keerthy --- arch/arm/dts/k3-am654-r5-base-board.dts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/dts/k3-am654-r5-base-board.dts b/arch/arm/dts/k3-am654-r5-base-board.dts index baa3a2c9e7..5c110ef9dd 100644 --- a/arch/arm/dts/k3-am654-r5-base-board.dts +++ b/arch/arm/dts/k3-am654-r5-base-board.dts @@ -138,6 +138,12 @@ power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>; }; +&wkup_vtm0 { + vdd-supply-3 = <&vdd_mpu>; + vdd-supply-4 = <&vdd_mpu>; + u-boot,dm-spl; +}; + &wkup_pmx0 { u-boot,dm-spl; wkup_uart0_pins_default: wkup_uart0_pins_default { From 69eceae8707e6df8f04a1012ea00f4c81d620cf0 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 24 Oct 2019 15:00:58 +0530 Subject: [PATCH 13/25] arm: dts: k3-j721e-r5-common-proc-board: Add VTM node Add VTM node for voltage and thermal management. For u-boot, this is needed for supporting AVS class 0, as the efuse values for the OPPs are stored under the VTM. Signed-off-by: Keerthy --- arch/arm/dts/k3-j721e-r5-common-proc-board.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts index 54d7998d27..e569809fcb 100644 --- a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts +++ b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts @@ -59,6 +59,13 @@ mboxes= <&mcu_secproxy 4>, <&mcu_secproxy 5>; mbox-names = "tx", "rx"; }; + + wkup_vtm0: wkup_vtm@42040000 { + compatible = "ti,am654-vtm", "ti,j721e-avs"; + reg = <0x0 0x42040000 0x0 0x330>; + power-domains = <&k3_pds 154 TI_SCI_PD_EXCLUSIVE>; + #thermal-sensor-cells = <1>; + }; }; &dmsc { From 0f63ceaf548ae311cf42c4692985ba4908862a22 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 24 Oct 2019 15:00:59 +0530 Subject: [PATCH 14/25] arm: dts: k3-j721e-r5-common: Add tps65941 node and dependent wkup_i2c0 node Add tps65941 node and dependent wkup_i2c0 node needed for AVS class 0 support Signed-off-by: Keerthy --- arch/arm/dts/k3-j721e-mcu-wakeup.dtsi | 11 +++++++ .../arm/dts/k3-j721e-r5-common-proc-board.dts | 32 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi b/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi index 92beeea34d..5dd07ac4da 100644 --- a/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi +++ b/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi @@ -57,6 +57,17 @@ clock-names = "fclk"; }; + wkup_i2c0: i2c@42120000 { + compatible = "ti,j721e-i2c", "ti,omap4-i2c"; + reg = <0x0 0x42120000 0x0 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "fck"; + clocks = <&k3_clks 197 0>; + power-domains = <&k3_pds 197 TI_SCI_PD_EXCLUSIVE>; + }; + mcu_uart0: serial@40a00000 { compatible = "ti,j721e-uart", "ti,am654-uart"; reg = <0x00 0x40a00000 0x00 0x100>; diff --git a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts index e569809fcb..165c38da4b 100644 --- a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts +++ b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts @@ -93,6 +93,13 @@ J721E_WKUP_IOPAD(0xe0, PIN_OUTPUT, 0) /* (G29) WKUP_GPIO0_12.MCU_UART0_TXD */ >; }; + + wkup_i2c0_pins_default: wkup-i2c0-pins-default { + pinctrl-single,pins = < + J721E_WKUP_IOPAD(0xf8, PIN_INPUT_PULLUP, 0) /* (J25) WKUP_I2C0_SCL */ + J721E_WKUP_IOPAD(0xfc, PIN_INPUT_PULLUP, 0) /* (H24) WKUP_I2C0_SDA */ + >; + }; }; &main_pmx0 { @@ -147,4 +154,29 @@ ti,driver-strength-ohm = <50>; }; +&wkup_i2c0 { + u-boot,dm-spl; + tps659413a: tps659413a@48 { + reg = <0x48>; + compatible = "ti,tps659413"; + u-boot,dm-spl; + pinctrl-names = "default"; + pinctrl-0 = <&wkup_i2c0_pins_default>; + clock-frequency = <400000>; + + regulators: regulators { + u-boot,dm-spl; + buck12_reg: buck12 { + /*VDD_MPU*/ + regulator-name = "buck12"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + regulator-boot-on; + u-boot,dm-spl; + }; + }; + }; +}; + #include "k3-j721e-common-proc-board-u-boot.dtsi" From 2f71498d52371341f5a3423f43d110a9be1123ae Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 24 Oct 2019 15:01:00 +0530 Subject: [PATCH 15/25] arm: dts: k3-j721e-r5-common-proc-board: Hook buck12_reg to vtm supply Hook buck12_reg to vtm avs supply Signed-off-by: Keerthy --- arch/arm/dts/k3-j721e-r5-common-proc-board.dts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts index 165c38da4b..41af48214f 100644 --- a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts +++ b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts @@ -179,4 +179,9 @@ }; }; +&wkup_vtm0 { + vdd-supply-2 = <&buck12_reg>; + u-boot,dm-spl; +}; + #include "k3-j721e-common-proc-board-u-boot.dtsi" From e41dd6c49959a0c82cd55e826cfe3102969803d8 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 24 Oct 2019 15:01:01 +0530 Subject: [PATCH 16/25] configs: am65x_evm_r5_defconfig: Enable TPS62363 regulator support TPS62363 is used to control the MPU_VDD voltage, so enable the driver for this. Signed-off-by: Tero Kristo Signed-off-by: Keerthy --- configs/am65x_evm_r5_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig index d0619e9b7a..a721b24ba4 100644 --- a/configs/am65x_evm_r5_defconfig +++ b/configs/am65x_evm_r5_defconfig @@ -84,6 +84,7 @@ CONFIG_DM_REGULATOR=y CONFIG_SPL_DM_REGULATOR=y CONFIG_DM_REGULATOR_GPIO=y CONFIG_SPL_DM_REGULATOR_GPIO=y +CONFIG_DM_REGULATOR_TPS62360=y CONFIG_RAM=y CONFIG_SPL_RAM=y CONFIG_K3_SYSTEM_CONTROLLER=y From b31e650867acfb016d1bfb8b895d7bd10cb5f1d1 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 24 Oct 2019 15:01:02 +0530 Subject: [PATCH 17/25] configs: am65x_evm_r5_defconfig: Enable AVS class 0 support Enable AVS class 0 support for the R5 SPL bootloader. Signed-off-by: Tero Kristo Signed-off-by: Keerthy --- configs/am65x_evm_r5_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig index a721b24ba4..4f122808de 100644 --- a/configs/am65x_evm_r5_defconfig +++ b/configs/am65x_evm_r5_defconfig @@ -99,3 +99,4 @@ CONFIG_TIMER=y CONFIG_SPL_TIMER=y CONFIG_OMAP_TIMER=y CONFIG_FS_FAT_MAX_CLUSTSIZE=16384 +CONFIG_K3_AVS0=y From 14dfca69d79e81a8b29324a86a819b1e642621ed Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 24 Oct 2019 15:01:03 +0530 Subject: [PATCH 18/25] configs: j721e_evm_r5_defconfig: Enable AVS Class 0 & dependent configs Enable AVS Class 0 & dependent config options. Signed-off-by: Keerthy --- configs/j721e_evm_r5_defconfig | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig index 30df739003..41d24ff9e5 100644 --- a/configs/j721e_evm_r5_defconfig +++ b/configs/j721e_evm_r5_defconfig @@ -59,10 +59,14 @@ CONFIG_CLK_TI_SCI=y CONFIG_TI_SCI_PROTOCOL=y CONFIG_DM_GPIO=y CONFIG_DA8XX_GPIO=y +CONFIG_DM_I2C=y +CONFIG_I2C_SET_DEFAULT_BUS_NUM=y +CONFIG_SYS_I2C_OMAP24XX=y CONFIG_DM_MAILBOX=y CONFIG_K3_SEC_PROXY=y CONFIG_MISC=y CONFIG_FS_LOADER=y +CONFIG_K3_AVS0=y CONFIG_DM_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_AM654=y @@ -75,6 +79,11 @@ CONFIG_SPL_PINCTRL=y CONFIG_PINCTRL_SINGLE=y CONFIG_POWER_DOMAIN=y CONFIG_TI_SCI_POWER_DOMAIN=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_TPS65941=y +CONFIG_DM_REGULATOR=y +CONFIG_SPL_DM_REGULATOR=y +CONFIG_DM_REGULATOR_TPS65941=y CONFIG_K3_SYSTEM_CONTROLLER=y CONFIG_REMOTEPROC_TI_K3_ARM64=y CONFIG_DM_RESET=y From 27b653449178e80b333e7bc5a81eed3bd1bd6861 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sun, 3 Nov 2019 16:18:27 -0600 Subject: [PATCH 19/25] ARM: omap3_logic: Power on MMC when setting up PMIC The PMIC enables power to the MMC card by default, but depending on the state it was left when restarted, it's possible the MMC may be powered down. This patch patch explicitly tells the twl4030 to power the MMC. Signed-off-by: Adam Ford --- board/logicpd/omap3som/omap3logic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/board/logicpd/omap3som/omap3logic.c b/board/logicpd/omap3som/omap3logic.c index ee77ce077c..43f049e592 100644 --- a/board/logicpd/omap3som/omap3logic.c +++ b/board/logicpd/omap3som/omap3logic.c @@ -141,6 +141,7 @@ void spl_board_prepare_for_linux(void) int misc_init_r(void) { twl4030_power_init(); + twl4030_power_mmc_init(0); omap_die_id_display(); return 0; } From 1e3d015a0344346cd8e4f0398c6b0a6d598ad41d Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sun, 3 Nov 2019 17:03:01 -0600 Subject: [PATCH 20/25] ARM: dts: logicpd-torpedo-37xx-devkit-u-boot: Remove unused GPIO The only GPIO bank needed in SPL is GPIO4 and the SPL space is tight. This patch removes the all but GPIO4 from the spl device tree to reduce the SPL footprint. Signed-off-by: Adam Ford --- .../logicpd-torpedo-37xx-devkit-u-boot.dtsi | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm/dts/logicpd-torpedo-37xx-devkit-u-boot.dtsi b/arch/arm/dts/logicpd-torpedo-37xx-devkit-u-boot.dtsi index 976330f897..76f74326ae 100644 --- a/arch/arm/dts/logicpd-torpedo-37xx-devkit-u-boot.dtsi +++ b/arch/arm/dts/logicpd-torpedo-37xx-devkit-u-boot.dtsi @@ -21,6 +21,26 @@ clock-frequency = <400000>; }; +&gpio1 { + /delete-property/ u-boot,dm-spl; +}; + +&gpio2 { + /delete-property/ u-boot,dm-spl; +}; + +&gpio3 { + /delete-property/ u-boot,dm-spl; +}; + +&gpio5 { + /delete-property/ u-boot,dm-spl; +}; + +&gpio6 { + /delete-property/ u-boot,dm-spl; +}; + /delete-node/ &uart2; /delete-node/ &uart3; /delete-node/ &mmc2; From 88279e1b0f106dc47f6e872f45960185b27bb946 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sun, 3 Nov 2019 17:03:02 -0600 Subject: [PATCH 21/25] Revert "ARM: omap3_logic/omap35_logic: Enable GPIO in SPL" The SPL is too tight, and it cannot start any longer. To help reduce the size of SPL, we need to remove some non-critical features. This reverts commit 66063a7c1388fb724e8671b03c529fb5cda992dd. Signed-off-by: Adam Ford --- configs/omap35_logic_defconfig | 1 + configs/omap3_logic_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/configs/omap35_logic_defconfig b/configs/omap35_logic_defconfig index 78fcbaaca2..3c9acd7e41 100644 --- a/configs/omap35_logic_defconfig +++ b/configs/omap35_logic_defconfig @@ -4,6 +4,7 @@ CONFIG_ARM=y CONFIG_ARCH_OMAP2PLUS=y CONFIG_SYS_TEXT_BASE=0x80100000 CONFIG_TI_COMMON_CMD_OPTIONS=y +# CONFIG_SPL_GPIO_SUPPORT is not set CONFIG_SYS_MALLOC_F_LEN=0x4000 CONFIG_TARGET_OMAP3_LOGIC=y # CONFIG_SPL_OMAP3_ID_NAND is not set diff --git a/configs/omap3_logic_defconfig b/configs/omap3_logic_defconfig index 81b57a8f7a..51547e7149 100644 --- a/configs/omap3_logic_defconfig +++ b/configs/omap3_logic_defconfig @@ -4,6 +4,7 @@ CONFIG_ARM=y CONFIG_ARCH_OMAP2PLUS=y CONFIG_SYS_TEXT_BASE=0x80100000 CONFIG_TI_COMMON_CMD_OPTIONS=y +# CONFIG_SPL_GPIO_SUPPORT is not set CONFIG_SYS_MALLOC_F_LEN=0x4000 CONFIG_TARGET_OMAP3_LOGIC=y # CONFIG_SPL_OMAP3_ID_NAND is not set From 899836c3155a5bacefa3e84057e08ad00dc9a143 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sun, 3 Nov 2019 17:15:52 -0600 Subject: [PATCH 22/25] ARM: dts: logicpd-som-lv-37xx-devkit-u-boot: Remove unused GPIO The only GPIO bank needed in SPL is GPIO4 and the SPL space is tight. This patch removes the all but GPIO4 from the spl device tree to reduce the SPL footprint. Signed-off-by: Adam Ford --- .../logicpd-som-lv-37xx-devkit-u-boot.dtsi | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm/dts/logicpd-som-lv-37xx-devkit-u-boot.dtsi b/arch/arm/dts/logicpd-som-lv-37xx-devkit-u-boot.dtsi index 1abd9a3887..e5d9e4f1b1 100644 --- a/arch/arm/dts/logicpd-som-lv-37xx-devkit-u-boot.dtsi +++ b/arch/arm/dts/logicpd-som-lv-37xx-devkit-u-boot.dtsi @@ -17,6 +17,26 @@ }; }; +&gpio1 { + /delete-property/ u-boot,dm-spl; +}; + +&gpio2 { + /delete-property/ u-boot,dm-spl; +}; + +&gpio3 { + /delete-property/ u-boot,dm-spl; +}; + +&gpio5 { + /delete-property/ u-boot,dm-spl; +}; + +&gpio6 { + /delete-property/ u-boot,dm-spl; +}; + &i2c1 { clock-frequency = <400000>; }; From 5d44207d1740af4639f6a5638dd08bb27652b047 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sun, 3 Nov 2019 17:15:53 -0600 Subject: [PATCH 23/25] configs: omap3_logic_somlv: Remove GPIO from SPL The SPL is too tight, and it cannot start any longer. To help reduce the size of SPL, we need to remove some non-critical features. This patch removes SPL_GPIO_SUPPORT to free up some operating space. Signed-off-by: Adam Ford --- configs/omap3_logic_somlv_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/omap3_logic_somlv_defconfig b/configs/omap3_logic_somlv_defconfig index 656a2d5cb1..cec5e7ef2e 100644 --- a/configs/omap3_logic_somlv_defconfig +++ b/configs/omap3_logic_somlv_defconfig @@ -4,6 +4,7 @@ CONFIG_ARM=y CONFIG_ARCH_OMAP2PLUS=y CONFIG_SYS_TEXT_BASE=0x80100000 CONFIG_TI_COMMON_CMD_OPTIONS=y +# CONFIG_SPL_GPIO_SUPPORT is not set CONFIG_SYS_MALLOC_F_LEN=0x4000 CONFIG_TARGET_OMAP3_LOGIC=y # CONFIG_SPL_OMAP3_ID_NAND is not set From 7e6668e8f0ea9694ec2a417a841bcb86462ceb7d Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Mon, 4 Nov 2019 17:05:24 -0600 Subject: [PATCH 24/25] Kconfig: ti: Make board detect EEPROM addresses depend BOARD_DETECT There is an option to enable the board detection for TI platforms. If this is option is not set, there is no reason to set the EEPROM bus address or chip address. This patch makes both EEPROM_BUS_ADDRESS and EEPROM_CHIP_ADDRESS depend on TI_I2C_BOARD_DETECT. Signed-off-by: Adam Ford --- board/ti/common/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/board/ti/common/Kconfig b/board/ti/common/Kconfig index b1956b8100..9ead7ca038 100644 --- a/board/ti/common/Kconfig +++ b/board/ti/common/Kconfig @@ -8,11 +8,13 @@ config EEPROM_BUS_ADDRESS int "Board EEPROM's I2C bus address" range 0 8 default 0 + depends on TI_I2C_BOARD_DETECT config EEPROM_CHIP_ADDRESS hex "Board EEPROM's I2C chip address" range 0 0xff default 0x50 + depends on TI_I2C_BOARD_DETECT config TI_COMMON_CMD_OPTIONS bool "Enable cmd options on TI platforms" From 72077fe160068d2e3d848ca5464d5cbef244eca0 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Thu, 7 Nov 2019 08:06:09 -0500 Subject: [PATCH 25/25] configs: j721e_evm_r5_defconfig: Remove SPL multi-DTB FIT support The SPL FIT will only have one DTB, so remove support for multi-DTB. This also removes an early access to EEPROM used to select the DTB that is not valid in SPL at the point at which it is accessed, that always returns false for GP devices and causes a firewall expection on HS. Signed-off-by: Andrew F. Davis Reviewed-by: Lokesh Vutla --- configs/j721e_evm_r5_defconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig index 41d24ff9e5..e5cda6800c 100644 --- a/configs/j721e_evm_r5_defconfig +++ b/configs/j721e_evm_r5_defconfig @@ -45,8 +45,6 @@ CONFIG_CMD_FAT=y CONFIG_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="k3-j721e-r5-common-proc-board" -CONFIG_SPL_MULTI_DTB_FIT=y -CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y CONFIG_DM=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y