RTC Missing from Device Tree

We have an M41T0M6 RTC device fitted to our custom Apalis TK1 carrier. When working with the system time recently, we noticed that the time is not being maintained - resetting to "2000-01-01 00:00" every time our platform is being rebooted.

For reference, this is an L4T Ubuntu-based system.

Upon closer inspection, it would appear that our I2C RTC device is not being loaded at bootup:

ubuntu@linux-toradex:~$ dmesg | grep rtc
[    4.165861] as3722-rtc as3722-rtc.1: rtc core: registered as3722 as rtc0
[    4.173819] as3722-rtc as3722-rtc.1: RTC interrupt 449
[    4.190254] rtc-ds1307: probe of 0-0068 failed with error -5
[    4.197636] tegra_rtc tegra_rtc: rtc core: registered tegra_rtc as rtc1
[    4.209827] tegra_rtc tegra_rtc: Tegra internal Real Time Clock
[    5.562800] as3722-rtc as3722-rtc.1: setting system clock to 2000-01-01 00:00:08 UTC (946684808)

However, two RTC devices already exist on the system:

ubuntu@linux-toradex:~$ ls -l /dev/rtc*
lrwxrwxrwx 1 root root      4 Jan  1 00:00 /dev/rtc -> rtc0
crw------- 1 root root 254, 0 Jan  1 00:00 /dev/rtc0
crw------- 1 root root 254, 1 Jan  1 00:00 /dev/rtc1

One of which we assume is the RTC fitted on the TK1 module, the other, we are unsure of its source.

If we check the the hwclock, it does indeed report the default time:

ubuntu@linux-toradex:~$ sudo hwclock
Sat Jan  1 00:27:23 2000  -0.983358 seconds

And upon closer inspection, the hwclock is using one of the installed RTC devices:

ubuntu@linux-toradex:~$ sudo hwclock --debug
hwclock from util-linux 2.20.1
Using /dev interface to clock.
Last drift adjustment done at 1503997511 seconds after 1969
Last calibration done at 1503997511 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
...got clock tick
Time read from Hardware Clock: 2000/01/01 00:28:24
Hw clock time : 2000/01/01 00:28:24 = 946686504 seconds since 1969
Sat Jan  1 00:28:24 2000  -0.428543 seconds

Now obviously, what we want is for the system to use our RTC rather than one of these other devices.

Having looked at the device-tree, its obvious that we have not configured the device correctly as by default it is assigned to GEN1_I2C (pins 209/211) whereas on our carrier, the RTC device is connected to I2C2 (pins 205/207).

Our question is this: once we have modified/rebuilt/updated the device tree, are there any special steps necessary in order to point the /dev/rtc device to our new device?

Would this be a correct modification of the tegra124-apalis-eval.dtb file to move the RTC onto the other I2C port:

i2c@7000c400 {
    status = "okay";
    clock-frequency = <100000>;

    rtc@68 {
        compatible = "st, m41t00";
        reg = <0x68>;
    };
};

[ 4.190254] rtc-ds1307: probe of 0-0068 failed with error -5

Seems like the probe failed with IO error. Can you see the device acked when probed with i2cdetect from command line ?

This is because there is no device of that type on that I2C bus, as explained in the post.

Once we have modified/rebuilt/updated the device tree, are there any special steps necessary in order to point the /dev/rtc device to our new device?

Yes, just create a file called /etc/udev/rules.d/99-rtc1.rules with e.g. the following contents:

KERNEL=="rtc1", SUBSYSTEM=="rtc", DRIVER=="", ATTR{name}=="m41t00", SYMLINK="rtc", MODE="0666"

Thanks @marcel.tx, would you agree with the changes to the device-tree with regards to how the i2c is configured (the physical address)?

Yes, sorry. That looks proper indeed.

Thanks again @marcel.tx

I’ve just re-built the device tree and updated the TK1 via the update_fdt command. The device is successfully registered as an RTC device:

ubuntu@linux-toradex:~$ dmesg | grep rtc
[    4.074817] as3722-rtc as3722-rtc.1: rtc core: registered as3722 as rtc0
[    4.082823] as3722-rtc as3722-rtc.1: RTC interrupt 449
[    4.093833] rtc-ds1307 1-0068: rtc core: registered m41t00 as rtc1
[    4.101733] tegra_rtc tegra_rtc: rtc core: registered tegra_rtc as rtc2
[    4.113894] tegra_rtc tegra_rtc: Tegra internal Real Time Clock
[    5.724173] as3722-rtc as3722-rtc.1: setting system clock to 2000-01-01 01:18:27 UTC (946689507)

However, when I try and read the hardware clock, I get an error:

ubuntu@linux-toradex:~$ sudo hwclock -r
hwclock: ioctl(RTC_RD_TIME) to /dev/rtc to read the time failed: Invalid argument

ubuntu@linux-toradex:~$ sudo hwclock --debug
hwclock from util-linux 2.20.1
Using /dev interface to clock.
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
/dev/rtc does not have interrupt functions. Waiting in loop for time from /dev/rtc to change
hwclock: ioctl(RTC_RD_TIME) to /dev/rtc to read the time failed: Invalid argument
...synchronization failed

I’ve double-checked and the RTC points to the correct device:

ubuntu@linux-toradex:~$ ls -l /dev/rtc*
lrwxrwxrwx 1 root root      4 Jan  1 01:18 /dev/rtc -> rtc1
crw------- 1 root root 254, 0 Jan  1 01:18 /dev/rtc0
crw-rw-rw- 1 root root 254, 1 Jan  1 01:18 /dev/rtc1
crw------- 1 root root 254, 2 Jan  1 01:18 /dev/rtc2

Any clues what this could point to?

You first will need to set a valid time in order to be able to read it back out.

Ok, managed to solve this little problem. The last post in this link helped:

https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=20619

One very final thing. We’ve disabled the NTP:

timedatectl set-ntp false

However, the RTC clock and the local time are out of sync. Is there any way to force re-sync every time the system boots?

I believe upon boot the Linux kernel automatically syncs from rtc0. The only way to influence that would be to disable the other RTC driver(s) and/or somehow change the order in which they are loaded (unfortunately device tree alias do not seem to work for this in downstream).

Alternatively you may just create a systemd service using e.g. hwclock to achieve the same albeit only a few seconds later and in Linux user space.

Thanks @marcel.tx, I’ll just use the 99-rtc1.rules file as per your previous suggestion. It works but just means I need to have an additional sync startup script

Yes, I believe outside of using NTP that is pretty much how one is supposed to do it particularly if the Linux kernel syncs from the wrong one. See e.g. also Poettering’s explanation of how that stuff is supposed to work.

hello everyone,

I am having similar trouble with another board wish is not a toradex product.

Can anyone help please ?

hi @ouss91: Welcome to the Toradex Community. We will try to answer your issue in this thread.
Best regards, Jaski