diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2013-11-28 17:11:45 -0500 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2014-01-09 17:02:37 -0500 |
commit | 977303979d68b323470dd92c2d4f7e95dedaea2b (patch) | |
tree | 77af7891991e63c448f691822164e505ef03d89c /drivers/i2c | |
parent | 4868ca387debaf5c19061a18624956233886ab01 (diff) |
i2c: nomadik: auto-calculate slave setup time
The Nomadik I2C controller needs to have the slave set-up time
configured based off the clock used to drive the I2C bus block.
Currently this is done with static assignments assuming that the
block is clocked 48MHz which is pretty likely to be bug-prone.
Calculate the SLSU from the equation given in the datasheet
instead.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-nomadik.c | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 8bf9ac01301a..51e61d8127cb 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c | |||
@@ -340,6 +340,8 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev) | |||
340 | { | 340 | { |
341 | u32 brcr1, brcr2; | 341 | u32 brcr1, brcr2; |
342 | u32 i2c_clk, div; | 342 | u32 i2c_clk, div; |
343 | u32 ns; | ||
344 | u16 slsu; | ||
343 | 345 | ||
344 | writel(0x0, dev->virtbase + I2C_CR); | 346 | writel(0x0, dev->virtbase + I2C_CR); |
345 | writel(0x0, dev->virtbase + I2C_HSMCR); | 347 | writel(0x0, dev->virtbase + I2C_HSMCR); |
@@ -347,18 +349,38 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev) | |||
347 | writel(0x0, dev->virtbase + I2C_RFTR); | 349 | writel(0x0, dev->virtbase + I2C_RFTR); |
348 | writel(0x0, dev->virtbase + I2C_DMAR); | 350 | writel(0x0, dev->virtbase + I2C_DMAR); |
349 | 351 | ||
352 | i2c_clk = clk_get_rate(dev->clk); | ||
353 | |||
350 | /* | 354 | /* |
351 | * set the slsu: | 355 | * set the slsu: |
352 | * | 356 | * |
353 | * slsu defines the data setup time after SCL clock | 357 | * slsu defines the data setup time after SCL clock |
354 | * stretching in terms of i2c clk cycles. The | 358 | * stretching in terms of i2c clk cycles + 1 (zero means |
355 | * needed setup time for the three modes are 250ns, | 359 | * "wait one cycle"), the needed setup time for the three |
356 | * 100ns, 10ns respectively thus leading to the values | 360 | * modes are 250ns, 100ns, 10ns respectively. |
357 | * of 14, 6, 2 for a 48 MHz i2c clk. | 361 | * |
362 | * As the time for one cycle T in nanoseconds is | ||
363 | * T = (1/f) * 1000000000 => | ||
364 | * slsu = cycles / (1000000000 / f) + 1 | ||
358 | */ | 365 | */ |
359 | writel(dev->cfg.slsu << 16, dev->virtbase + I2C_SCR); | 366 | ns = DIV_ROUND_UP_ULL(1000000000ULL, i2c_clk); |
367 | switch (dev->cfg.sm) { | ||
368 | case I2C_FREQ_MODE_FAST: | ||
369 | case I2C_FREQ_MODE_FAST_PLUS: | ||
370 | slsu = DIV_ROUND_UP(100, ns); /* Fast */ | ||
371 | break; | ||
372 | case I2C_FREQ_MODE_HIGH_SPEED: | ||
373 | slsu = DIV_ROUND_UP(10, ns); /* High */ | ||
374 | break; | ||
375 | case I2C_FREQ_MODE_STANDARD: | ||
376 | default: | ||
377 | slsu = DIV_ROUND_UP(250, ns); /* Standard */ | ||
378 | break; | ||
379 | } | ||
380 | slsu += 1; | ||
360 | 381 | ||
361 | i2c_clk = clk_get_rate(dev->clk); | 382 | dev_dbg(&dev->adev->dev, "calculated SLSU = %04x\n", slsu); |
383 | writel(slsu << 16, dev->virtbase + I2C_SCR); | ||
362 | 384 | ||
363 | /* | 385 | /* |
364 | * The spec says, in case of std. mode the divider is | 386 | * The spec says, in case of std. mode the divider is |
@@ -915,11 +937,6 @@ static const struct i2c_algorithm nmk_i2c_algo = { | |||
915 | }; | 937 | }; |
916 | 938 | ||
917 | static struct nmk_i2c_controller u8500_i2c = { | 939 | static struct nmk_i2c_controller u8500_i2c = { |
918 | /* | ||
919 | * Slave data setup time; 250ns, 100ns, and 10ns, which | ||
920 | * is 14, 6 and 2 respectively for a 48Mhz i2c clock. | ||
921 | */ | ||
922 | .slsu = 0xe, | ||
923 | .tft = 1, /* Tx FIFO threshold */ | 940 | .tft = 1, /* Tx FIFO threshold */ |
924 | .rft = 8, /* Rx FIFO threshold */ | 941 | .rft = 8, /* Rx FIFO threshold */ |
925 | .clk_freq = 400000, /* fast mode operation */ | 942 | .clk_freq = 400000, /* fast mode operation */ |
@@ -1027,7 +1044,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) | |||
1027 | 1044 | ||
1028 | /* fetch the controller configuration from machine */ | 1045 | /* fetch the controller configuration from machine */ |
1029 | dev->cfg.clk_freq = pdata->clk_freq; | 1046 | dev->cfg.clk_freq = pdata->clk_freq; |
1030 | dev->cfg.slsu = pdata->slsu; | ||
1031 | dev->cfg.tft = pdata->tft; | 1047 | dev->cfg.tft = pdata->tft; |
1032 | dev->cfg.rft = pdata->rft; | 1048 | dev->cfg.rft = pdata->rft; |
1033 | dev->cfg.sm = pdata->sm; | 1049 | dev->cfg.sm = pdata->sm; |