[U-Boot] [PATCH] rockchip: i2c: enable I2C inside GRF for rk3066 and rk3188

Alexander Kochetkov al.kochet at gmail.com
Tue Feb 20 08:43:23 UTC 2018


In order to make I2C work on rk3066 and rk3188 boards GFR
must be updated.

Signed-off-by: Alexander Kochetkov <al.kochet at gmail.com>
---
 drivers/i2c/rk_i2c.c |   85 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 80 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c
index 332280c..3ec5474 100644
--- a/drivers/i2c/rk_i2c.c
+++ b/drivers/i2c/rk_i2c.c
@@ -12,6 +12,7 @@
 #include <dm.h>
 #include <errno.h>
 #include <i2c.h>
+#include <syscon.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/i2c.h>
@@ -34,6 +35,13 @@ struct rk_i2c {
 	unsigned int speed;
 };
 
+/**
+ * @grf_offset: offset inside the grf regmap for setting the i2c type
+ */
+struct rk_i2c_soc_data {
+	int grf_offset;
+};
+
 static inline void rk_i2c_get_div(int div, int *divh, int *divl)
 {
 	*divl = div / 2;
@@ -381,9 +389,37 @@ static int rockchip_i2c_ofdata_to_platdata(struct udevice *bus)
 static int rockchip_i2c_probe(struct udevice *bus)
 {
 	struct rk_i2c *priv = dev_get_priv(bus);
+	struct rk_i2c_soc_data *soc_data;
+	uint32_t value;
+	int bus_nr;
+	void *grf;
+	int ret;
 
 	priv->regs = dev_read_addr_ptr(bus);
 
+	soc_data = (struct rk_i2c_soc_data*)dev_get_driver_data(bus);
+
+	if (soc_data->grf_offset >= 0) {
+		grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+		if (IS_ERR(grf)) {
+			ret = PTR_ERR(grf);
+			debug("%s: Could not get syscon for %s: %d\n",
+			 __func__, bus->name, ret);
+			return ret;
+		}
+
+		ret = dev_read_alias_seq(bus, &bus_nr);
+		if (ret < 0) {
+			debug("%s: Could not get alias for %s: %d\n",
+			 __func__, bus->name, ret);
+			return ret;
+		}
+
+		/* 27+i: write mask, 11+i: value */
+		value = BIT(27 + bus_nr) | BIT(11 + bus_nr);
+		writel(value, grf + soc_data->grf_offset);
+	}
+
 	return 0;
 }
 
@@ -392,12 +428,51 @@ static const struct dm_i2c_ops rockchip_i2c_ops = {
 	.set_bus_speed	= rockchip_i2c_set_bus_speed,
 };
 
+static const struct rk_i2c_soc_data rk3066_soc_data = {
+	.grf_offset = 0x154,
+};
+
+static const struct rk_i2c_soc_data rk3188_soc_data = {
+	.grf_offset = 0x0a4,
+};
+
+static const struct rk_i2c_soc_data rk3228_soc_data = {
+	.grf_offset = -1,
+};
+
+static const struct rk_i2c_soc_data rk3288_soc_data = {
+	.grf_offset = -1,
+};
+
+static const struct rk_i2c_soc_data rk3328_soc_data = {
+	.grf_offset = -1,
+};
+
+static const struct rk_i2c_soc_data rk3399_soc_data = {
+	.grf_offset = -1,
+};
+
 static const struct udevice_id rockchip_i2c_ids[] = {
-	{ .compatible = "rockchip,rk3066-i2c" },
-	{ .compatible = "rockchip,rk3188-i2c" },
-	{ .compatible = "rockchip,rk3288-i2c" },
-	{ .compatible = "rockchip,rk3328-i2c" },
-	{ .compatible = "rockchip,rk3399-i2c" },
+	{
+		.compatible = "rockchip,rk3066-i2c",
+		.data = (ulong)&rk3066_soc_data,
+	},
+	{
+		.compatible = "rockchip,rk3188-i2c",
+		.data = (ulong)&rk3188_soc_data,
+	},
+	{
+		.compatible = "rockchip,rk3288-i2c",
+		.data = (ulong)&rk3288_soc_data,
+	},
+	{
+		.compatible = "rockchip,rk3328-i2c",
+		.data = (ulong)&rk3328_soc_data,
+	},
+	{
+		.compatible = "rockchip,rk3399-i2c",
+		.data = (ulong)&rk3399_soc_data,
+	},
 	{ }
 };
 
-- 
1.7.9.5



More information about the U-Boot mailing list