-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(CLK)(RTC)(Stm32) Add RTC + STGEN support for stm32mpx platform + clk framework fix + RTC framework update #7184
base: master
Are you sure you want to change the base?
Conversation
Hello, @Upsylonbare, @Gabriel-Fernandz, can you review this P-R as well please? |
If this P-R seems too big, I can split it in 2. I kept it that way because STGEN is dependent on the RTC and is its only user on our platforms. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @GseoC,
Here is my first review !
core/include/drivers/stm32_rtc.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about not exporting the "private" stm32_rtc_calendar struct to other drivers but keep it inside stm32_rtc driver.
stm32_rtc_get_calendar() looks like a get_time() with subsecond feature.
A subsecond field could be added to the optee_rtc_time struct and the RTC framework could be extended with both stm32_rtc_diff_* functions from this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok to update and propagate the use of optee_rtc_time but the time_diff APIs are sepcific to our platforms. Let's see if what I've proposed suits what you have it mind
core/drivers/stm32_rtc.c
Outdated
31, 28, 31, 30, 31, 30, | ||
31, 31, 30, 31, 30, 31 | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this implementation does not well handle case where current
relates to a date lower ref
reference.
Maybe building a decimal value for both as done in rtc_timecmp()
(commit "drivers: rtc: add time comparison in RTC API") could help comparing most of the time values to help rejecting absolute time difference computation when argument do no match this constraint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about converting the struct optee_rtc_time
time capture into a 64bit elapsed milliseconds since year 0 (to make things simpler, even if not strictly applicable before... quite a while, let's say 1970) and simply substract them in stm32_rtc_diff_calendar_ms()
:
#define MS_PER_SEC ULL(1000)
#define MS_PER_MIN (ULL(60) * MS_PER_SEC)
#define MS_PER_HOUR (ULL(60) * MS_PER_MIN)
#define MS_PER_DAY (ULL(24) * MS_PER_HOUR)
/* 1970 is realistic, 2024 would be also. STM32 RTC supports 2000 */
#define YEAR_MIN 1970
/*
* Ensure 64bit millisecond data do not overflow.
* Compute 366 days/year for simplicity, still large enough.
* We also could use a quite realistic arbitrary value, like 3000 ;-)
*/
#define YEAR_MAX (ULLONG_MAX / 366 / MS_PER_DAY)
static uint64_t rtc_time_to_ms(struct optee_rtc_time *ref)
{
static const uint8_t month_len[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
static const uint8_t month_len_leap[] = {
31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
const uint8_t *month_days = NULL;
uint64_t time_ms = 0;
uint64_t days = 0;
uint64_t year = 0;
unsigned int n = 0;
if (!ref->tm_mday || !ref->tm_mon || ref->tm_year < YEAR_MIN ||
ref->tm_year > YEAR_MAX)
panic();
if (rtc_is_a_leap_year(ref->tm_year))
month_days = month_len_leap;
else
month_days = month_len;
/* Elapsed milliseconds since midnight */
time_ms = ref->tm_ms;
time_ms += ref->tm_sec * MS_PER_SEC;
time_ms += ref->tm_min * MS_PER_MIN;
time_ms += ref->tm_hour * MS_PER_HOUR;
/* Elapsed days in current month and in past months of current year */
days = ref->tm_mday - 1;
for (n = 0; n < ref->tm_mon - 1; n++)
days += month_days[n];
/* Elapsed days pasted years */
year = ref->tm_year - 1;
days += (year * 365) + (year / 4) + (year / 400) - (year / 100);
/* Accumulated the elapsed days */
time_ms += days * MS_PER_DAY;
return time_ms;
}
unsigned long long stm32_rtc_diff_calendar_ms(struct optee_rtc_time *cur,
struct optee_rtc_time *ref)
{
return rtc_time_to_ms(cur) - rtc_time_to_ms(ref);
}
unsigned long long stm32_rtc_diff_calendar_tick(struct optee_rtc_time *ref,
struct optee_rtc_time *cur,
unsigned long long tick_rate)
{
signed long long diff_ms = stm32_rtc_diff_calendar_ms(cur, ref);
signed long long res = 0;
if (diff_ms < 0 || MUL_OVERFLOW(diff_ms, tick_rate, &res))
return ULLONG_MAX;
return (unsigned long long)res;
}
dc4bb02
to
741d1b4
Compare
Updated with comments addressed. Given how much change there is, I didn't bother with commits on top. Let's start a "new" review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed-by: Etienne Carriere <[email protected]>
for commits:
- "dt-bindings: stm32: fix CLKSRC for RTC in stm32mp13 clock bindings"
- "plat-stm32mp1: conf: default enable the RTC driver",
- "plat-stm32mp2: conf: default enable the RTC driver",
- "dts: stm32: add RTC node in stm32mp251.dtsi",
- "dts: stm32: add STGEN node in stm32mp251.dtsi",
(with a change in the commit message: s/cortexA35/Cortex-A35/) - "plat-stm32mp2: conf: default enable STGEN for STM32MP2 platforms",
Could shorten header line: "plat-stm32mp2: conf: default embed STGEN driver".
Acked-by: Etienne Carriere <[email protected]>
for commit
"clk: stm32mp25: configure STGEN flexgen in .enable ops"
with the 2 comments addressed.
For commit "clk: fix clk_get_rate() when parent clock rate was changed", could you add few inline descriptions as those proposed in #7184 (comment) (they likely need some rephrasing)? I think the struct clk_ops
should also clarify that root clocks must implement .get_rate
operation handler.
Comments addressed and fixed some functional issues |
core/drivers/stm32_rtc.c
Outdated
31, 28, 31, 30, 31, 30, | ||
31, 31, 30, 31, 30, 31 | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about converting the struct optee_rtc_time
time capture into a 64bit elapsed milliseconds since year 0 (to make things simpler, even if not strictly applicable before... quite a while, let's say 1970) and simply substract them in stm32_rtc_diff_calendar_ms()
:
#define MS_PER_SEC ULL(1000)
#define MS_PER_MIN (ULL(60) * MS_PER_SEC)
#define MS_PER_HOUR (ULL(60) * MS_PER_MIN)
#define MS_PER_DAY (ULL(24) * MS_PER_HOUR)
/* 1970 is realistic, 2024 would be also. STM32 RTC supports 2000 */
#define YEAR_MIN 1970
/*
* Ensure 64bit millisecond data do not overflow.
* Compute 366 days/year for simplicity, still large enough.
* We also could use a quite realistic arbitrary value, like 3000 ;-)
*/
#define YEAR_MAX (ULLONG_MAX / 366 / MS_PER_DAY)
static uint64_t rtc_time_to_ms(struct optee_rtc_time *ref)
{
static const uint8_t month_len[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
static const uint8_t month_len_leap[] = {
31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
const uint8_t *month_days = NULL;
uint64_t time_ms = 0;
uint64_t days = 0;
uint64_t year = 0;
unsigned int n = 0;
if (!ref->tm_mday || !ref->tm_mon || ref->tm_year < YEAR_MIN ||
ref->tm_year > YEAR_MAX)
panic();
if (rtc_is_a_leap_year(ref->tm_year))
month_days = month_len_leap;
else
month_days = month_len;
/* Elapsed milliseconds since midnight */
time_ms = ref->tm_ms;
time_ms += ref->tm_sec * MS_PER_SEC;
time_ms += ref->tm_min * MS_PER_MIN;
time_ms += ref->tm_hour * MS_PER_HOUR;
/* Elapsed days in current month and in past months of current year */
days = ref->tm_mday - 1;
for (n = 0; n < ref->tm_mon - 1; n++)
days += month_days[n];
/* Elapsed days pasted years */
year = ref->tm_year - 1;
days += (year * 365) + (year / 4) + (year / 400) - (year / 100);
/* Accumulated the elapsed days */
time_ms += days * MS_PER_DAY;
return time_ms;
}
unsigned long long stm32_rtc_diff_calendar_ms(struct optee_rtc_time *cur,
struct optee_rtc_time *ref)
{
return rtc_time_to_ms(cur) - rtc_time_to_ms(ref);
}
unsigned long long stm32_rtc_diff_calendar_tick(struct optee_rtc_time *ref,
struct optee_rtc_time *cur,
unsigned long long tick_rate)
{
signed long long diff_ms = stm32_rtc_diff_calendar_ms(cur, ref);
signed long long res = 0;
if (diff_ms < 0 || MUL_OVERFLOW(diff_ms, tick_rate, &res))
return ULLONG_MAX;
return (unsigned long long)res;
}
Ok I'll rework and squash the part handling calendat diffs. |
Comments addressed and some more updates applied while squashing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed-by: Etienne Carriere <[email protected]>
for commits
"clk: fix clk_get_rate() when parent clock rate was changed",
"dt-bindings: stm32: fix CLKSRC for RTC in stm32mp13 clock bindings",
"plat-stm32mp1: conf: default enable the RTC driver",
"plat-stm32mp2: conf: default enable the RTC driver",
"dts: stm32: add RTC node in stm32mp251.dtsi",
"plat-stm32mp1: enable RTC framework if CFG_DRIVERS_RTC is set",
"plat-stm32mp2: enable RTC framework if CFG_DRIVERS_RTC is set",
"dts: stm32: add STGEN node in stm32mp251.dtsi" and
"plat-stm32mp2: conf: default enable STGEN for STM32MP2 platforms".
Acked-by: Etienne Carriere <[email protected]>
- for commit
"clk: stm32mp25: configure STGEN flexgen in .enable ops".
For commit "drivers: rtc: add time comparison in RTC API", some fixes needed in the commit message (otherwise, looks good to me):
- s/sub-second/millisecond/g
- The header line should rather be "drivers: rtc: add few helper functions".
Comments for commit "drivers: stm32_rtc: introduce STM32 RTC driver`"
and "drivers: counter: stm32_stgen: add STGEN driver".
Comments addressed and tags applied. Note that I've added drivers: rtc: add RTC_TIME help following your suggestion |
|
Fine with me. |
Comments addressed but I reworked the RTC framework patches to make some stm32_rtc functions generic. Let me know what you think of it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments for commits "drivers: rtc: add RTC functions and millisecond field"
and "drivers: stm32_rtc: check data consistency in rtc_set_time()".
Updated with conversion to signed APIs and minor comment addressed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For commit "driver: rtc: RTC_TIME help"
s/RTC_TIME help/RTC_TIME() helper macro/ (2 occurrences)
Updated with latest comments addressed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed-by: Etienne Carriere <[email protected]>
for commits
"drivers: stm32_rtc: check data consistency in rtc_set_time()" and
"drivers: rtc: add RTC_TIME() helper macro".
Typo in commit "drivers: stm32_rtc: introduce STM32 RTC driver" regarding the stm32_rtc device time range.
1 comment for commit "drivers: counter: stm32_stgen: add STGEN driver".
clk_get_rate() returns a cached value of the clock rate. If the rate of the parent clock changed, then the rate is not synchronized. Change the function to compute all clock parents' rates and return the synchronized value. Signed-off-by: Gabriel Fernandez <[email protected]> Signed-off-by: Gatien Chevallier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]> Fixes: 2305544 ("drivers: clk: add generic clock framework")
Bad copy/paste, use MUX ID to configure the clock source of RTC and not the clock ID. Signed-off-by: Gabriel Fernandez <[email protected]> Signed-off-by: Gatien Chevallier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]> Fixes: 19a4632 ("dt-bindings: stm32: add stm32mp13 clock and reset bindings")
b949f90
to
0cf4d79
Compare
Updated with latest comments addressed and tags applied. Note that I've added a patch on top to fix an undesired behavior in I also added a patch (drivers: atmel_rtc: fix and update RTC ranges) to update/fix Atmel RTC. @tprrt or @TonyHan11 , do you maintain these platform? If so, can you review this patch please? I just compiled |
Hi, I have a failed check on this series due a failed xtest 1006 with Qemu: It seems strange that this series impacts it, maybe there's something else behind it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed-by: Etienne Carriere <[email protected]>
for commit
"drivers: rtc: add RTC functions and millisecond field" with a suggestion on trace 2 messages trace level.
Acked-by: Etienne Carriere <[email protected]>
for commit
"drivers: atmel_rtc: fix and update RTC ranges".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For commit "drivers: counter: stm32_stgen: add STGEN driver": 1 last comment to address.
0cf4d79
to
1fe3ae1
Compare
Comments addressed and tags applied. I also moved code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra comment for commit "drivers: rtc: add RTC functions and millisecond field".
Reviewed-by: Etienne Carriere <[email protected]>
for commits
"drivers: stm32_rtc: introduce STM32 RTC driver" and
"drivers: counter: stm32_stgen: add STGEN driver".
Add a millisecond field in the optee_rtc_time structure. Add different APIs to manipulate optee_rtc_time structures: rtc_is_a_leap_year(): Detects if the given year is a leap year rtc_get_month_days(): Returns the number of day in the given month rtc_timecmp(): Compare two time captures rtc_diff_calendar_ms(): Returns the difference in milliseconds between two time captures rtc_diff_calendar_tick(): Returns the difference in number of ticks between two time captures Signed-off-by: Clément Le Goffic <[email protected]> Signed-off-by: Gatien Chevallier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
Add RTC_TIME() helper macro that allows to initialize all fields of a struct optee_rtc_time. Signed-off-by: Gatien Chevallier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
Ensure that arguments passed to rtc_set_time() are coherent to defined RTC range and Gregorian calendar values. Signed-off-by: Gatien Chevallier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
Use RTC_TIME() helper macro to initialize Atmel RTC ranges and fix its month and weekday values. Also add the milliseconds field even though it's not used. Signed-off-by: Gatien Chevallier <[email protected]> Acked-by: Etienne Carriere <[email protected]>
Driver interface allows to read date&time from RTC device, generate RTC timestamps and compute time delta between RTC date & time values. The RTC is a firewall-aware peripheral. It means that the RTC driver is in charge of configuring its own firewall restrictions and that the RTC has dedicated firewall configuration registers. The RTC provide APIs with time structure compatible with linux kernel driver. Signed-off-by: Gatien Chevallier <[email protected]> Signed-off-by: Clément Le Goffic <[email protected]> Signed-off-by: Lionel Debieve <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
Default enable the RTC driver support on stm32mp1 platforms. Signed-off-by: Gatien Chevallier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
Default enable the RTC driver support on stm32mp2 platforms. Signed-off-by: Gatien Chevallier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
Add the RTC node in stm32mp251.dtsi and default enable it. Signed-off-by: Gatien Chevallier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
If CFG_DRIVERS_RTC is enabled, force the compilation of the file core/drivers/rtc/rtc.c in order to share the generic functions. Signed-off-by: Gatien Chevallier <[email protected]> Signed-off-by: Clément Le Goffic <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
If CFG_DRIVERS_RTC is enabled, force the compilation of the file core/drivers/rtc/rtc.c in order to share the generic functions. Signed-off-by: Gatien Chevallier <[email protected]> Signed-off-by: Clément Le Goffic <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
STGEN flexgen is skipped during RCC probe to prevent misalignment between stgen_clk frequency and STGEN register. Configure the STGEN flexgen in the .enable ops so that it is configured after the STGEN itself is configured and started. Signed-off-by: Gatien Chevallier <[email protected]> Signed-off-by: Thomas Bourgoin <[email protected]> Acked-by: Etienne Carriere <[email protected]>
STGEN is the platform timer. It generates a time-count value that provides a consistent view of time for multiple processors and other blocks in a device. It is physically linked to the ARM generic timer. Add the STGEN driver that is in charge of configuring the ARM generic timer source and send an SMC to the BL31 monitor to update the CP15 register. This driver is only compatible for 64bits platforms. Signed-off-by: Gatien Chevallier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
Add the STGEN node in the stm32mp251.dtsi SoC device tree file and default enable it as it is the source for the ARM generic timer of the ARM cortexA35. Signed-off-by: Gatien Chevallier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
Default enable STGEN for STM32MP2 platforms. Signed-off-by: Gatien Chevallier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
1fe3ae1
to
af2c298
Compare
Last comments addressed and all tags applied, thanks |
(Core)
This P-R adds some functionnalities like time comparison or leap year detection in the RTC framework.
It also fixes the
clk_get_rate()
function in the clock framework.(STM32)
Add the Real-Time Clock (RTC) driver for both STM32MP1x and 2x platforms
Add the System Time GENerator (STGEN) driver for STM32MP2x platforms
This P-R has a dependency on https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/33853 because only the BL31 can update the ARMCP15 register on ARMv8A 64bits platforms. (merged)