Browse Source

Merge branch 'agust@denx.de' of git://git.denx.de/u-boot-staging

Tom Rini 6 years ago
parent
commit
cca7429ddd

+ 9 - 0
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

+ 1 - 0
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/

+ 7 - 0
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;

+ 40 - 7
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)

+ 8 - 1
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 },
 	{ }
 };
 

+ 1 - 1
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

+ 3 - 0
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 {

+ 29 - 0
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

+ 2 - 0
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));