Repository navigation
hi3516cv300: bind rtc-hibvt to the SoC RTC, and judge the time by its counter - #125
Conversation
The RTC node said "hisilicon,hi_rtc", which no in-tree driver matches. rtc-hibvt matches "hisilicon,hi35xx-rtc" and drives the same block (SPI bridge at 0x12090000, the same register map as the SDK's hi3516cv300 RTC module), so with CONFIG_RTC_DRV_HIBVT the board still had no /dev/rtc0. That is OpenIPC/firmware#191: hwclock has no RTC to open, and the SDK module only offers private HI_RTC_* ioctls, so pointing /dev/rtc0 at it fails with EPERM.
…K_CFG alone Port of the hisilicon-hi3536dv100 change (#81), which this branch's copy of the driver matches byte for byte: - read_time() no longer fails, or logs, because of the low-voltage flag. The flag was "cleared" by writing 1 to RTC_INT_CLR, which is the alarm bit, so once set it never cleared and the RTC stayed unreadable. It is not a verdict on the time anyway: on a hi3516ev300 it stays set with a backup cell that keeps the time. - A counter before 2000-01-01, which is what a counter that lost power reads, is reported as unset, so hctosys does not set the clock to 1970. set_time() refuses the same range. - The flag is cleared with LV_INT_MASK. On hi3516cv300, skip the RTC_CLK_CFG write. The SDK's own hi3516cv300 RTC driver never writes it, and it reads 0 on a running board; the 0x01 here is the hi3536cv100 value.
PR Summary by QodoBind the hi3516cv300 RTC and reject reset counter values
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
The cv300 and ev100 kernels were built without the RTC class, so the board had no /dev/rtc0: hwclock failed with "can't open '/dev/misc/rtc'", hctosys never ran, and fake-hwclock had no RTC to keep. The SDK's hi3516cv300_rtc.ko, which the image ships but nothing loads, cannot stand in: it offers only private HI_RTC_* ioctls, so hwclock's RTC_RD_TIME on it fails with EPERM (#191). Turn on the RTC class with hctosys, systohc, the dev, sysfs and proc interfaces, and rtc-hibvt. It binds once the device tree names the RTC "hisilicon,hi35xx-rtc" (OpenIPC/linux#125); until then this costs about 8 KB of kernel and changes nothing else.
Code Review by Qodo
1.
|
set_time() collected the SPI write results in an unsigned char, so a bridge timeout (-EIO) came back as 251: RTC_SET_TIME reported success for a write that never reached the RTC. Every other function here already uses int.
The cv300 kernel was built without the RTC class, so the board had no /dev/rtc0: hwclock failed with "can't open '/dev/misc/rtc'", hctosys never ran, and fake-hwclock had no RTC to keep. The SDK's hi3516cv300_rtc.ko, which the image ships but nothing loads, cannot stand in: it offers only private HI_RTC_* ioctls, so hwclock's RTC_RD_TIME on it fails with EPERM (#191). Turn on the RTC class with hctosys, systohc, the dev, sysfs and proc interfaces, and rtc-hibvt. It binds once the device tree names the RTC "hisilicon,hi35xx-rtc" (OpenIPC/linux#125); until then this costs about 8 KB of kernel and changes nothing else. hi3516ev100 shares the kernel family but is left as it is: there is no ev100 board to run it on.
|
/review |
|
Code review by qodo was updated up to the latest commit 9c86555 |
The cv300 kernel was built without the RTC class, so the board had no /dev/rtc0: hwclock failed with "can't open '/dev/misc/rtc'", hctosys never ran, and fake-hwclock had no RTC to keep. The SDK's hi3516cv300_rtc.ko, which the image ships but nothing loads, cannot stand in: it offers only private HI_RTC_* ioctls, so hwclock's RTC_RD_TIME on it fails with EPERM (#191). Turn on the RTC class with hctosys, systohc, the dev, sysfs and proc interfaces, and rtc-hibvt. It binds once the device tree names the RTC "hisilicon,hi35xx-rtc" (OpenIPC/linux#125); until then this costs about 8 KB of kernel and changes nothing else. hi3516ev100 shares the kernel family but is left as it is: there is no ev100 board to run it on.
Kernel half of OpenIPC/firmware#191: on hi3516cv300,
hwclockhas no RTC to use. The firmware half, which turns on the RTC options in the cv300 and ev100 kernel configs, is OpenIPC/firmware#2643. It has no effect until this is merged.Why there is no /dev/rtc0 today
"hisilicon,hi_rtc", whilertc-hibvtmatches"hisilicon,hi35xx-rtc". So even withCONFIG_RTC_DRV_HIBVT=y, nothing binds.rtc-hibvtis the right driver. The block at 0x12090000 is the SPI-bridged RTC thatrtc-hibvtdrives. The SDK'shi3516cv300RTC module uses the sameSPI_CLK_DIV/SPI_RWoffsets, the sameu_spi_rwbit layout and the same register map.hi3516cv300_rtc.ko, but it is a character device with privateHI_RTC_*ioctls. That is why pointing/dev/rtc0at it givesRTC_RD_TIME: Operation not permittedin the issue.Change
arm: dts: hi3516cv300: the RTC compatible becomes"hisilicon,hi35xx-rtc".rtc: hibvt:rtc-hibvt.cthis branch matches byte for byte. The read no longer fails while the low-voltage flag is set (the flag was "cleared" with the alarm bit, so it never cleared). A counter before 2000-01-01 is refused both ways, so a counter that lost power never sets the clock to 1970. The flag is cleared withLV_INT_MASK.ARCH_HI3516CV300, the driver no longer writesRTC_CLK_CFG. The SDK's own cv300 RTC driver never touches it, and it reads0x00on a running board. The0x01written here is the hi3536cv100 value.Verification
Lab hi3516cv300 (
hi3516cv300_lite, imx291, no backup battery). I built the kernel from OpenIPC/firmware#2643's config with these two commits on top, and U-Boot loaded it over TFTP. The NOR kernel was never written. Afterwards the board went back to its own kernel and original environment.Before, on the shipped kernel:
With this change, the first boot from power-on (the counter starts at zero with no battery):
Once userspace has set the time,
hwclockworks:Warm reboot. The RTC kept counting, and hctosys applies it:
30 s PoE cut. The counter restarts, and it is refused rather than set to 1970:
set_time()andread_time()agree:Not covered:
ARCH_HI3516CV300symbol, but wasn't run on hardware.Review fix:
set_time()errorshibvt_rtc_set_time()collected the SPI write results in anunsigned char, so a bridge timeout (-EIO) came back as251, andRTC_SET_TIMEreported success for a write that never reached the RTC (Qodo). It is now anint, like every other function in the file.The SPI timeout can't be triggered on demand, so the error path itself is covered only by the type fix. The success path was re-run on hardware:
That is the lab hi3516cv300 again, booted over TFTP on this branch's head and then returned to its own kernel.