Using a device table overlay to disable the onboard RTC on the beaglebone black

Since the Beaglebone Black RTC is not usable (I believe due to a hw bug), I’m using an external RTC chip (A Maxim / Dallas DS1338 on i2c2 at address 0x68), and informing the kernel about this using a device tree overlay.

I’m also disabling the onboard RTC using a (currently separate) device tree overlay, this is because otherwise the omap rtc gets enumerated first which leaves the kernel time starting at jan 1st 2000 on cold boot. The onboard rtc ends up being /dev/rtc0 (which is linked to by /dev/rtc) and ntpd does its clock drift adjustment vs this rtc-with-no-battery-backup etc. - it seemed best to just disable it, since I have another one which is actually battery-backed.

This seem to work, but I wanted to check that there wasn’t some other functionality I’d be harming by doing this?

If anyone is familiar with device tree overlays, I would also appreciate a review of these:

Firstly BB-DS1388-I2C2-68.dts - which I compile with:

dtc -W no-unit_address_vs_reg -@ -I dts -O dtb -o BB-DS1388-I2C2-68-00A0.dtbo BB-DS1388-I2C2-68.dts

/dts-v1/;
/plugin/;

/ {

compatible = “ti,beaglebone”, “ti,beaglebone-black”;
part-number = “BB-DS1388-I2C2-68”;
version = “00A0”;

fragment@0 {
target = <&i2c2>;

overlay {
#address-cells = <1>;
#size-cells = <0>;
pinctrl-0 = <&i2c2_pins>;

clock-frequency = <100000>;
status = “okay”;

capertc: rtc@68 { /* Real time clock defined as a child of the i2c2 bus */
compatible = “maxim,ds1338”;
#address-cells = <1>;
#size-cells = <0>;
reg = <0x68>;
};
};
};
};

Secondly to disable the onboard RTC - BB-NO-OMAP-RTC.dts

dtc -W no-unit_address_vs_reg -@ -I dts -O dtb -o BB-NO-OMAP-RTC-00A0.dtbo BB-NO-OMAP-RTC.dts

/dts-v1/;
/plugin/;

/ {

compatible = “ti,beaglebone”, “ti,beaglebone-black”;
part-number = “BB-NO-OMAP-RTC”;
version = “00A0”;

fragment@0 {
target = <&rtc>;

overlay {
status = “disabled”;

};
};
};

Any feedback welcome!

Thanks,

Tim.

Since the Beaglebone Black RTC is not usable (I believe due to a hw bug),
I'm using an external RTC chip (A Maxim / Dallas DS1338 on i2c2 at address
0x68), and informing the kernel about this using a device tree overlay.

Correct, without a battery it's pretty useless. :wink:

I'm also disabling the onboard RTC using a (currently separate) device tree
overlay, this is because otherwise the omap rtc gets enumerated first which
leaves the kernel time starting at jan 1st 2000 on cold boot. The onboard
rtc ends up being /dev/rtc0 (which is linked to by /dev/rtc) and ntpd does
its clock drift adjustment vs this rtc-with-no-battery-backup etc. - it
seemed best to just disable it, since I have another one which is actually
battery-backed.

This seem to work, but I wanted to check that there wasn't some other
functionality I'd be harming by doing this?

If anyone is familiar with device tree overlays, I would also appreciate a
review of these:

Your overlays look good, have you tried combining them into one file?

If it works fine as one file (BB-I2C2-DS1388-00A0.dts) , can you
submit a pull request for:

https://github.com/beagleboard/bb.org-overlays/tree/master/src/arm

and i'll push it out for all users. :wink:

Regards,

I think that is what I am looking for to replace the typical “hack” solution I found described in a few places with a search.
The hack solution uses a systemd service and a script to force the system clock to the value read from the hardware clock rtc1 shortly after boot.

This works, somewhat, but I noticed the hwclock was drifting several seconds per day, even after connecting the board to the internet with network time
and allowing the drift adjustment to work. I suspected the drift adjustment is not being applied to the external clock rtc1.

Note that there is a kernel option to change the hardware clock to rtc1. The default is of course rtc0. So if you are building or re-building the kernel this would be the easiest solution.

I’ll try your device tree fragments soon and report what happens. Thanks for the work on this, the clock drift problem is the last piece of one of my projects still not resolved.

Regards,
Greg

Thanks Robert,

The overlays work when combined into a single file, however I've noticed
that with the onboard RTC disabled, the beaglebone black no longer
powers off.

I'm guessing that the RTC is being used during shutdown? I'm not sure
whether the power off code is just using the RTC to trigger the next
stage of the shutdown code, or if it's actually used to trigger the HW
shutdown sequence directly. If the former then perhaps it would work OK
with the ds1338 if it was available earlier in the boot sequence?

Any ideas, and if waiting for ds1338 init is the answer how to arrange
for that?

If omap rtc is essential to the shutdown sequence, then I suppose I'll
see if I can either set the ds1338 to be /dev/rtc0 or just get linked to
/dev/rtc e.g. using udev?

When the 'poweroff' command is issued, then I get:

omap_rtc disabled at boot:

[ 3.788171] bone_capemgr bone_capemgr: initialized OK.
[ 3.800527] PM: rtc0 not available
[ 3.805005] hctosys: unable to open rtc device (rtc0)
...
[ 4.856569] rtc-ds1307 2-0068: rtc core: registered ds1338 as rtc0
[ 4.900682] rtc-ds1307 2-0068: 56 bytes nvram
[ 4.934936] PM: bootloader does not support rtc-only!
...
[ 7.036492] systemd[1]: System time before build time, advancing clock.

omap_rtc disabled at poweroff:

[ 57.328742] systemd-shutdown[1]: Powering off.
...
[ 57.378562] reboot: System halted
<remains powered>

omap_rtc NOT disabled (ds1338 also enabled) - at boot:

[ 3.365041] omap_rtc 44e3e000.rtc: already running
[ 3.370543] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc
as rtc0
...
[ 3.800087] bone_capemgr bone_capemgr: initialized OK.
[ 3.812568] PM: bootloader does not support rtc-only!
...
[ 3.819111] omap_rtc 44e3e000.rtc: setting system clock to 2017-09-11
12:55:47 UTC
[ 4.865031] rtc-ds1307 2-0068: rtc core: registered ds1338 as rtc1
[ 4.894450] rtc-ds1307 2-0068: 56 bytes nvram
...

omap_rtc NOT disabled - at 'poweroff':

[ 53.181208] systemd-shutdown[1]: Powering off.
...
[ 53.231249] reboot: Power down
[ 53.234626] System will go to power_off state in approx. 1 second
<power actually turns off>

Cheers,

Tim.

To answer my own question, in the debug messages I posted earlier the
ds1338 was getting initialised late because the kernel which I was using
at the time had the driver (rtc-ds1307) built as a module.

Using a kernel with the ds13xx driver built-in instead gets more sane
RTC behaviour, but still results in the shutdown code halting the system
instead of attempting a power off.

Tim.

Hi Tim,

Yeah, shutdown is tied to the built-in rtc..

I'm thinking we need to do something like here in the Jetson, and add
a rtc aliases:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/tegra124-jetson-tk1.dts?h=v4.13#n12

Regards,

Thanks Robert - much appreciated...

I found this -
http://developer.toradex.com/device-tree-customization#aliases - which
concurs. As far as I can tell unfortunately it doesn't seem possible to
dynamically add new aliases using a device tree overlay (yet?), so
that'll mean recompiling the main device tree instead I think.

Does that sound right?

I find any other way of forcing /ocp/rtc@44e3e00 to be rtc1 at least,
but I could easily be missing something of course.

Cheers,

Tim.

I'm close (using a pcf8523)

root@beaglebone:~# uname -r
4.9.49-ti-r58

root@beaglebone:~# dmesg | grep rtc
[ 2.428569] omap_rtc 44e3e000.rtc: already running
[ 2.429071] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc0
[ 2.649410] rtc-pcf8523 2-0068: /aliases ID 0 not available
[ 2.650843] rtc-pcf8523 2-0068: rtc core: registered rtc-pcf8523 as rtc1
[ 2.693786] PM: bootloader does not support rtc-only!
[ 2.694815] omap_rtc 44e3e000.rtc: setting system clock to
2017-09-11 20:09:40 UTC (1505160580)

https://github.com/RobertCNelson/bb.org-overlays/blob/rtc-hacks/src/arm/BB-I2C2-PCF8523-00A0.dts

for some reason, it still gave rtc0 to omap...

Regards,

I'm close (using a pcf8523)

root@beaglebone:~# uname -r
4.9.49-ti-r58

root@beaglebone:~# dmesg | grep rtc
[ 2.428569] omap_rtc 44e3e000.rtc: already running
[ 2.429071] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc0
[ 2.649410] rtc-pcf8523 2-0068: /aliases ID 0 not available
[ 2.650843] rtc-pcf8523 2-0068: rtc core: registered rtc-pcf8523 as rtc1
[ 2.693786] PM: bootloader does not support rtc-only!
[ 2.694815] omap_rtc 44e3e000.rtc: setting system clock to
2017-09-11 20:09:40 UTC (1505160580)

https://github.com/RobertCNelson/bb.org-overlays/blob/rtc-hacks/src/arm/BB-I2C2-PCF8523-00A0.dts

for some reason, it still gave rtc0 to omap...

one kinda crazy idea... we know am335x's are not battery backed up, so
what if we just specify "rtc1"

with pcf8523 plugged in:

root@beaglebone:~# dmesg | grep rtc
[ 1.982270] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc0
[ 2.186787] rtc-pcf8523 2-0068: rtc core: registered rtc-pcf8523 as rtc1
[ 2.229775] PM: bootloader does not support rtc-only!
[ 2.231880] rtc-pcf8523 2-0068: setting system clock to 2017-09-11
21:22:26 UTC (1505164946)

with pcf8523 not plugged in:
root@beaglebone:~# dmesg | grep rtc
[ 2.163450] omap_rtc 44e3e000.rtc: already running
[ 2.163946] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc0
[ 2.399128] PM: bootloader does not support rtc-only!
[ 2.400752] hctosys: unable to open rtc device (rtc1)

This is what i'm thinking:

diff --git a/patches/defconfig b/patches/defconfig
index ef7b6cd..6904989 100644
--- a/patches/defconfig
+++ b/patches/defconfig
@@ -5306,9 +5306,9 @@ CONFIG_RTC_LIB=y
CONFIG_RTC_MC146818_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+CONFIG_RTC_HCTOSYS_DEVICE="rtc1"
CONFIG_RTC_SYSTOHC=y
-CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
+CONFIG_RTC_SYSTOHC_DEVICE="rtc1"
# CONFIG_RTC_DEBUG is not set

Bingo, got it:

dmeroot@beaglebone:~# dmesg | grep rtc
[ 1.981906] omap_rtc 44e3e000.rtc: already running
[ 1.982366] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc1
[ 2.186792] rtc-pcf8523 2-0068: rtc core: registered rtc-pcf8523 as rtc0
[ 2.229750] PM: bootloader does not support rtc-only!
[ 2.231877] rtc-pcf8523 2-0068: setting system clock to 2017-09-11
21:41:08 UTC (1505166068)

Just missed a "0" on the 32bit register value:

https://github.com/RobertCNelson/bb.org-overlays/commit/946359cdf5fc6d2a0e1cbf04541116d6d0757848

Regards,

Hi Robert,

Great, I've got that working (without hacking the main device table)
based on your example - much appreciated. I'd tried something similar
but had slipped up by putting the aliases definition at the top level,
instead of inside an __overlay__ within its own fragment.

I'd be happy to create a pull request if you think it would be useful?

Tim.

Yeap, please submit it.

I'm also cleaning up the other RTC example in the git tree to use the aliases,.

Regards,

Hi,

I’m running the “Debian 9.3 2018-01-28 4GB SD IoT” image and added a PCF8523 RTC to the i2c2 bus. Specifically, I am working with this board from Adafruit:
https://www.adafruit.com/product/3295

Everything works fine manually:

config-pin P9_19 i2c
config-pin P9_20 i2c

echo pcf8523 0x68 > /sys/class/i2c-adapter/i2c-2/new_device

[ 473.652063] rtc-pcf8523 2-0068: rtc core: registered rtc-pcf8523 as rtc1
[ 473.663924] i2c i2c-2: new_device: Instantiated device pcf8523 at 0x68

hwclock -w -f /dev/rtc1
hwclock -r -f /dev/rtc1

2018-02-20 22:04:30.521921+0000

I wanted to have it come up automatically by using the BB-I2C2-PCF8523-00A0.dts as mentioned in this thread, but that causes ‘config-pin’ to stop working for setting up my other pins. I think this has something to do with the universal overlay now being disabled? What is the correct way to get all this working together?

Thanks.

I've been working on this for a few weeks. While it isn't 100% ready,
it's ready for what you just asked here ^...

Can’t boot back after step 5. I am running from eMMC, if that makes a difference.

U-Boot SPL 2018.03-rc2-00002-ged1e504391 (Feb 16 2018 - 15:02:58 -0600)
Trying to boot from MMC2
MMC: block number 0x1 exceeds max(0x0)
MMC: block number 0x1 exceeds max(0x0)
MMC: block number 0x44 exceeds max(0x0)
MMC: block number 0x301 exceeds max(0x0)
mmc_load_image_raw_sector: mmc block read error
** Partition 1 not valid on device 1 **
spl_register_fat_device: fat register err - -1
spl_load_image_fat: error reading image u-boot.img, err - -1
spl: no partition table found
SPL: failed to boot from all boot devices

ERROR ### Please RESET the board

I’ll re-image tomorrow and will reboot after each step, but I assume it was upgrading the bootloader in step 1.

Thanks.

Cool, haven't tested rc2 with the eMMC yet, i'll debug that tomorrow..

Regards,

Okay, it "looks" like this was fixed in rc3:

Blue, eMMC boot..

U-Boot SPL 2018.03-rc3-00002-g97c27b4ee5 (Feb 20 2018 - 20:15:25 -0600)
Trying to boot from MMC2

U-Boot 2018.03-rc3-00002-g97c27b4ee5 (Feb 20 2018 - 20:15:25 -0600),
Build: jenkins-github_Bootloader-Builder-38

CPU : AM335X-GP rev 2.1
I2C: ready
DRAM: 512 MiB
No match for driver 'omap_hsmmc'
No match for driver 'omap_hsmmc'
Some drivers were not found
Reset Source: Global warm SW reset has occurred.
Reset Source: Power-on reset has occurred.
MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1
Board: BeagleBone Black
<ethaddr> not set. Validating first E-fuse MAC
BeagleBone Black:
Model: BeagleBoard.org BeagleBone Blue:

Next i'm going to upgrade test my BBB farm, so let's see how many
don't come up..

Regards,

all 19 units came back up..

Regards,

Now it won’t boot after upgrading the kernel in step 2 (still running off eMMC):

Loading, please wait…
starting version 232
[ 3.031626] usb 1-1: new high-speed USB device number 2 using musb-hdrc
[ 3.193198] usb 1-1: New USB device found, idVendor=05e3, idProduct=0610
[ 3.200011] usb 1-1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[ 3.207193] usb 1-1: Product: USB2.0 Hub
[ 3.231002] hub 1-1:1.0: USB hub found
[ 3.239646] hub 1-1:1.0: 4 ports detected
Begin: Loading essential drivers … done.
Begin: Running /scripts/init-premount … done.
Begin: Mounting root file system … Begin: Running /scripts/local-top … done.
Begin: Running /scripts/local-premount … Scanning for Btrfs filesystems
done.
Begin: Waiting for root file system … Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
Begin: Running /scripts/local-block … done.
done.
Gave up waiting for root file system device. Common problems:

  • Boot args (cat /proc/cmdline)
  • Check rootdelay= (did the system wait long enough?)
  • Missing modules (cat /proc/modules; ls /dev)
    ALERT! /dev/mmcblk1p1 does not exist. Dropping to a shell!

BusyBox v1.22.1 (Debian 1:1.22.0-19+b3) built-in shell (ash)
Enter ‘help’ for a list of built-in commands.

(initramfs)

Thanks.

That's odd, can you plug in a usb serial and grab this section of u-boot:

loading /boot/vmlinuz-4.16.0-rc2-bone3 ...
10183168 bytes read in 672 ms (14.5 MiB/s)
uboot_overlays: [uboot_base_dtb=am335x-boneblue.dtb] ...
uboot_overlays: Switching too: dtb=am335x-boneblue.dtb ...
loading /boot/dtbs/4.16.0-rc2-bone3/am335x-boneblue.dtb ...
51263 bytes read in 43 ms (1.1 MiB/s)
uboot_overlays: [fdt_buffer=0x60000] ...
uboot_overlays: loading /lib/firmware/BB-ADC-00A0.dtbo ...
695 bytes read in 262 ms (2 KiB/s)
uboot_overlays: loading /lib/firmware/AM335X-PRU-RPROC-4-4-TI-00A0.dtbo ...
2402 bytes read in 277 ms (7.8 KiB/s)
loading /boot/initrd.img-4.16.0-rc2-bone3 ...
3865578 bytes read in 276 ms (13.4 MiB/s)
debug: [console=ttyO0,115200n8 bone_capemgr.uboot_capemgr_enabled=1
root=/dev/mmcblk1p1 ro rootfstype=ext4 rootwait coherent_pool=1M
net.ifnames=0 quiet] ...
debug: [bootz 0x82000000 0x88080000:3afbea 88000000] ...
## Flattened Device Tree blob at 88000000
   Booting using the fdt blob at 0x88000000
   Loading Ramdisk to 8fc50000, end 8ffffbea ... OK
   reserving fdt memory region: addr=88000000 size=6d000
   Loading Device Tree to 8fbe0000, end 8fc4ffff ... OK

Starting kernel ...

Regards,