
In order to make I2C work on rk3066 and rk3188 boards GFR must be updated.
Signed-off-by: Alexander Kochetkov al.kochet@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, + }, { } };