Page 1 of 1

SAMA5D2 Flexcom in I2C / TWI mode under Linux?

Posted: Fri Aug 23, 2019 12:58 pm
by mikehaben
Hi all,
Has anyone successfully used a SAMA5D2 Flexcom interface in I2C mode under Linux? The situation I have is that, under Linux4SAM tag "sama5d27wlsom1ek_1.0" (4.14.88), a "/dev/i2c-2" node is created when I do
insmod /lib/modules/4.14.88/kernel/drivers/i2c/busses/i2c-at91.ko,
but then i2cdetect -y 2 returns
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: at91_i2c f8034600.i2c: controller timed out
-- at91_i2c f8034600.i2c: controller timed out
-- at91_i2c f8034600.i2c: controller timed out
(etc.)
and I can see that the SDA and SCL pins are not toggling at all, just sitting at logic-1. This is the relevant section of my .DTS file:

Code: Select all

			flx0: flexcom@f8034000 {
				atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
				status = "okay";

				i2c2: i2c@600 {
					compatible = "atmel,sama5d2-i2c";
					reg = <0x600 0x100>;
					interrupts = <19 IRQ_TYPE_LEVEL_HIGH 7>;
                    			dmas =  < &dma0  (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(11)) >,
                            				< &dma0  (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(12)) >;
					dma-names = "tx", "rx";
					#address-cells = <1>;
					#size-cells = <0>;
					clocks = <&flx0_clk>;
                    			clock-names = "i2c2_clk";
                    			clock-frequency = <400000>;
					pinctrl-names = "default";
					pinctrl-0 = <&pinctrl_flx0_i2c>;
					atmel,fifo-size = <16>;
					status = "okay";
				};
			};

				pinctrl_flx0_i2c: flx0_i2c {
					pinmux = <PIN_PB28__FLEXCOM0_IO0>, <PIN_PB29__FLEXCOM0_IO1>;
					bias-disable;
				};
I've checked that PB28 and PB29 pinmuxes are not being redefined elsewhere in the DTS/DTSI files.
I've tried building i2c-at91.ko into the kernel and as a loadable module (after reading https://archlinuxarm.org/forum/viewtopi ... 47&p=55799)
I've read and re-read Documentation/devicetree/bindings/mfd/atmel-flexcom.txt and ...bindings/i2c/i2c-at91.txt, Googled and grep'd and tried many small alterations to the DTS file.
And now I'm ready to admit I'm stuck!

Any suggestions please?

Thansk, Mike H.

Re: SAMA5D2 Flexcom in I2C / TWI mode under Linux?

Posted: Fri Aug 23, 2019 2:48 pm
by mikehaben
And a snippet more info:
  • root@TABASCO:~# cat /sys/kernel/debug/pinctrl/fc038000.pinctrl/pinmux-pins
    Pinmux settings per pin
    Format: pin (name): mux_owner gpio_owner hog?
    pin 0 (PA0): a0000000.sdio-host (GPIO UNCLAIMED) function A group PA0
    pin 1 (PA1): a0000000.sdio-host (GPIO UNCLAIMED) function A group PA1
    pin 2 (PA2): a0000000.sdio-host (GPIO UNCLAIMED) function A group PA2
    ...
    pin 60 (PB28): f8034600.i2c (GPIO UNCLAIMED) function C group PB28
    pin 61 (PB29): f8034600.i2c (GPIO UNCLAIMED) function C group PB29
So the Flexcom0 (0xf8034000) I2C function (offset 0x600) has definitely "claimed" the pins.

Re: SAMA5D2 Flexcom in I2C / TWI mode under Linux?

Posted: Fri Aug 23, 2019 4:32 pm
by mikehaben
Finally, a possible clue:
  • root@TABASCO:~# cat /sys/kernel/debug/clk/flx0_clk/clk_enable_count
    0
Looks like the FLEXCOM0 peripheral-clock is not being enabled! But why not? The I2C device is being instantiated during boot:
  • root@TABASCO:~# dmesg | grep i2c
    [ 0.750000] at91_i2c f8034600.i2c: using dma0chan0 (tx) and dma0chan1 (rx) for DMA transfers
    [ 0.760000] at91_i2c f8034600.i2c: Using FIFO (16 data)
    [ 0.760000] at91_i2c f8034600.i2c: AT91 i2c bus driver (hw version: 0x704).
    [ 1.260000] i2c /dev entries driver
Is there a way of forcing a particular clock to be enabled?

Gaaah, i hate Device-Tree! :evil:

Re: SAMA5D2 Flexcom in I2C / TWI mode under Linux?

Posted: Tue Aug 27, 2019 2:58 am
by blue_z
mikehaben wrote: This is the relevant section of my .DTS file:

Code: Select all

			flx0: flexcom@f8034000 {
				atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
				status = "okay";

				i2c2: i2c@600 {
That last label would seem to conflict with the subnode in flx1: flexcom@f8038000.

mikehaben wrote: Looks like the FLEXCOM0 peripheral-clock is not being enabled!
That is probably not the correct assessment.
Power management can turn off the peripheral when it is idle, but should turn it back on when in use (e.g. when it's open()ed).
You could confirm that by hacking & rebuilding the flexcom and i2c drivers with no PM capability to sleep.

Try probing device registers in a live system using the devmem command in Busybox.
Examine the PMC_PCSR0 register at 0xF0014018 to see which peripheral clocks are enabled (e.g. FLEXCOM0 is PID19).

Consider adding printk()s to the i2c_at91.c driver or enable its debug.
FWIW there's a lengthy warning in at91_do_twi_transfer() from which the "controller timed out" messages originate.


Regards

Re: SAMA5D2 Flexcom in I2C / TWI mode under Linux?

Posted: Mon Sep 02, 2019 4:08 pm
by mikehaben
blue_z wrote:
That last label would seem to conflict with the subnode in flx1: flexcom@f8038000.
Do you mean the definition of i2c2 as a sub-device of flx1 in at91-sama5d27_som1_ek.dts? That file isn't being used, so there's no conflict.

Re. using devmem to read and write peripheral registers directly: thank you, I wasn't aware of that utility!
I've used it to write PMC_PCER0 bit 19 to 1 "behind the kernel's back", then check that it remains set by reading back PMC_PCSR0. Then I tried i2cdetect again, but with the same result - the SCL/SDA pins remain high, and console shows "at91_i2c f8034600.i2c: controller timed out".
PMC_PCSR0 bit 19 is still set immediately after i2cdetect completes, and is then cleared after 1-2 seconds, so looks like the kernel power-management is working correctly.

Hmmmm....

Re: SAMA5D2 Flexcom in I2C / TWI mode under Linux?

Posted: Tue Sep 03, 2019 10:15 am
by mikehaben
... and in fact, if I simply do
i2cdetect -y 2
let it run for a few seconds, then Ctrl-C and
devmem2 0xF0014018
it reads 0x080C20E0 - bit 19 is set, FLEXCOM0 clock has been enabled.
Another devmem2 0xF0014018 a couple of seconds later reads back 0x080420E0, FLEXCOM0 clock has been disabled again. Seems that power-management is doing exactly what it should.

I've switched back to testing with mainline Linux 5.2 instead of Linux4SAM 4.14.88, seems no worse...

Re: SAMA5D2 Flexcom in I2C / TWI mode under Linux?

Posted: Fri Sep 06, 2019 12:02 am
by kriekhof
Hello, I just had the same problem, but on flexcom2

Apparently, this will happen if the i2c bus does not have external pull up resistors on it.
once I added a couple 10k resistors connected to 3.3v, I was off to the races.

Also, flexcom0 and flexcom3 (may?) require smaller resistance than usual (2.2k specifically)

Perhaps this is your problem as well?

Re: SAMA5D2 Flexcom in I2C / TWI mode under Linux?

Posted: Fri Sep 06, 2019 11:59 am
by mikehaben
We have FLEXCOM4 lines available on an expansion connector, so I tried configuring that as TWI (i2c3), and i2cdetect -y 3 works just fine! Even the SCL clock-frequency (measured on an oscilloscope) is as configured in the DTS file.
I've gone through line-by-line comparing the configurations of i2c2 and i2c3, ensured they are identical (except for peripheral-IDs in the "clocks" and "interrupts" items), yet still i2c2 does not work - i2c2detect reports "at91_i2c f8034600.i2c: controller timed out".

So what is different about FLEXCOM0?

Re: SAMA5D2 Flexcom in I2C / TWI mode under Linux?

Posted: Fri Sep 06, 2019 12:02 pm
by mikehaben
@kriekhof: thank you, but yes, we have pullup resistors (4k7 to 1.8V) on both lines. i2c3 is working OK with 10k pullups.

Re: SAMA5D2 Flexcom in I2C / TWI mode under Linux?

Posted: Mon Sep 09, 2019 9:48 am
by mikehaben
Sorry everyone! After all that, the issue turned out to be a cut track caused by a previous board-modification!
FLEXCOM0 is now working in TWI mode, and i2cdetect does find a device at the expected address.