Originally, when the timer's source clock is 32.768 kHz, the timer driver
uses two consecutive reads to ensure the timer reading is correct.
However, it is not robust enough due to an asynchronous timing issue in
the chip. The workaround is to add at least two NOPs between the
LDR and CMP instructions. This commit implements the workaround in the
assembly code to ensure it is not affected by the compiler toolchain
or optimization flags.
Signed-off-by: Jun Lin <CHLin56@nuvoton.com>
Add missing braces to comply with MISRA C:2012 Rule 15.6 and
also following Zephyr's style guideline.
Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
The timer driver doesn't annouce/set the timeout at the tick boundary
but at the absolute next expiration time.
It will cause the accumatlation of the tick drift and cannot pass the
kernel/timer/timer_behavior test suite.
This commit fixes the tick drift problem by annouce the time at the tick
bouandry.
Fixes#59594
Signed-off-by: Jun Lin <CHLin56@nuvoton.com>
Timer "drivers" do not use the device model infrastructure, they are
singletons with a SYS_INIT call. This means they do not have to include
device.h but init.h. Things worked because device.h includes init.h.
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
The init infrastructure, found in `init.h`, is currently used by:
- `SYS_INIT`: to call functions before `main`
- `DEVICE_*`: to initialize devices
They are all sorted according to an initialization level + a priority.
`SYS_INIT` calls are really orthogonal to devices, however, the required
function signature requires a `const struct device *dev` as a first
argument. The only reason for that is because the same init machinery is
used by devices, so we have something like:
```c
struct init_entry {
int (*init)(const struct device *dev);
/* only set by DEVICE_*, otherwise NULL */
const struct device *dev;
}
```
As a result, we end up with such weird/ugly pattern:
```c
static int my_init(const struct device *dev)
{
/* always NULL! add ARG_UNUSED to avoid compiler warning */
ARG_UNUSED(dev);
...
}
```
This is really a result of poor internals isolation. This patch proposes
a to make init entries more flexible so that they can accept sytem
initialization calls like this:
```c
static int my_init(void)
{
...
}
```
This is achieved using a union:
```c
union init_function {
/* for SYS_INIT, used when init_entry.dev == NULL */
int (*sys)(void);
/* for DEVICE*, used when init_entry.dev != NULL */
int (*dev)(const struct device *dev);
};
struct init_entry {
/* stores init function (either for SYS_INIT or DEVICE*)
union init_function init_fn;
/* stores device pointer for DEVICE*, NULL for SYS_INIT. Allows
* to know which union entry to call.
*/
const struct device *dev;
}
```
This solution **does not increase ROM usage**, and allows to offer clean
public APIs for both SYS_INIT and DEVICE*. Note that however, init
machinery keeps a coupling with devices.
**NOTE**: This is a breaking change! All `SYS_INIT` functions will need
to be converted to the new signature. See the script offered in the
following commit.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
init: convert SYS_INIT functions to the new signature
Conversion scripted using scripts/utils/migrate_sys_init.py.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
manifest: update projects for SYS_INIT changes
Update modules with updated SYS_INIT calls:
- hal_ti
- lvgl
- sof
- TraceRecorderSource
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
tests: devicetree: devices: adjust test
Adjust test according to the recently introduced SYS_INIT
infrastructure.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
tests: kernel: threads: adjust SYS_INIT call
Adjust to the new signature: int (*init_fn)(void);
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Change automated searching for files using "IRQ_CONNECT()" API not
including <zephyr/irq.h>.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
In order to bring consistency in-tree, migrate all drivers to the new
prefix <zephyr/...>. Note that the conversion has been scripted, refer
to #45388 for more details.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
The function npcx_clock_get_sleep_ticks is currently guarded by
CONFIG_PM && CONFIG_NPCX_PM_TRACE. The other codes guarded by
CONFIG_NPCX_PM_TRACE is used to trace and will print a lot of messages.
The user who wants to use npcx_clock_get_sleep_ticks has to enable this
flag and get a lot of console spam. This commit removes the guard
CONFIG_NPCX_PM_TRACE and makes this function is available when
CONFIG_PM is defined.
Signed-off-by: Jun Lin <CHLin56@nuvoton.com>
Rename CONFIG_SOC_POWER_MANAGEMENT_TRACE to CONFIG_NPCX_PM_TRACE so that
it is clear that it's a NPCX specific option.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
In npcx_itim_evt_isr, it updates the cyc_sys_announced variable and
then calls sys_clock_announce() to update the kernel curr_tick variable.
If an ISR handler with higher priority preempts the timer ISR after the
sys_clock_announce is updated and before the sys_clock_announce() is
called, it will read the wrong time when calling k_uptime_get() because
the cyc_sys_announced and the curr_tick are not synchronized.
The commit fixes the problem by raising the timer's interrupt priority
to the highest one (i.e. 1 in npcx's configuration).
This commit also moves the computation of the delta cycle inside the
spinlock in sys_clock_elapsed() to prevent another potential racing
condition.
Signed-off-by: Jun Lin <CHLin56@nuvoton.com>
Signed-off-by: Wealian Liao <WHLIAO@nuvoton.com>
The init responsibility moves to the drivers themselves. The npcx itim
initialize doesn't work now. This adds timer initialization for npcx
itim to fix it.
Signed-off-by: Wealian Liao <WHLIAO@nuvoton.com>
The weak symbol sys_clock_driver_init has been removed, therefore moving
the init responsability to the drivers themselves. As a result, the init
function has now been made static on all drivers and moved to the
bottom, following the convention used in other areas.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This change adds `k_cycle_get_64()` on platforms that
support a 64-bit cycle counter.
The interface functions `arch_k_cycle_get_64()` and
`sys_clock_cycle_get_64()` are also introduced.
Fixes#39934
Signed-off-by: Christopher Friedt <chrisfriedt@gmail.com>
Convert the various device_get_binding() calls used to get the device
clock node to use DEVICE_DT_GET. The latter is processed at link time,
so it should be a bit more efficient.
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
In npcx series, we use ITIM64 as system kernel timer. Its source clock
frequency must equal to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC. This CL
added check during initialization to prevent ambiguous condition.
Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
During polling ITEN bit to make sure ITIM timer is enabled, we might
have the chance that npcx_itim_evt_enable() return fake error when
timeout expired but ITEN bit is set already if CONFIG_ZERO_LATENCY_IRQS
is enabled. (Since SVCall's interrupt priority is not the highest, the
other interrupts with IRQ_ZERO_LATENCY flag could preempt CPU resource
at this moment.)
In order to prevent return fake error code, this CL adjusts the check
conditions for ITEN bit and timeout.
Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
This is another API that is being used in all timer drivers and is not
internal to the clock subsystem. Remove the leading z_ and make promote
it to a cross-subsystem API.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The clock/timer APIs are not application facing APIs, however, similar
to arch_ and a few other APIs they are available to implement drivers
and add support for new hardware and are documented and available to be
used outside of the clock/kernel subsystems.
Remove the leading z_ and provide them as clock_* APIs for someone
writing a new timer driver to use.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Use timeout mechanism instead of unbounded loop during enabling ITIM32
module which source clock is LFCLK (32KHz).
Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
This CL introduces power management driver that improves the efficiency
of ec operation by adjusting the chip’s power consumption to the level
of activity required by the application in npcx series.
The following list summarizes the main properties of the various chip
power states. Please refer the power.c file for more detail.
Main power states in npcx series include:
- Active: Core, RAM and modules operate at the clocks generated by PLL.
- Idle: Enter this state when the Core executes WFI or WFE instruction.
- Sleep: clock is stopped for most of modules but PLL is enabled.
- Deep Sleep: As Sleep mode but PLL is disabled.
- Standby: All power rails are turned off besides standby and battery
power rails.
And this CL implements one power state, PM_STATE_SUSPEND_TO_IDLE, with
two sub-states for Zephyr power management system.
Sub-state 0 - "Deep Sleep" mode with “Instant” wake-up if residency
time is greater or equal to 1 ms
Sub-state 1 - "Deep Sleep" mode with "Standard" wake-up if residency
time is greater or equal to 201 ms
Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
This CL introduces a kernel device driver implemented by the internal
64/32-bit timers in Nuvoton NPCX series. Via these two kinds of timer,
the driver provides an standard "system clock driver" interface.
It includes:
- A system timer based on an ITIM64 (Internal 64-bit timer) instance,
clocked by APB2 which freq is CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC.
- Its prescaler is set to 1 and provide the kernel cycles reading
without handling overflow mechanism.
- A event timer based on an ITIM32 (Internal 32-bit timer) instance,
clocked by LCLK which frequency is 32KHz and still activated when ec
entered "idle/deep idle" power state for better power consumption.
- Its prescaler is set to 1 and provide timeout event mechansim.
- Compensate system timer which clock is gating for better power
consumption after ec left"idle/deep idle" power state.
This CL passed starve, timer_api, and timer_monotonic test suites.
Signed-off-by: Mulin Chao <mlchao@nuvoton.com>