Intel® SoC FPGA Embedded Development Suite
Support for SoC FPGA Software Development, SoC FPGA HPS Architecture, HPS SoC Boot and Configuration, Operating Systems
444 Discussions

driver for HPS I2C Hardware in u-boot 04.2020 deactivates clocks

Silvan
Novice
7,988 Views

Hello all,

I have an Arria 10 SoC device on our custom board. The board boots from an SD Card, loading u-boot and than a Linux kernel.

Until now, I used an old u-boot build flow utilized Quartus and the bsp-editor. With a small adaption,  u-boot (2014.10) is able to read a MAC address from an external EEPROM connected through an I2C interface.

Now I have to switch to a the new u-boot build flow created on the sources: https://github.com/altera-opensource/u-boot-socfpga (2020.04) as described on: https://rocketboards.org/foswiki/Documentation/BuildingBootloader?erpm_id=6579622_ts1606222496230

 

For our custom board, I adapted the u-boot configuration and device tree blob of the Arria 10 SoC DevKit included in the sources. When configuring the basic Hardware (SD Card, UART, Ethernet, ...) our board is able to boot the Liunx kernel.

As soon as, I try to enable and use the I2C interface in u-boot, the kernel isn't able to boot anymore. In configuration I added and activated the following configs:

CONFIG_MISC=y
CONFIG_I2C_EEPROM=y
CONFIG_SYS_I2C_EEPROM_BUS=0
CONFIG_SYS_I2C_EEPROM_ADDR=0x50
CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW=0
CONFIG_SYS_EEPROM_SIZE=512
CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=0
CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=0
CONFIG_CMD_EEPROM=y
CONFIG_CMD_I2C=y
CONFIG_SYS_I2C_DW=y

 

And in the device tree blob I have the I2C hardware:

&i2c1 {
  status = "okay";
  clock-frequency = <100000>;
  eeprom@50 {
    compatible = "atmel,24c512";
    reg = <0x50>;
    pagesize = <32>;
  };
};

 

With this adaption I could enable the I2C hardware in the u-boot console. When I try to boot the Linux kernel afterwards, the HPS gets stuck. I could enclose the issue to the u-boot function dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL); which is called before the kernel starts.

The function loops over the device tree blob and disable all active hardware. This is also done for the I2C driver and its clocks. So the designware_i2c_remove function disables the clock and after disabling the l4_sp_clk the device hangs.

Does anyone know, how to prevent the deactivation of the clocks? Does anyone has experience with the use of I2C in u-boot 2020.04?

 

Cheers

Silvan

 

0 Kudos
1 Solution
MWill5
Beginner
4,617 Views

Hello,

We had a similar problem trying to migrate to the socfpga_v2021.04 branch of uBoot.  We have an on-board EEPROM (I2C) that contains factory configuration data that is needed during the uBoot TPL phase.

We are seeing that the designware_i2c I2C controller is resetting the l4_sp_clk when it is removed prior to starting the linux kernel.  The result is that there is a bus hang when the kernel tries to access the UART peripheral (which needs that clock).  The kernel we are trying to use is from 4.9.78-ltsi.  It's possible that later versions of the kernel properly re-enable the l4_sp_clk, but this doesn't seem to be the case for our particular configuration (which works fine with uboot 2014.10).  We also had to set the socfpga_legacy_reset_compat=1 uBoot environment variable as well, as without it this version of uBoot will reset all the peripherals as it switches to linux, resulting in a similar hang.

 

Our work-around can be found in this patch here:

Critical Link LLC git repositories. - u-boot-socfpga.git/blobdiff - drivers/i2c/designware_i2c.c

 

-Mike

 

 

View solution in original post

33 Replies
EBERLAZARE_I_Intel
5,298 Views

Hi Silvan,

 

I noticed that you changed from the default configuration, thus you may need to change the Linux's device tree as well, you may find in similar directory:

\linux-socfpga-socfpga-5.4.54-lts\arch\arm\boot\dts

The file is called "socfpga_arria10_socdk".

From my experience of changing Uboot settings for a custom board, if you opt to use the Linux, you need to check the Linux's device tree as well. In addition, before changing the device tree, you need to check if the other config of the I2C is reliable to what you looking for, the frequency, compatible, etc..

Also, are you using "I2C1" in the old Uboot that worked? 

0 Kudos
Silvan
Novice
5,278 Views

Hi Eberlazare,

Thanks for your feedback.

 

I didn’t changed the Linux device tree during the u-boot migration from 2014.10 to 2020.04. Is it required? I think the issue which I observe in u-boot 2020.04 is shortly before the Linux kernel starts.

Our u-boot device tree is based on \arch\arm\dts\socfpga_arria10.dtsi which includes the I2C1 device information (compatible, clock, ...). I think, its configuration is correct because I’m able to communicate with our EEPROM from u-boot.

 

The issue which I’m observe is when u-boot switch to the Linux kernel. Before loading the kernel, u-boot has a clean-up routine to release allocated hardware resources. And at the point when the enabled I2C hardware is released, the system stops to work. I added additional debug/print-outputs in the u-boot sources to isolate the issue. I attached the log on this reply and a description follows bellow.

 

Yes, the old u-boot version 2014.10 used also I2C1 to read the MAC address from an external EEPROM. As far as I understand, the Hardware and FPGA firmware work correctly. So what is the recommendation to enable and use the I2C hardware in u-boot 2020.04? Is it wrong to just enable the i2c hardware based on \arch\arm\dts\socfpga_arria10.dtsi?

 

 

Short log description:

  1. Enabling the I2C device with ‘i2c dev 0’ (Line 44) and list available devices with ‘i2c prob’ (Line 52).
  2. Boot Linux kernel with ‘run bootcmd’ (Line 54)
  3. Starting log in file: \arch\arm\lib\bootm.c In function ‘announce_and_cleanup(int fake)’ dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL); is called. (Line 87)
  4. The function is implemented in \drivers\core\root.c and calls ‘device_remove’ from \drivers\core\device-remove.c which loops over all active devices and disable it and there child. (Line 88)
  5. If I2C active (which is true after calling ‘i2c prob’) (Line 305) the remove function ‘designware_i2c_remove(struct udevice *dev)’ in /drivers/i2c/designware_i2c.c is called (Line 337). This function stops the l4_sp_clkclk_disable clock which results in a non working system and after a while the watchdog reboot the device… (Line 339)

 

0 Kudos
EBERLAZARE_I_Intel
5,261 Views

Hi,

Yes as per my experience, it is required as you are running in Linux.

Correct me if I am wrong, you did change in the Uboot device tree, and in Uboot you are not seeing such issue, but only in Linux am I correct?

Have you tried changing the Linux device tree as well? 

0 Kudos
Silvan
Novice
5,253 Views

Hi Eberlazare,

No your assumption is wrong. I see such issue in Uboot! So I changed the Uboot device tree and using the I2C hardware in Uboot.

After that, I'm not able to boot an Linux because Uboot never try to load and start the Linux as described in my previous post.

Did you has any idea for that issue? And what is the recommendation from intel to using the I2C hardware in Uboot?

0 Kudos
EBERLAZARE_I_Intel
5,232 Views

Hi,

My recommendation is to check with default settings of GHRD and UBoot.

According to 2020.04 the device tree settings are set as per below:

&i2c1 {
status = "okay";

/*
* adjust the falling times to decrease the i2c frequency to 50Khz
* because the LCD module does not work at the standard 100Khz
*/
clock-frequency = <100000>;
i2c-sda-falling-time-ns = <6000>;
i2c-scl-falling-time-ns = <6000>;

adc@14 {
compatible = "lltc,ltc2497";
reg = <0x14>;
vref-supply = <&ref_033v>;
};

adc@16 {
compatible = "lltc,ltc2497";
reg = <0x16>;
vref-supply = <&ref_033v>;
};

eeprom@51 {
compatible = "atmel,24c32";
reg = <0x51>;
pagesize = <32>;
};

rtc@68 {
compatible = "dallas,ds1339";
reg = <0x68>;
};

ltc@5c {
compatible = "ltc2977";
reg = <0x5c>;
};
};

The difference is the EEPROM part and also you did not specify the SDA and SCL falling time. I am unsure if adding the falling time would prevent the clock to be deactivated but it is worth a try.

0 Kudos
EBERLAZARE_I_Intel
5,132 Views
0 Kudos
Silvan
Novice
5,128 Views

The issue is still there.

It is independent on the EEPROM type because the initialization of the I2C Hardware results into the issue. (On the u-boot console I could setup the I2C hardware without the initialization of external I2C device like the EEPROM)

Do you have additional information or are you able to reproduce the issue on your side?

Thanks, Silvan

0 Kudos
EBERLAZARE_I_Intel
5,088 Views

Hi,

The only thing I could think of is to try to debug using ARM DS and see where the steps stops.

https://rocketboards.org/foswiki/Documentation/SoCEDS#Run_U_45Boot_SPL_from_Debugger

 

0 Kudos
Silvan
Novice
5,012 Views

Hi Eberlazare,

In the meantime I've got the current version of intels arria10 development board (Rev. C). I started with the current version of the GSRD v20.1 from https://rocketboards.org/foswiki/Documentation/Arria10SoCGSRD

I still run into troubles by using the i2c device from u-boot. Do you have any examples or documentation how to get access to the EEPROM on the development board from u-boot? I'm looking for the current version of the following description: https://rocketboards.org/foswiki/Documentation/UBootA10HPSEMACAddressEEPROMSupport

This is exactly what I try to do. Read the Ethernet MAC address from the external EEPROM.

 

Thanks also for the documentation to the ARM DS debugging instructions. I'm not sure if it is exactly what we want. Because the documentation describes how to debug u-boot SPL. In our case, the u-boot SPL works fine and loads the full version of u-boot into the external RAM. The I2C issues are in the full u-boot image...

0 Kudos
EBERLAZARE_I_Intel
4,924 Views

Hi,

Ww have a video on the demo to do this via Uboot:

https://www.youtube.com/watch?v=2uC2r8YMUOA&ab_channel=IntelFPGA

Let me know if you're having trouble on the steps from the video.

0 Kudos
Silvan
Novice
4,904 Views

Hello Eberlazare,

Thanks for the link. The GSRD used in the movie is version 17.0 which use u-boot 2014.10. With this version I'm able to get access to the EEPROM connected on the I2C bus.

What I'm looking for, is exact the same procedure for the actual version of the GSRD (2020.11). This version use u-boot 2020.04 in which I'm not able to get the I2C access running as described in my first request.

Do you have such example using GSRD 2020.11 including u-boot 2020.11?

Or please, could you reproduce the issue on your side for this version? Do you need additional information for that?

Thanks,

Silvan

0 Kudos
EBERLAZARE_I_Intel
4,856 Views

hi Silvan,

Thanks for this followup, I think we can check with the changes made from 2014.10 to 2020.04, since you mentioned it worked on 2014. 

For 2020.11 uboot GHRD:

https://releases.rocketboards.org/release/2020.11/gsrd/a10_gsrd/

I can re-try using on Dev Kit and test from my side, it may take a few days.

 

 

0 Kudos
EBERLAZARE_I_Intel
4,766 Views

Hi,

Just an update, I am still working on this issue.

0 Kudos
Silvan
Novice
4,742 Views

Thanks for the information. Are you already able to reproduce the issue on your side? And now you are looking for fixes?

0 Kudos
EBERLAZARE_I_Intel
4,654 Views

Hi,

I am not seeing the issue with 2020.10 Uboot with the default GHRDs, I am trying different type of UBoot and checking the device tree of I2c individually .

0 Kudos
Silvan
Novice
4,645 Views

Hi Eberlazare,

On my side there is still an issue. Which u-boot version (commit ID) do you used? And what was the u-boot configuration applied for the i2c access test? Maybe you could share your binaries with me?

Attached you find my version of u-boot 2020.10:

https://github.com/altera-opensource/u-boot-socfpga.git

branch: socfpga_v2020.10

commit: c79c23c6201819ca32b6739eff2e2b25e19f6624

I enabled the I2C drivers and EEPROM drivers in the configuration. The resulting socfpga_arria10_defconfig is also in the attachment.

In u-boot I tried to enable and use the devices with the u-boot command 'i2c' and 'eeprom'. In both cases, the system hangs afterwards. Do you see any different between your tests and my one?

Thanks for your support,

Silvan

0 Kudos
EBERLAZARE_I_Intel
4,460 Views

Hi Silvan,

 

I git from https://github.com/altera-opensource/u-boot-socfpga/tree/socfpga_v2020.10

I shall re-try again using dev kit today, and configure and enable the I2C and EEPROM drivers in Uboot.

0 Kudos
Silvan
Novice
4,449 Views

Thanks for re-try. And please try also to exchange data between u-boot and EEPROM. Only the declaration in the device tree doesn't result in the issue. Using the EEPROM (read or write) from u-boot triggers the issue and let the system crash in  the following boot process.

 

Let me know when you have any news. Thanks and best regards, Silvan

0 Kudos
Silvan
Novice
4,372 Views
0 Kudos
EBERLAZARE_I_Intel
4,324 Views

Hi Silvan,

 

My apologies for the late respond.

 

For the 2020.04, U-boot, I checked, for the i2c tools. The following configs must be modified and included or my “make menuconfig”.

 

CONFIG_CMD_I2C=y

CONFIG_DM_I2C=y

CONFIG_SYS_I2C_DW=y

 

The file is in directory of U-boot "configs/socfpga_arria10_defconfig", I am unsure why the above is not set by default, as they are avaialbe in our other devices. 

 

I am checking with our internal team on the clarification, and will let you know once I have the reply.

 

Also, from my side I am trying the above on our dev kit as well, for U-boot version 2020.04 with the above config turned on. The default without the above config, the I2C tools does not work.

 

 

 

0 Kudos
Reply