summaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses
diff options
context:
space:
mode:
authorDoug Anderson <dianders@chromium.org>2014-12-18 12:44:07 -0500
committerWolfram Sang <wsa@the-dreams.de>2015-01-13 10:21:05 -0500
commit387f0de6c37380ad72bb92bb621f23555dd4c42e (patch)
tree6c93ae93a5c2309c9346607191fa09dc581df286 /drivers/i2c/busses
parent1330e29105a3ad0a2a88d7a37ddd29d3f70675cf (diff)
i2c: rk3x: Account for repeated start time requirement
On Rockchip I2C the controller drops SDA low slightly too soon to meet the "repeated start" requirements. >From my own experimentation over a number of rates: - controller appears to drop SDA at .875x (7/8) programmed clk high. - controller appears to keep SCL high for 2x programmed clk high. The first rule isn't enough to meet tSU;STA requirements in Standard-mode on the system I tested on. The second rule is probably enough to meet tHD;STA requirements in nearly all cases (especially after accounting for the first), but it doesn't hurt to account for it anyway just in case. Even though the repeated start requirement only need to be accounted for during a small part of the transfer, we'll adjust the timings for the whole transfer to meet it. I believe that adjusting the timings in just the right place to switch things up for repeated start would require several extra interrupts and that doesn't seem terribly worth it. With this change and worst case rise/fall times, I see 100kHz i2c going to ~85kHz. With slightly optimized rise/fall (800ns / 50ns) I see i2c going to ~89kHz. Fast-mode isn't affected much because tSU;STA is shorter relative to tHD;STA there. As part of this change we needed to account for the SDA falling time. The specification indicates that this should be the same, but we'll follow Designware's lead and add a binding. Note that we deviate from Designware and assign the default SDA falling time to be the same as the SCL falling time, which is incredibly likely. Signed-off-by: Doug Anderson <dianders@chromium.org> [wsa: rebased to i2c/for-next] Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r--drivers/i2c/busses/i2c-rk3x.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
index 36a922445814..5f96b1b3e3a5 100644
--- a/drivers/i2c/busses/i2c-rk3x.c
+++ b/drivers/i2c/busses/i2c-rk3x.c
@@ -102,8 +102,9 @@ struct rk3x_i2c {
102 102
103 /* Settings */ 103 /* Settings */
104 unsigned int scl_frequency; 104 unsigned int scl_frequency;
105 unsigned int rise_ns; 105 unsigned int scl_rise_ns;
106 unsigned int fall_ns; 106 unsigned int scl_fall_ns;
107 unsigned int sda_fall_ns;
107 108
108 /* Synchronization & notification */ 109 /* Synchronization & notification */
109 spinlock_t lock; 110 spinlock_t lock;
@@ -437,8 +438,9 @@ out:
437 * 438 *
438 * @clk_rate: I2C input clock rate 439 * @clk_rate: I2C input clock rate
439 * @scl_rate: Desired SCL rate 440 * @scl_rate: Desired SCL rate
440 * @rise_ns: How many ns it takes for signals to rise. 441 * @scl_rise_ns: How many ns it takes for SCL to rise.
441 * @fall_ns: How many ns it takes for signals to fall. 442 * @scl_fall_ns: How many ns it takes for SCL to fall.
443 * @sda_fall_ns: How many ns it takes for SDA to fall.
442 * @div_low: Divider output for low 444 * @div_low: Divider output for low
443 * @div_high: Divider output for high 445 * @div_high: Divider output for high
444 * 446 *
@@ -447,11 +449,13 @@ out:
447 * too high, we silently use the highest possible rate. 449 * too high, we silently use the highest possible rate.
448 */ 450 */
449static int rk3x_i2c_calc_divs(unsigned long clk_rate, unsigned long scl_rate, 451static int rk3x_i2c_calc_divs(unsigned long clk_rate, unsigned long scl_rate,
450 unsigned long rise_ns, unsigned long fall_ns, 452 unsigned long scl_rise_ns,
453 unsigned long scl_fall_ns,
454 unsigned long sda_fall_ns,
451 unsigned long *div_low, unsigned long *div_high) 455 unsigned long *div_low, unsigned long *div_high)
452{ 456{
453 unsigned long spec_min_low_ns, spec_min_high_ns; 457 unsigned long spec_min_low_ns, spec_min_high_ns;
454 unsigned long spec_max_data_hold_ns; 458 unsigned long spec_setup_start, spec_max_data_hold_ns;
455 unsigned long data_hold_buffer_ns; 459 unsigned long data_hold_buffer_ns;
456 460
457 unsigned long min_low_ns, min_high_ns; 461 unsigned long min_low_ns, min_high_ns;
@@ -490,18 +494,35 @@ static int rk3x_i2c_calc_divs(unsigned long clk_rate, unsigned long scl_rate,
490 if (scl_rate <= 100000) { 494 if (scl_rate <= 100000) {
491 /* Standard-mode */ 495 /* Standard-mode */
492 spec_min_low_ns = 4700; 496 spec_min_low_ns = 4700;
497 spec_setup_start = 4700;
493 spec_min_high_ns = 4000; 498 spec_min_high_ns = 4000;
494 spec_max_data_hold_ns = 3450; 499 spec_max_data_hold_ns = 3450;
495 data_hold_buffer_ns = 50; 500 data_hold_buffer_ns = 50;
496 } else { 501 } else {
497 /* Fast-mode */ 502 /* Fast-mode */
498 spec_min_low_ns = 1300; 503 spec_min_low_ns = 1300;
504 spec_setup_start = 600;
499 spec_min_high_ns = 600; 505 spec_min_high_ns = 600;
500 spec_max_data_hold_ns = 900; 506 spec_max_data_hold_ns = 900;
501 data_hold_buffer_ns = 50; 507 data_hold_buffer_ns = 50;
502 } 508 }
503 min_low_ns = spec_min_low_ns + fall_ns; 509 min_high_ns = scl_rise_ns + spec_min_high_ns;
504 min_high_ns = spec_min_high_ns + rise_ns; 510
511 /*
512 * Timings for repeated start:
513 * - controller appears to drop SDA at .875x (7/8) programmed clk high.
514 * - controller appears to keep SCL high for 2x programmed clk high.
515 *
516 * We need to account for those rules in picking our "high" time so
517 * we meet tSU;STA and tHD;STA times.
518 */
519 min_high_ns = max(min_high_ns,
520 DIV_ROUND_UP((scl_rise_ns + spec_setup_start) * 1000, 875));
521 min_high_ns = max(min_high_ns,
522 DIV_ROUND_UP((scl_rise_ns + spec_setup_start +
523 sda_fall_ns + spec_min_high_ns), 2));
524
525 min_low_ns = scl_fall_ns + spec_min_low_ns;
505 max_low_ns = spec_max_data_hold_ns * 2 - data_hold_buffer_ns; 526 max_low_ns = spec_max_data_hold_ns * 2 - data_hold_buffer_ns;
506 min_total_ns = min_low_ns + min_high_ns; 527 min_total_ns = min_low_ns + min_high_ns;
507 528
@@ -599,9 +620,9 @@ static void rk3x_i2c_adapt_div(struct rk3x_i2c *i2c, unsigned long clk_rate)
599 u64 t_low_ns, t_high_ns; 620 u64 t_low_ns, t_high_ns;
600 int ret; 621 int ret;
601 622
602 ret = rk3x_i2c_calc_divs(clk_rate, i2c->scl_frequency, i2c->rise_ns, 623 ret = rk3x_i2c_calc_divs(clk_rate, i2c->scl_frequency, i2c->scl_rise_ns,
603 i2c->fall_ns, &div_low, &div_high); 624 i2c->scl_fall_ns, i2c->sda_fall_ns,
604 625 &div_low, &div_high);
605 WARN_ONCE(ret != 0, "Could not reach SCL freq %u", i2c->scl_frequency); 626 WARN_ONCE(ret != 0, "Could not reach SCL freq %u", i2c->scl_frequency);
606 627
607 clk_enable(i2c->clk); 628 clk_enable(i2c->clk);
@@ -644,8 +665,9 @@ static int rk3x_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long
644 switch (event) { 665 switch (event) {
645 case PRE_RATE_CHANGE: 666 case PRE_RATE_CHANGE:
646 if (rk3x_i2c_calc_divs(ndata->new_rate, i2c->scl_frequency, 667 if (rk3x_i2c_calc_divs(ndata->new_rate, i2c->scl_frequency,
647 i2c->rise_ns, i2c->fall_ns, &div_low, 668 i2c->scl_rise_ns, i2c->scl_fall_ns,
648 &div_high) != 0) 669 i2c->sda_fall_ns,
670 &div_low, &div_high) != 0)
649 return NOTIFY_STOP; 671 return NOTIFY_STOP;
650 672
651 /* scale up */ 673 /* scale up */
@@ -875,15 +897,18 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
875 * the default maximum timing from the specification. 897 * the default maximum timing from the specification.
876 */ 898 */
877 if (of_property_read_u32(pdev->dev.of_node, "i2c-scl-rising-time-ns", 899 if (of_property_read_u32(pdev->dev.of_node, "i2c-scl-rising-time-ns",
878 &i2c->rise_ns)) { 900 &i2c->scl_rise_ns)) {
879 if (i2c->scl_frequency <= 100000) 901 if (i2c->scl_frequency <= 100000)
880 i2c->rise_ns = 1000; 902 i2c->scl_rise_ns = 1000;
881 else 903 else
882 i2c->rise_ns = 300; 904 i2c->scl_rise_ns = 300;
883 } 905 }
884 if (of_property_read_u32(pdev->dev.of_node, "i2c-scl-falling-time-ns", 906 if (of_property_read_u32(pdev->dev.of_node, "i2c-scl-falling-time-ns",
885 &i2c->fall_ns)) 907 &i2c->scl_fall_ns))
886 i2c->fall_ns = 300; 908 i2c->scl_fall_ns = 300;
909 if (of_property_read_u32(pdev->dev.of_node, "i2c-sda-falling-time-ns",
910 &i2c->scl_fall_ns))
911 i2c->sda_fall_ns = i2c->scl_fall_ns;
887 912
888 strlcpy(i2c->adap.name, "rk3x-i2c", sizeof(i2c->adap.name)); 913 strlcpy(i2c->adap.name, "rk3x-i2c", sizeof(i2c->adap.name));
889 i2c->adap.owner = THIS_MODULE; 914 i2c->adap.owner = THIS_MODULE;