Unable to use 1MHz or 3.4MHz in i2c0 with linaro kernel 4.4

96boards

#1

My intention is to run I2C0 with 3.4MHz.
@guodong can you please help me on this ?

Unable to use 1MHz or 3.4MHz in i2c0 with linaro kernel 4.4.
Kernel rejects the entries. We tried to bypass the check inside the i2c core driver but still we were seeing the default 400KHz freq in CRO.


Hikey960 i2c0/7 problem
#2

High speed mode does not seem to be enabled in 4.4, could you upgrade to kernel 4.9?

b6e67145f14903ca430e011db3b771d8de4c3d8a
i2c: designware: Enable high speed mode


#3

I tried 4.9 as it is with just dtsi file changes where I set clock-frequency = <1000000>; of i2c0 to 1MHz and 3.4MHz, It didn’t work in both the case and in CRO it was showing 400KHz. I’m debugging the i2c-designware-core.c whether the high speed-mode is getting set during init. Let me know if any other param/config entries to updated to enable the high speed-mode


#4

Ok It might be due to this issue: https://bugs.96boards.org/show_bug.cgi?id=578
Which has been fixed by this patch: https://github.com/96boards-hikey/tools-images-hikey960/commit/92f365073cd812a8d8ca159b01f52dd6dd06d111

So you should try to update your xloader and lpm partitions with the following procedure:

Note that this patch introduces a regression with ARM-TF/UEFI and is going to be reverted.


#5

Cool. I will try this first thing tomorrow. Looks like I don’t have authorisation to read the bug description from the bugzilla, can you just brief me on what it’s about and what regression it introduces as I’m planning to use the setup for some long-runs and stability scenarios. Thank you so much in advance.


#6

Yes this mainly fix an issue with SPI2 and I2C0 speed reported here:

Seems that i2c/spi fix introduces a regression with the ARM-ATF/UEFI bootloader, this shouldn’t be a problem for you since you don’t use this bootloader.

$ git clone https://github.com/96boards-hikey/tools-images-hikey960.git
$ cd tools-images-hikey960
$ git reset --hard 92f3650
$ ./recovery-flash.sh


#7

Flashed the above images as you mentioned and tried with 3.4Mz but still not good enough looks like, CRO still reads at 400KHz.


#8

Is anyone able run i2c0 at 3.4MHz, has it been tested?
My boss and other stake holders are behind me to make this interface work, urgent attention required.
If no option left, I will have to write a software i2c.
Any other recommendations or suggestions are welcome.


#9

OK You have applied the patched bootloader with SPI/i2C fix + changed the device-tree + kernel 4.9, correct ?
What appends if you reduce the frequency, does it still running at 400KHz?
What kind of I2C driver are you running, kernel or userspace one ?
I will try to reproduce this tomorrow.


#10

OK You have applied the patched bootloader with SPI/i2C fix + changed the device-tree + kernel 4.9, correct ?
Yes, completely.

What appends if you reduce the frequency, does it still running at 400KHz?
Yes. I tried setting it to 1 and 3.4 MHz.
I’ll try 1MHz one more time after applying the bootloader patch but with 3.4MHz, it’s the same result.

What kind of I2C driver are you running, kernel or userspace one ?
Kernel I2C.

Thanks a lot!


#11

@arjuntj, I’m able to reproduce the issue, I’m going to try to determine if it’s a kernel or firmware issue.


#12

I had a quick look at the current driver, and it seems that something is missing to fully manage fast-mode+(1MHz) and high-speed(3.4MHz), not sure why it’s incomplete. I’m going to try a clean patch.

For debug purpose, could you please try to apply the following kernel diff an retry with k4.9 + 3.4MHz:
in dw_i2c_plat_probe function (drivers/i2c/busses/i2c-designware-platdrv.c):

+     dev->hs_hcnt = 5;
+     dev->hs_lcnt = 7;
r = i2c_dw_probe(dev);
if (r)
            goto exit_probe;
            return r;

#13

when I applied the above patch, system booted up but got stuck in the initialisation.
It didn’t go to recovery mode but even the adb did not get initialised.


#14

This is weird because that works on my side (system boots). Be sure to rebuild the dt and flash both boot.img and dt.img following these steps (use make instead of make bootimage to be sure).


#15

I tried building everything allover but same result. The moment I comment out those 2 line change, it boots up properly.

Just to understand, change in i2c-designware-platdrv.c would require device tree image to be built ?


#16

Correction. It booted up. There was one hard-coding(debug code trace) of clock-freq in /i2c-designware-platdrv.c which I missed to reset. I will connect CRO and let you know the result very soon.


#17

@Loic With your patch (+3.4MHz set) following are my observations:

  1. Initial clock cycles were at 400KHz
  2. Then proceeded by consistent clock cycles at 1.2MHz

#18

Ok, thanks this is better. Basically these variables are used to define the number of clock cycles the i2c phy needs to wait at high and low level. Knowing that in our case i2c0 ic clock is 32mhz. But some rising and falling delays need to be to be considered as well.

So you may have to play with these values, you can try to reduce them to (1,1) but I’m not sure about the result. Seems you are the first one to try at high-speed.


#19

Thanks @Loic for all the help.
Tried (1,1) but the result is almost the same, max freq it hit is 1.3MHz.
Do you expect some patch/update for the issue soon on kernel 4.9/4.4?
3.4 MHz is the goal :wink:


#20

Don’t expect patch for now, I assume this is mainly an hw/oscillator limitation.
However, from the kernel, i2c7 (LS connector i2c1) is reported with a 106Mhz clock (vs 32Mhz for i2c0).
I suggest you to try with i2c1 (keeping the change in kernel).