Patchwork i2c: mxs: fix broken timing calculation

login
register
mail settings
Submitter Lothar Waßmann
Date July 5, 2013, 4:28 p.m.
Message ID <1373041680-26939-1-git-send-email-LW@KARO-electronics.de>
Download mbox | patch
Permalink /patch/257195/
State Accepted
Headers show

Comments

Lothar Waßmann - July 5, 2013, 4:28 p.m.
The timing calculation is rather bogus and gives extremely wrong
results for higher frequencies (on an i.MX28). E.g. instead of 400 kHz
I measured 770 kHz.

Implement a calculation that adheres to the I2C spec and gives exact
results for I2C frequencies from 12.56 kHz to 960 kHz.

Also the bus_free and leadin parameters are programmed according to
the I2C spec for standard and fast mode.

This was tested on a Ka-Ro TX28 module with a DS1339, TSC2007, PCA9554
and SGTL5000 client.

Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
 drivers/i2c/busses/i2c-mxs.c |   87 ++++++++++++++++++++++++++++++-----------
 1 files changed, 63 insertions(+), 24 deletions(-)
Marek Vasut - July 5, 2013, 4:53 p.m.
Hi Lothar,

> The timing calculation is rather bogus and gives extremely wrong
> results for higher frequencies (on an i.MX28). E.g. instead of 400 kHz
> I measured 770 kHz.
> 
> Implement a calculation that adheres to the I2C spec and gives exact
> results for I2C frequencies from 12.56 kHz to 960 kHz.
> 
> Also the bus_free and leadin parameters are programmed according to
> the I2C spec for standard and fast mode.

I suspect the resulting speed is heavily dependent on hardware properties of the 
bus. Did you have a chance to check it with a scope? I will try to recheck on 
other boards next week.

Best regards,
Marek Vasut
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Lothar Waßmann - July 5, 2013, 5:28 p.m.
Hi,

Marek Vasut writes:
> Hi Lothar,
> 
> > The timing calculation is rather bogus and gives extremely wrong
> > results for higher frequencies (on an i.MX28). E.g. instead of 400 kHz
> > I measured 770 kHz.
> > 
> > Implement a calculation that adheres to the I2C spec and gives exact
> > results for I2C frequencies from 12.56 kHz to 960 kHz.
> > 
> > Also the bus_free and leadin parameters are programmed according to
> > the I2C spec for standard and fast mode.
> 
> I suspect the resulting speed is heavily dependent on hardware properties of the 
> bus. Did you have a chance to check it with a scope? I will try to recheck on 
> other boards next week.
> 
Of course I did! I found the DS1339 RTC not working on our hardware
with the I2C clock frequency set to 400kHz and then checked the bus
timing. I found the SCL frequency to be 770kHz instead of 400kHz and
113kHz instead of 100kHz.
On what hardware did you do your measurements?

The fancy constants -2 and -7 in the calculation were derived from
measuring the clock low and high time with low_count and high_count
set to 1 and measuring the actual timing of the signal.
The clock frequeny in this setup is 2.18 MHz corresponding to 11 clock
cycles of the 24MHz clock. The LOW time was about 140ns and the HIGH
time 318ns corresponding to 3 and 8 (instead of 1) clock cycles.

These constants could be different for different SoCs (i.MX23).
But I don't have any hardware to verify that.

Maybe some guru from Freescale can comment on this and perhaps
document the relationship between the register contents and the actual
timing.



Lothar Waßmann
Marek Vasut - July 5, 2013, 5:37 p.m.
Dear Lothar Waßmann,

> Hi,
> 
> Marek Vasut writes:
> > Hi Lothar,
> > 
> > > The timing calculation is rather bogus and gives extremely wrong
> > > results for higher frequencies (on an i.MX28). E.g. instead of 400 kHz
> > > I measured 770 kHz.
> > > 
> > > Implement a calculation that adheres to the I2C spec and gives exact
> > > results for I2C frequencies from 12.56 kHz to 960 kHz.
> > > 
> > > Also the bus_free and leadin parameters are programmed according to
> > > the I2C spec for standard and fast mode.
> > 
> > I suspect the resulting speed is heavily dependent on hardware properties
> > of the bus. Did you have a chance to check it with a scope? I will try
> > to recheck on other boards next week.
> 
> Of course I did! I found the DS1339 RTC not working on our hardware
> with the I2C clock frequency set to 400kHz and then checked the bus
> timing. I found the SCL frequency to be 770kHz instead of 400kHz and
> 113kHz instead of 100kHz.
> On what hardware did you do your measurements?

MX28EVK and M28EVK.

> The fancy constants -2 and -7 in the calculation were derived from
> measuring the clock low and high time with low_count and high_count
> set to 1 and measuring the actual timing of the signal.
> The clock frequeny in this setup is 2.18 MHz corresponding to 11 clock
> cycles of the 24MHz clock. The LOW time was about 140ns and the HIGH
> time 318ns corresponding to 3 and 8 (instead of 1) clock cycles.
> 
> These constants could be different for different SoCs (i.MX23).
> But I don't have any hardware to verify that.

I can check it for you on MX23 next week, I have two boards with that chip with 
well accessible I2C. I am not in the office now, so this will have to wait until 
next week.

btw offtopic, I will at least try to fix the PIO in the meantime.

> Maybe some guru from Freescale can comment on this and perhaps
> document the relationship between the register contents and the actual
> timing.

Ok, you're taking a third stab at getting FSL to explain how to configure 
arbitrary clock speeds on the MXS I2C. Good luck ;-D

Best regards,
Marek Vasut
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Lothar Waßmann - July 15, 2013, 10:22 a.m.
Hi Mark,

Marek Vasut writes:
> Dear Lothar Waßmann,
> 
> > Hi,
> > 
> > Marek Vasut writes:
> > > Hi Lothar,
> > > 
> > > > The timing calculation is rather bogus and gives extremely wrong
> > > > results for higher frequencies (on an i.MX28). E.g. instead of 400 kHz
> > > > I measured 770 kHz.
> > > > 
> > > > Implement a calculation that adheres to the I2C spec and gives exact
> > > > results for I2C frequencies from 12.56 kHz to 960 kHz.
> > > > 
> > > > Also the bus_free and leadin parameters are programmed according to
> > > > the I2C spec for standard and fast mode.
> > > 
> > > I suspect the resulting speed is heavily dependent on hardware properties
> > > of the bus. Did you have a chance to check it with a scope? I will try
> > > to recheck on other boards next week.
> > 
> > Of course I did! I found the DS1339 RTC not working on our hardware
> > with the I2C clock frequency set to 400kHz and then checked the bus
> > timing. I found the SCL frequency to be 770kHz instead of 400kHz and
> > 113kHz instead of 100kHz.
> > On what hardware did you do your measurements?
> 
> MX28EVK and M28EVK.
> 
> > The fancy constants -2 and -7 in the calculation were derived from
> > measuring the clock low and high time with low_count and high_count
> > set to 1 and measuring the actual timing of the signal.
> > The clock frequeny in this setup is 2.18 MHz corresponding to 11 clock
> > cycles of the 24MHz clock. The LOW time was about 140ns and the HIGH
> > time 318ns corresponding to 3 and 8 (instead of 1) clock cycles.
> > 
> > These constants could be different for different SoCs (i.MX23).
> > But I don't have any hardware to verify that.
> 
> I can check it for you on MX23 next week, I have two boards with that chip with 
> well accessible I2C. I am not in the office now, so this will have to wait until 
> next week.
> 
Did you have time to look into this? And also recheck the timing on
the i.MX28? Because there obviously is a fundamental discrepancy
between your and my measurements.

> btw offtopic, I will at least try to fix the PIO in the meantime.
> 
Did you succeed at this? Because this is the real problem for the
DS1339 failing on our board. With DMA only transfers it works, but
other chips (TSC2007, PCA9554, SGTL5000) fail.

I also tried to get the PIO transfers working but didn't have any
success. Interestingly all the chips mentioned above worked flawlessly
with the 3.3 kernel. That should exclude any HW deficiencies of our
modules or the I2C interface of the i.MX28 in general.

What disturbs me most is the sequence of accessing the I2C DATA
register and clearing the DMAREQ bit. Normally you should clear the
DMAREQ _before_ accessing the DATA reg, because the access will
trigger a new assertion of DMAREQ. Thus clearing that bit _after_
the access (like suggested in the i.MX28 Ref Manual and currently
implemented in the driver) is racy and potentially leads to
inadvertently clearing a fresh DMAREQ condition.

But handling it 'the right way' in the driver doesn't improve
anything.


Lothar Waßmann
Marek Vasut - July 15, 2013, 12:24 p.m.
Hi Lothar,

> Hi Mark,
> 
> Marek Vasut writes:
> > Dear Lothar Waßmann,
> > 
> > > Hi,
> > > 
> > > Marek Vasut writes:
> > > > Hi Lothar,
> > > > 
> > > > > The timing calculation is rather bogus and gives extremely wrong
> > > > > results for higher frequencies (on an i.MX28). E.g. instead of 400
> > > > > kHz I measured 770 kHz.
> > > > > 
> > > > > Implement a calculation that adheres to the I2C spec and gives
> > > > > exact results for I2C frequencies from 12.56 kHz to 960 kHz.
> > > > > 
> > > > > Also the bus_free and leadin parameters are programmed according to
> > > > > the I2C spec for standard and fast mode.
> > > > 
> > > > I suspect the resulting speed is heavily dependent on hardware
> > > > properties of the bus. Did you have a chance to check it with a
> > > > scope? I will try to recheck on other boards next week.
> > > 
> > > Of course I did! I found the DS1339 RTC not working on our hardware
> > > with the I2C clock frequency set to 400kHz and then checked the bus
> > > timing. I found the SCL frequency to be 770kHz instead of 400kHz and
> > > 113kHz instead of 100kHz.
> > > On what hardware did you do your measurements?
> > 
> > MX28EVK and M28EVK.
> > 
> > > The fancy constants -2 and -7 in the calculation were derived from
> > > measuring the clock low and high time with low_count and high_count
> > > set to 1 and measuring the actual timing of the signal.
> > > The clock frequeny in this setup is 2.18 MHz corresponding to 11 clock
> > > cycles of the 24MHz clock. The LOW time was about 140ns and the HIGH
> > > time 318ns corresponding to 3 and 8 (instead of 1) clock cycles.
> > > 
> > > These constants could be different for different SoCs (i.MX23).
> > > But I don't have any hardware to verify that.
> > 
> > I can check it for you on MX23 next week, I have two boards with that
> > chip with well accessible I2C. I am not in the office now, so this will
> > have to wait until next week.
> 
> Did you have time to look into this? And also recheck the timing on
> the i.MX28? Because there obviously is a fundamental discrepancy
> between your and my measurements.

I did not, sorry. I am catching a train to Prague only today, my vacation took a 
tag longer.

> > btw offtopic, I will at least try to fix the PIO in the meantime.
> 
> Did you succeed at this? Because this is the real problem for the
> DS1339 failing on our board. With DMA only transfers it works, but
> other chips (TSC2007, PCA9554, SGTL5000) fail.

Is that correct to assume that even DMA fails? So far I got to a patch [1], 
which is almost an RFC, but please give it a go. I suspect I didn't CC you, I 
will CC you on V2.

> I also tried to get the PIO transfers working but didn't have any
> success. Interestingly all the chips mentioned above worked flawlessly
> with the 3.3 kernel. That should exclude any HW deficiencies of our
> modules or the I2C interface of the i.MX28 in general.

At that time, the i2c used the PIOQUEUE mode, but that is not compatible with 
MX23. Think of it like this:

        PIO    PIOQUEUE  DMA
MX23  broken      N/A    OK
MX28    OK        OK     OK

So MX23 is really a poor device :(

> What disturbs me most is the sequence of accessing the I2C DATA
> register and clearing the DMAREQ bit. Normally you should clear the
> DMAREQ _before_ accessing the DATA reg, because the access will
> trigger a new assertion of DMAREQ.

Fully agreed. I spent _days_ on the patch [1] to fully understand the hardware 
and fix all the fine details of this operation. I also tried to document it in 
the code for future adventurers who dare to enter this insanity. The DMAREQ bit 
is nonsense it seems.

> Thus clearing that bit _after_
> the access (like suggested in the i.MX28 Ref Manual and currently
> implemented in the driver) is racy and potentially leads to
> inadvertently clearing a fresh DMAREQ condition.

Yes, indeed.

> But handling it 'the right way' in the driver doesn't improve
> anything.
> 
> 
> Lothar Waßmann

[1] http://permalink.gmane.org/gmane.linux.drivers.i2c/15787

Best regards,
Marek Vasut
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Lothar Waßmann - July 16, 2013, 8:10 a.m.
Hi,

Marek Vasut writes:
> > > btw offtopic, I will at least try to fix the PIO in the meantime.
> > 
> > Did you succeed at this? Because this is the real problem for the
> > DS1339 failing on our board. With DMA only transfers it works, but
> > other chips (TSC2007, PCA9554, SGTL5000) fail.
> 
> Is that correct to assume that even DMA fails? So far I got to a patch [1], 
> which is almost an RFC, but please give it a go. I suspect I didn't CC you, I 
> will CC you on V2.
> 
I applied that patch and all the above mentioned devices seem to work
with it.
And with my patch the timing is also correct.


Lothar Waßmann
Marek Vasut - July 17, 2013, 5:54 p.m.
Dear Lothar Waßmann,

> Hi,
> 
> Marek Vasut writes:
> > > > btw offtopic, I will at least try to fix the PIO in the meantime.
> > > 
> > > Did you succeed at this? Because this is the real problem for the
> > > DS1339 failing on our board. With DMA only transfers it works, but
> > > other chips (TSC2007, PCA9554, SGTL5000) fail.
> > 
> > Is that correct to assume that even DMA fails? So far I got to a patch
> > [1], which is almost an RFC, but please give it a go. I suspect I didn't
> > CC you, I will CC you on V2.
> 
> I applied that patch and all the above mentioned devices seem to work
> with it.
> And with my patch the timing is also correct.

First, please accept my appology for the delay. I finally measured the bus. 
Without this patch, I see 107khz at 100kHz setting and 410kHz at 400kHz setting. 
With this patch I see 93kHz and 307kHz respectively.

I suspect the result really is board-dependent. Can you measure MX28EVK so we 
know what the result is there please? I don't have one here. 

Best regards,
Marek Vasut
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Lothar Waßmann - July 18, 2013, 11:18 a.m.
Hi,

> > Marek Vasut writes:
> > > > > btw offtopic, I will at least try to fix the PIO in the meantime.
> > > > 
> > > > Did you succeed at this? Because this is the real problem for the
> > > > DS1339 failing on our board. With DMA only transfers it works, but
> > > > other chips (TSC2007, PCA9554, SGTL5000) fail.
> > > 
> > > Is that correct to assume that even DMA fails? So far I got to a patch
> > > [1], which is almost an RFC, but please give it a go. I suspect I didn't
> > > CC you, I will CC you on V2.
> > 
> > I applied that patch and all the above mentioned devices seem to work
> > with it.
> > And with my patch the timing is also correct.
> 
> First, please accept my appology for the delay. I finally measured the bus. 
> Without this patch, I see 107khz at 100kHz setting and 410kHz at 400kHz setting. 
> With this patch I see 93kHz and 307kHz respectively.
> 
> I suspect the result really is board-dependent. Can you measure MX28EVK so we 
> know what the result is there please? I don't have one here. 
> 
No, I don't have an EVK. Obviously the base clock from which the I2C
clock is derived must be different from 24MHz on your board.

Can you measure the high and low width of the SCL signal when setting
the HIGH_COUNT and LOW_COUNT to 1 and 10 (0x0a) successively?

I'm getting a LOW pulse with of:
130ns, 520ns
and a HIGH pulse width of:
330ns, 730ns

Thus the granularity of the timing setting is about 40ns which is
close the period of the 24MHz clock of 41.666ns that the SCL timing
generation is based on.


Lothar Waßmann
Wolfram Sang - Aug. 15, 2013, 10:12 a.m.
On Thu, Jul 18, 2013 at 01:18:48PM +0200, Lothar Waßmann wrote:
> Hi,
> 
> > > Marek Vasut writes:
> > > > > > btw offtopic, I will at least try to fix the PIO in the meantime.
> > > > > 
> > > > > Did you succeed at this? Because this is the real problem for the
> > > > > DS1339 failing on our board. With DMA only transfers it works, but
> > > > > other chips (TSC2007, PCA9554, SGTL5000) fail.
> > > > 
> > > > Is that correct to assume that even DMA fails? So far I got to a patch
> > > > [1], which is almost an RFC, but please give it a go. I suspect I didn't
> > > > CC you, I will CC you on V2.
> > > 
> > > I applied that patch and all the above mentioned devices seem to work
> > > with it.
> > > And with my patch the timing is also correct.
> > 
> > First, please accept my appology for the delay. I finally measured the bus. 
> > Without this patch, I see 107khz at 100kHz setting and 410kHz at 400kHz setting. 
> > With this patch I see 93kHz and 307kHz respectively.
> > 
> > I suspect the result really is board-dependent. Can you measure MX28EVK so we 
> > know what the result is there please? I don't have one here. 
> > 
> No, I don't have an EVK. Obviously the base clock from which the I2C
> clock is derived must be different from 24MHz on your board.
> 
> Can you measure the high and low width of the SCL signal when setting
> the HIGH_COUNT and LOW_COUNT to 1 and 10 (0x0a) successively?
> 
> I'm getting a LOW pulse with of:
> 130ns, 520ns
> and a HIGH pulse width of:
> 330ns, 730ns
> 
> Thus the granularity of the timing setting is about 40ns which is
> close the period of the 24MHz clock of 41.666ns that the SCL timing
> generation is based on.

Ping, waiting for updates. Marek, any time for this?

Haven't checked in detail if it is a similar issue, yet the designware
people had some in-depth discussions about I2C timings and PCB
influences...
Wolfram Sang - Aug. 15, 2013, 10:13 a.m.
> Haven't checked in detail if it is a similar issue, yet the designware
> people had some in-depth discussions about I2C timings and PCB
> influences...

the discussion is here:

http://thread.gmane.org/gmane.linux.drivers.i2c/15785
Marek Vasut - Aug. 15, 2013, 9:30 p.m.
Dear Wolfram Sang,

> On Thu, Jul 18, 2013 at 01:18:48PM +0200, Lothar Waßmann wrote:
> > Hi,
> > 
> > > > Marek Vasut writes:
> > > > > > > btw offtopic, I will at least try to fix the PIO in the
> > > > > > > meantime.
> > > > > > 
> > > > > > Did you succeed at this? Because this is the real problem for the
> > > > > > DS1339 failing on our board. With DMA only transfers it works,
> > > > > > but other chips (TSC2007, PCA9554, SGTL5000) fail.
> > > > > 
> > > > > Is that correct to assume that even DMA fails? So far I got to a
> > > > > patch [1], which is almost an RFC, but please give it a go. I
> > > > > suspect I didn't CC you, I will CC you on V2.
> > > > 
> > > > I applied that patch and all the above mentioned devices seem to work
> > > > with it.
> > > > And with my patch the timing is also correct.
> > > 
> > > First, please accept my appology for the delay. I finally measured the
> > > bus. Without this patch, I see 107khz at 100kHz setting and 410kHz at
> > > 400kHz setting. With this patch I see 93kHz and 307kHz respectively.
> > > 
> > > I suspect the result really is board-dependent. Can you measure MX28EVK
> > > so we know what the result is there please? I don't have one here.
> > 
> > No, I don't have an EVK. Obviously the base clock from which the I2C
> > clock is derived must be different from 24MHz on your board.
> > 
> > Can you measure the high and low width of the SCL signal when setting
> > the HIGH_COUNT and LOW_COUNT to 1 and 10 (0x0a) successively?
> > 
> > I'm getting a LOW pulse with of:
> > 130ns, 520ns
> > and a HIGH pulse width of:
> > 330ns, 730ns
> > 
> > Thus the granularity of the timing setting is about 40ns which is
> > close the period of the 24MHz clock of 41.666ns that the SCL timing
> > generation is based on.
> 
> Ping, waiting for updates. Marek, any time for this?

I talked to Lothar OTR for a little, since the files with measurements were big. 
I think we can apply these as after this patch, the result on both M28EVK and 
MX23EVK is reasonably good.

Please add my Acked-by: Marek Vasut <marex@denx.de> and apply.

> Haven't checked in detail if it is a similar issue, yet the designware
> people had some in-depth discussions about I2C timings and PCB
> influences...

Yes, that's what I am a little worried as the results of my measurements 
slightly differ on both boards. Maybe we should mull over this stuff a little 
longer, thanks for bringing this up. On the other hand, the results seems close 
enough to not cause trouble.

Best regards,
Marek Vasut
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Wolfram Sang - Aug. 16, 2013, 4:10 p.m.
On Fri, Jul 05, 2013 at 06:28:00PM +0200, Lothar Waßmann wrote:
> The timing calculation is rather bogus and gives extremely wrong
> results for higher frequencies (on an i.MX28). E.g. instead of 400 kHz
> I measured 770 kHz.
> 
> Implement a calculation that adheres to the I2C spec and gives exact
> results for I2C frequencies from 12.56 kHz to 960 kHz.
> 
> Also the bus_free and leadin parameters are programmed according to
> the I2C spec for standard and fast mode.
> 
> This was tested on a Ka-Ro TX28 module with a DS1339, TSC2007, PCA9554
> and SGTL5000 client.
> 
> Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>

Applied to for-next, thanks! Please mention stuff like the whitespace
fix in the changelog, too.

Patch

diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index df8ff5a..1333456 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -114,9 +114,10 @@  struct mxs_i2c_dev {
 
 	uint32_t timing0;
 	uint32_t timing1;
+	uint32_t timing2;
 
 	/* DMA support components */
-	struct dma_chan         	*dmach;
+	struct dma_chan			*dmach;
 	uint32_t			pio_data[2];
 	uint32_t			addr_data;
 	struct scatterlist		sg_io[2];
@@ -136,7 +137,7 @@  static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)
 	 */
 	writel(i2c->timing0, i2c->regs + MXS_I2C_TIMING0);
 	writel(i2c->timing1, i2c->regs + MXS_I2C_TIMING1);
-	writel(0x00300030, i2c->regs + MXS_I2C_TIMING2);
+	writel(i2c->timing2, i2c->regs + MXS_I2C_TIMING2);
 
 	writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
 }
@@ -577,41 +578,79 @@  static const struct i2c_algorithm mxs_i2c_algo = {
 	.functionality = mxs_i2c_func,
 };
 
-static void mxs_i2c_derive_timing(struct mxs_i2c_dev *i2c, int speed)
+static void mxs_i2c_derive_timing(struct mxs_i2c_dev *i2c, uint32_t speed)
 {
-	/* The I2C block clock run at 24MHz */
+	/* The I2C block clock runs at 24MHz */
 	const uint32_t clk = 24000000;
-	uint32_t base;
+	uint32_t divider;
 	uint16_t high_count, low_count, rcv_count, xmit_count;
+	uint32_t bus_free, leadin;
 	struct device *dev = i2c->dev;
 
-	if (speed > 540000) {
-		dev_warn(dev, "Speed too high (%d Hz), using 540 kHz\n", speed);
-		speed = 540000;
-	} else if (speed < 12000) {
-		dev_warn(dev, "Speed too low (%d Hz), using 12 kHz\n", speed);
-		speed = 12000;
+	divider = DIV_ROUND_UP(clk, speed);
+
+	if (divider < 25) {
+		/*
+		 * limit the divider, so that min(low_count, high_count)
+		 * is >= 1
+		 */
+		divider = 25;
+		dev_warn(dev,
+			"Speed too high (%u.%03u kHz), using %u.%03u kHz\n",
+			speed / 1000, speed % 1000,
+			clk / divider / 1000, clk / divider % 1000);
+	} else if (divider > 1897) {
+		/*
+		 * limit the divider, so that max(low_count, high_count)
+		 * cannot exceed 1023
+		 */
+		divider = 1897;
+		dev_warn(dev,
+			"Speed too low (%u.%03u kHz), using %u.%03u kHz\n",
+			speed / 1000, speed % 1000,
+			clk / divider / 1000, clk / divider % 1000);
 	}
 
 	/*
-	 * The timing derivation algorithm. There is no documentation for this
-	 * algorithm available, it was derived by using the scope and fiddling
-	 * with constants until the result observed on the scope was good enough
-	 * for 20kHz, 50kHz, 100kHz, 200kHz, 300kHz and 400kHz. It should be
-	 * possible to assume the algorithm works for other frequencies as well.
+	 * The I2C spec specifies the following timing data:
+	 *                          standard mode  fast mode Bitfield name
+	 * tLOW (SCL LOW period)     4700 ns        1300 ns
+	 * tHIGH (SCL HIGH period)   4000 ns         600 ns
+	 * tSU;DAT (data setup time)  250 ns         100 ns
+	 * tHD;STA (START hold time) 4000 ns         600 ns
+	 * tBUF (bus free time)      4700 ns        1300 ns
 	 *
-	 * Note it was necessary to cap the frequency on both ends as it's not
-	 * possible to configure completely arbitrary frequency for the I2C bus
-	 * clock.
+	 * The hardware (of the i.MX28 at least) seems to add 2 additional
+	 * clock cycles to the low_count and 7 cycles to the high_count.
+	 * This is compensated for by subtracting the respective constants
+	 * from the values written to the timing registers.
 	 */
-	base = ((clk / speed) - 38) / 2;
-	high_count = base + 3;
-	low_count = base - 3;
-	rcv_count = (high_count * 3) / 4;
-	xmit_count = low_count / 4;
+	if (speed > 100000) {
+		/* fast mode */
+		low_count = DIV_ROUND_CLOSEST(divider * 13, (13 + 6));
+		high_count = DIV_ROUND_CLOSEST(divider * 6, (13 + 6));
+		leadin = DIV_ROUND_UP(600 * (clk / 1000000), 1000);
+		bus_free = DIV_ROUND_UP(1300 * (clk / 1000000), 1000);
+	} else {
+		/* normal mode */
+		low_count = DIV_ROUND_CLOSEST(divider * 47, (47 + 40));
+		high_count = DIV_ROUND_CLOSEST(divider * 40, (47 + 40));
+		leadin = DIV_ROUND_UP(4700 * (clk / 1000000), 1000);
+		bus_free = DIV_ROUND_UP(4700 * (clk / 1000000), 1000);
+	}
+	rcv_count = high_count * 3 / 8;
+	xmit_count = low_count * 3 / 8;
+
+	dev_dbg(dev,
+		"speed=%u(actual %u) divider=%u low=%u high=%u xmit=%u rcv=%u leadin=%u bus_free=%u\n",
+		speed, clk / divider, divider, low_count, high_count,
+		xmit_count, rcv_count, leadin, bus_free);
 
+	low_count -= 2;
+	high_count -= 7;
 	i2c->timing0 = (high_count << 16) | rcv_count;
 	i2c->timing1 = (low_count << 16) | xmit_count;
+	i2c->timing2 = (bus_free << 16 | leadin);
 }
 
 static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)