aboutsummaryrefslogtreecommitdiff
path: root/src/soc/rockchip/rk3288/i2c.c
diff options
context:
space:
mode:
authorhuang lin <hl@rock-chips.com>2014-09-27 12:02:27 +0800
committerAaron Durbin <adurbin@google.com>2015-04-02 21:16:28 +0200
commitbbcffd9e25e12a8ee5858ac580aa7e86ecf32ee5 (patch)
tree71643c01f781877ae677f424dbfb6023f521e4d7 /src/soc/rockchip/rk3288/i2c.c
parent1fd5a9b36d8b817614ef7f0c301291da0cdb7466 (diff)
rockchip: support i2c clock setting
BUG=None TEST=Boot Veyron Pinky and measure i2c clock frequency Original-Change-Id: I04d9fa75a05280885f083a828f78cf55811ca97d Original-Signed-off-by: huang lin <hl@rock-chips.com> Original-Reviewed-on: https://chromium-review.googlesource.com/219660 Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Original-Commit-Queue: Julius Werner <jwerner@chromium.org> Change-Id: Ie7ac3f2d0d76a4d3347bd469bf7af3295cc454fd (cherry picked from commit 4b9b3c2f8b7c6cd189cb8f239508431ee08ebc52) Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/9241 Reviewed-by: Patrick Georgi <pgeorgi@google.com> Tested-by: build bot (Jenkins)
Diffstat (limited to 'src/soc/rockchip/rk3288/i2c.c')
-rw-r--r--src/soc/rockchip/rk3288/i2c.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/soc/rockchip/rk3288/i2c.c b/src/soc/rockchip/rk3288/i2c.c
index 9348b6cf89..142ec4a489 100644
--- a/src/soc/rockchip/rk3288/i2c.c
+++ b/src/soc/rockchip/rk3288/i2c.c
@@ -30,6 +30,9 @@
#include "addressmap.h"
#include "grf.h"
#include "soc.h"
+#include "i2c.h"
+#include "clock.h"
+
#define RETRY_COUNT 3
/* 100000us = 100ms */
#define I2C_TIMEOUT_US 100000
@@ -275,3 +278,39 @@ int platform_i2c_transfer(unsigned bus, struct i2c_seg *segments, int seg_count)
}
return res;
}
+
+void i2c_init(unsigned int bus, unsigned int hz)
+{
+ unsigned int clk_div;
+ unsigned int divl;
+ unsigned int divh;
+ unsigned int i2c_src_clk;
+ struct rk3288_i2c_regs *regs = i2c_bus[bus];
+
+ /*i2c0,i2c2 src clk from pd_bus_pclk
+ other i2c src clk from peri_pclk
+ */
+ switch (bus) {
+ case 0:
+ case 2:
+ i2c_src_clk = PD_BUS_PCLK_HZ;
+ break;
+ case 1:
+ case 3:
+ case 4:
+ case 5:
+ i2c_src_clk = PERI_PCLK_HZ;
+ break;
+ default:
+ break;
+ }
+
+ /*SCL Divisor = 8*(CLKDIVL + 1 + CLKDIVH + 1)
+ SCL = PCLK/ SCLK Divisor
+ */
+ clk_div = div_round_up(i2c_src_clk, hz * 8) - 2;
+ divh = clk_div / 2;
+ divl = ALIGN_UP(clk_div, 2) / 2;
+ assert((divh < 65536) && (divl < 65536));
+ writel((divh << 16) | (divl << 0), &regs->i2c_clkdiv);
+}