diff options
author | Mulin Chao <mlchao@nuvoton.com> | 2019-08-06 19:34:27 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-08-12 23:53:53 +0000 |
commit | d09bc18d46c37070e3309b4f72a33d27134dea45 (patch) | |
tree | 90b23bd28e77e72905e76fbb4c43b289d800cfce /chip | |
parent | f21845b628b79c3ecbe460d900670757449225ab (diff) | |
download | chrome-ec-d09bc18d46c37070e3309b4f72a33d27134dea45.tar.gz |
npcx: i2c: adjust i2c bus frequency when it is set to 100kHz.
When npcx i2c module's bus frequency is set to 100KHz, it operates in
normal mode and its bus frequency, fSCL, follows the formula listed
below:
fSCL = fCLK / (4*SCLFRQ), ie. SCLFRQ = fCLK / (4*fSCL)
where fCLK is the source clock frequency of i2c module and SCLFRQ
defines the SCL output period in SMBCTL2/3 registers.
But integer division in this formula is equal to the floor of regular
division if it isn't divisible. So far, all i2c modules' source clock
frequency is 15MHz and if the desired i2c bus frequency is 100KHz, the
SCLFRQ will be:
SCLFRQ = fCLK/(4*fSCL) = 15MHz/(4*100kHz) = floor(37.5) = 37
And the actual i2c frequency is:
fSCL = fCLK/(4*SCLFRQ) = 15MHz/(4*37) = 101.35KHz
That's why we observe the i2c frequency is slightly higher than 100kHz.
To fix this issue, this CL replaces integer division with the ceiling value
of the formula to make sure bus frequency is lower than 100KHz and meet
i2c spec when it operates in normal mode.
BRANCH=none
BUG=b:138350407
TEST=No build errors for npcx series. Measure the actual i2c bus
which is configured to 100KHz after applying this CL. The actual
frequency is 98.7 KHz on npcx5/7 evbs.
Change-Id: I71e2c3090bc91c7b9945c01c04c9ac5ac656c893
Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1741566
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Reviewed-by: Jett Rink <jettrink@chromium.org>
Reviewed-by: Furquan Shaikh <furquan@chromium.org>
Commit-Queue: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/npcx/i2c.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/chip/npcx/i2c.c b/chip/npcx/i2c.c index 151f786fbf..f98697da7b 100644 --- a/chip/npcx/i2c.c +++ b/chip/npcx/i2c.c @@ -758,9 +758,9 @@ static void i2c_freq_changed(void) * Set SCL frequency by formula: * tSCL = 4 * SCLFRQ * tCLK * fSCL = fCLK / (4*SCLFRQ) - * SCLFRQ = fSCL/(4*fSCL) + * SCLFRQ = ceil(fCLK/(4*fSCL)) */ - scl_freq = (freq/1000) / (bus_freq*4); /* bus_freq is KHz */ + scl_freq = DIV_ROUND_UP(freq, bus_freq*4000); /* Unit in bps */ /* Normal mode if i2c freq is under 100kHz */ if (bus_freq <= 100) { |