aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini2018-08-07 07:15:11 -0400
committerTom Rini2018-08-07 07:15:11 -0400
commitcca7429ddd24d0cccc72f708a6f05c6ab9a75303 (patch)
tree2176a8a80050fe9839e2ef39e82ef6dc57ff68e8
parentbb694d4e898b1368ba96e01481dc0a79c491e77c (diff)
parent3d7690aec1020aa579eee189ed07d5e6289e3617 (diff)
Merge branch 'agust@denx.de' of git://git.denx.de/u-boot-staging
-rw-r--r--common/spl/Kconfig9
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/core/device.c7
-rw-r--r--drivers/i2c/imx_lpi2c.c47
-rw-r--r--drivers/i2c/muxes/pca954x.c9
-rw-r--r--drivers/power/domain/Makefile2
-rw-r--r--include/imx_lpi2c.h3
-rw-r--r--include/power-domain.h29
-rw-r--r--test/dm/power-domain.c2
9 files changed, 100 insertions, 9 deletions
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 0be8ff0d87d..0ad1e049a92 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -609,6 +609,15 @@ config SPL_POWER_SUPPORT
in drivers/power, drivers/power/pmic and drivers/power/regulator
as part of an SPL build.
+config SPL_POWER_DOMAIN
+ bool "Support power domain drivers"
+ help
+ Enable support for power domain control in SPL. Many SoCs allow
+ power to be applied to or removed from portions of the SoC (power
+ domains). This may be used to save power. This API provides the
+ means to control such power management hardware. This enables
+ the drivers in drivers/power/domain as part of a SPL build.
+
config SPL_RAM_SUPPORT
bool "Support booting from RAM"
default y if MICROBLAZE || ARCH_SOCFPGA || TEGRA || ARCH_ZYNQ
diff --git a/drivers/Makefile b/drivers/Makefile
index 276e5ee4d7e..d53208540ea 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_ARMADA_XP) += ddr/marvell/axp/
obj-$(CONFIG_ALTERA_SDRAM) += ddr/altera/
obj-$(CONFIG_SPL_POWER_SUPPORT) += power/ power/pmic/
obj-$(CONFIG_SPL_POWER_SUPPORT) += power/regulator/
+obj-$(CONFIG_SPL_POWER_DOMAIN) += power/domain/
obj-$(CONFIG_SPL_DM_RESET) += reset/
obj-$(CONFIG_SPL_MTD_SUPPORT) += mtd/
obj-$(CONFIG_SPL_ONENAND_SUPPORT) += mtd/onenand/
diff --git a/drivers/core/device.c b/drivers/core/device.c
index d5f5fc31b03..207d566b71d 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -26,6 +26,7 @@
#include <dm/util.h>
#include <linux/err.h>
#include <linux/list.h>
+#include <power-domain.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -304,6 +305,7 @@ static void *alloc_priv(int size, uint flags)
int device_probe(struct udevice *dev)
{
+ struct power_domain pd;
const struct driver *drv;
int size = 0;
int ret;
@@ -383,6 +385,11 @@ int device_probe(struct udevice *dev)
if (dev->parent && device_get_uclass_id(dev) != UCLASS_PINCTRL)
pinctrl_select_state(dev, "default");
+ if (dev->parent && device_get_uclass_id(dev) != UCLASS_POWER_DOMAIN) {
+ if (!power_domain_get(dev, &pd))
+ power_domain_on(&pd);
+ }
+
ret = uclass_pre_probe_device(dev);
if (ret)
goto fail;
diff --git a/drivers/i2c/imx_lpi2c.c b/drivers/i2c/imx_lpi2c.c
index ff07ca34aac..6c343072fb2 100644
--- a/drivers/i2c/imx_lpi2c.c
+++ b/drivers/i2c/imx_lpi2c.c
@@ -261,8 +261,14 @@ static int bus_i2c_write(struct udevice *bus, u32 chip, u8 *buf, int len)
}
+u32 __weak imx_get_i2cclk(u32 i2c_num)
+{
+ return 0;
+}
+
static int bus_i2c_set_bus_speed(struct udevice *bus, int speed)
{
+ struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus);
struct imx_lpi2c_reg *regs;
u32 val;
u32 preescale = 0, best_pre = 0, clkhi = 0;
@@ -273,9 +279,18 @@ static int bus_i2c_set_bus_speed(struct udevice *bus, int speed)
int i;
regs = (struct imx_lpi2c_reg *)devfdt_get_addr(bus);
- clock_rate = imx_get_i2cclk(bus->seq);
- if (!clock_rate)
- return -EPERM;
+
+ if (IS_ENABLED(CONFIG_CLK)) {
+ clock_rate = clk_get_rate(&i2c_bus->per_clk);
+ if (clock_rate <= 0) {
+ dev_err(bus, "Failed to get i2c clk: %d\n", clock_rate);
+ return clock_rate;
+ }
+ } else {
+ clock_rate = imx_get_i2cclk(bus->seq);
+ if (!clock_rate)
+ return -EPERM;
+ }
mode = (readl(&regs->mcr) & LPI2C_MCR_MEN_MASK) >> LPI2C_MCR_MEN_SHIFT;
/* disable master mode */
@@ -417,6 +432,11 @@ static int imx_lpi2c_set_bus_speed(struct udevice *bus, unsigned int speed)
return bus_i2c_set_bus_speed(bus, speed);
}
+__weak int enable_i2c_clk(unsigned char enable, unsigned int i2c_num)
+{
+ return 0;
+}
+
static int imx_lpi2c_probe(struct udevice *bus)
{
struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus);
@@ -440,10 +460,23 @@ static int imx_lpi2c_probe(struct udevice *bus)
return ret;
}
- /* To i.MX7ULP, only i2c4-7 can be handled by A7 core */
- ret = enable_i2c_clk(1, bus->seq);
- if (ret < 0)
- return ret;
+ if (IS_ENABLED(CONFIG_CLK)) {
+ ret = clk_get_by_name(bus, "per", &i2c_bus->per_clk);
+ if (ret) {
+ dev_err(bus, "Failed to get per clk\n");
+ return ret;
+ }
+ ret = clk_enable(&i2c_bus->per_clk);
+ if (ret) {
+ dev_err(bus, "Failed to enable per clk\n");
+ return ret;
+ }
+ } else {
+ /* To i.MX7ULP, only i2c4-7 can be handled by A7 core */
+ ret = enable_i2c_clk(1, bus->seq);
+ if (ret < 0)
+ return ret;
+ }
ret = bus_i2c_init(bus, 100000);
if (ret < 0)
diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c
index 4debc039572..ab8b4000afb 100644
--- a/drivers/i2c/muxes/pca954x.c
+++ b/drivers/i2c/muxes/pca954x.c
@@ -17,7 +17,8 @@ DECLARE_GLOBAL_DATA_PTR;
enum pca_type {
PCA9544,
PCA9547,
- PCA9548
+ PCA9548,
+ PCA9646
};
struct chip_desc {
@@ -51,6 +52,11 @@ static const struct chip_desc chips[] = {
.muxtype = pca954x_isswi,
.width = 8,
},
+ [PCA9646] = {
+ .enable = 0x0,
+ .muxtype = pca954x_isswi,
+ .width = 4,
+ },
};
static int pca954x_deselect(struct udevice *mux, struct udevice *bus,
@@ -86,6 +92,7 @@ static const struct udevice_id pca954x_ids[] = {
{ .compatible = "nxp,pca9544", .data = PCA9544 },
{ .compatible = "nxp,pca9547", .data = PCA9547 },
{ .compatible = "nxp,pca9548", .data = PCA9548 },
+ { .compatible = "nxp,pca9646", .data = PCA9646 },
{ }
};
diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile
index c7d76444020..020eee23782 100644
--- a/drivers/power/domain/Makefile
+++ b/drivers/power/domain/Makefile
@@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_POWER_DOMAIN) += power-domain-uclass.o
+obj-$(CONFIG_$(SPL_)POWER_DOMAIN) += power-domain-uclass.o
obj-$(CONFIG_BCM6328_POWER_DOMAIN) += bcm6328-power-domain.o
obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain.o
obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o
diff --git a/include/imx_lpi2c.h b/include/imx_lpi2c.h
index 3fbb40bdd1a..2700e5f8763 100644
--- a/include/imx_lpi2c.h
+++ b/include/imx_lpi2c.h
@@ -8,6 +8,8 @@
#ifndef __IMX_LPI2C_H__
#define __IMX_LPI2C_H__
+#include <clk.h>
+
struct imx_lpi2c_bus {
int index;
ulong base;
@@ -15,6 +17,7 @@ struct imx_lpi2c_bus {
int speed;
struct i2c_pads_info *pads_info;
struct udevice *bus;
+ struct clk per_clk;
};
struct imx_lpi2c_reg {
diff --git a/include/power-domain.h b/include/power-domain.h
index aba8c0f65c4..a558fbbdb21 100644
--- a/include/power-domain.h
+++ b/include/power-domain.h
@@ -87,7 +87,15 @@ struct power_domain {
* @power_domain A pointer to a power domain struct to initialize.
* @return 0 if OK, or a negative error code.
*/
+#if CONFIG_IS_ENABLED(POWER_DOMAIN)
int power_domain_get(struct udevice *dev, struct power_domain *power_domain);
+#else
+static inline
+int power_domain_get(struct udevice *dev, struct power_domain *power_domain)
+{
+ return -ENOSYS;
+}
+#endif
/**
* power_domain_free - Free a previously requested power domain.
@@ -96,7 +104,14 @@ int power_domain_get(struct udevice *dev, struct power_domain *power_domain);
* requested by power_domain_get().
* @return 0 if OK, or a negative error code.
*/
+#if CONFIG_IS_ENABLED(POWER_DOMAIN)
int power_domain_free(struct power_domain *power_domain);
+#else
+static inline int power_domain_free(struct power_domain *power_domain)
+{
+ return -ENOSYS;
+}
+#endif
/**
* power_domain_on - Enable power to a power domain.
@@ -105,7 +120,14 @@ int power_domain_free(struct power_domain *power_domain);
* requested by power_domain_get().
* @return 0 if OK, or a negative error code.
*/
+#if CONFIG_IS_ENABLED(POWER_DOMAIN)
int power_domain_on(struct power_domain *power_domain);
+#else
+static inline int power_domain_on(struct power_domain *power_domain)
+{
+ return -ENOSYS;
+}
+#endif
/**
* power_domain_off - Disable power ot a power domain.
@@ -114,6 +136,13 @@ int power_domain_on(struct power_domain *power_domain);
* requested by power_domain_get().
* @return 0 if OK, or a negative error code.
*/
+#if CONFIG_IS_ENABLED(POWER_DOMAIN)
int power_domain_off(struct power_domain *power_domain);
+#else
+static inline int power_domain_off(struct power_domain *power_domain)
+{
+ return -ENOSYS;
+}
+#endif
#endif
diff --git a/test/dm/power-domain.c b/test/dm/power-domain.c
index a1e1df2bb21..48318218a9e 100644
--- a/test/dm/power-domain.c
+++ b/test/dm/power-domain.c
@@ -26,6 +26,8 @@ static int dm_test_power_domain(struct unit_test_state *uts)
ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "power-domain-test",
&dev_test));
+ ut_asserteq(1, sandbox_power_domain_query(dev_power_domain,
+ TEST_POWER_DOMAIN));
ut_assertok(sandbox_power_domain_test_get(dev_test));
ut_assertok(sandbox_power_domain_test_on(dev_test));