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

@Loic Just to give an update. I tried with i2c7(LS connector i2c1) with 3.4MHz set and the observation is:

  1. Initial clock cycles for each set of clock were at 400KHz
  2. Remaining clock cycles(for each set) at ~3.7MHz(rarely saw some 1.5MHz clocks too)
    Since it happens for each set, not getting the desired output.

Is it worth a shot to try it on HS connector i2c lines ? or will it be using the same HW channel ? what’s yout thought.
In-parallel, am trying for bit-banging.

The I2C specification requires that a high-speed mode device must be ‘activated’ to operate in high-speed (3.4Mbit/s). This is performed by sending a special master code (00001XXX) following the start bit at lower speed mode (e.g. 400Kbps).

Spec says:
Data transfer continues in Hs-mode after the next repeated START (Sr), and only switches back to F/S-mode after a STOP condition. To reduce the overhead of the master code, it is possible that a master links a number of Hs-mode transfers, separated by repeated START conditions.

So your observation sounds normal to me, however the controller should ‘links’ your transfers in a same session (Repeated START) when sending/receiving several bytes.

Could you firstly try to configure hcnt and lcnt to meet 3.4MHz, this is theoretically the maximum speed.

spec also says that Hs-mode master devices generate a serial clock signal with a HIGH to LOW ratio of
1 to 2. So your hcnt should be ~2*lcnt.

Don’t think you will hae more chance on HS connector, I suggested you I2C7 because of the 100MHz oscillator (vs 32MHz for others).

1 Like

@Loic I’m able to consistently run it on 3.4MHz by adjusting hcnt and lcnt.
Thanks!
Wanted to know which gpio/i2c lines(with pull-up for SCL & SDA) I can choose in HiKey960 to use for bit-banging(software i2c). For this I’ll start a new thread.

1 Like

Great, could you share the values, I would like to rework the driver to support fast-speed/high-speed out of the box.

hcnt = 2
lcnt = 1
Works good for 3.4MHz

2 Likes

@Loic With the exact setup, when I change the freq. from 3.4MHz to 1MHz, CRO outputs still 400KHz. Any other registry update do we have to do ? Unable to get the register information doc.

Hi @arjuntj,

Since Hikey960 uses designware i2c IP, you can find the datasheet from synopsys site [1].

But that requires some privileges I guess.

Thanks,
Mani

[1] https://www.synopsys.com/dw/doc.php/iip/DW_apb_i2c/latest/doc/DW_apb_i2c_databook.pdf

2 Likes

@arjuntj, the driver lacks the ability to automatically configure i2c Fast-Speed-plus (1MhZ) as well. So in the same way as for high-speed, you need to configure the values manually. Try to set fp_hcnt and fc_lcnt at the same place as the hp ones:
dev->fp_hcnt = 17;
dev->fp_lcnt = 15;

Note that my values are for i2c0, with the 32 MHz oscillator, so you have to adjust them for i2c7 (100Mhz oscillator). After this workaround you should be finally able to use the driver with all supported speeds.

1 Like

@Loic
Thanks a lot.
I tried the below value yesterday and i2c read/write was failing.
dev->fp_hcnt = 2;
dev->fp_lcnt = 1;
I will try more combination .

The values you suggested for i2c0(17,15) is based on which registry data ?
I will switch to i2c0 as a next step if required

O_FREQ = i2c controller oscillator frequency (tick)
I2C_FREQ = i2c bus expected frequency
cnt = duration in tick count of the I2C bus period

So basically:
cnt = (O_FREQ / I2C_FREQ)

I2C controller needs to know this value in order to manage I2C clock. However, you don’t directly configure the period duration but the high-level and low-level duration (in tick count).

hcnt + lcnt = cnt

Then, to target a 1Mhz Frequency with i2c0 controller (32Mhz oscillator):
cnt = 32Mhz / 1Mhz = 32
hcnt + lcnt = 32
hcn ~= lnct = 32/2 ~= 16

For i2c7 with 100Mhz oscillator, hcnt ~= lnct ~= 50

This is how I found my values, for sure, this can require some adjustment depending controller spec, latency, rise/fall time… however, since i2c is a synchronous bus, freq accuracy is typically not a problem.

1 Like

Thank you @Loic.

Below are the configurations which works for me:

i2c0
1MHz →
dev->fp_hcnt = 10;
dev->fp_lcnt = 8;

3.4MHz →
Couldn’t make it stretch

i2c1
1MHz →
dev->fp_hcnt = 45;
dev->fp_lcnt = 43;

3.4MHz → (Last time (2,1) combination was giving me 3.4MHz good)
dev->hs_hcnt = 9;
dev->hs_lcnt = 7;

400KHz–>
dev->fs_hcnt = 125;
dev->fs_lcnt = 123;

2 Likes

Thank you @Mani. I was able to download it finally and it was very useful.

1 Like