Because soc device is not ready when sysctr probes, so directly use
smccc to get soc version. For i.MX95 B0, no need to quirk to workaround
the system counter issue.
Reviewed-by: Jacky Bai <ping.bai@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Acked-by: Jason Liu <jason.hui.liu@nxp.com>
With gplay test[1] together with system suspend/resume, linux sometimes
stuck with all 6 A55 cores in cpuidle. It is the broadcast timer not
trigger interrupt, although set_next_event set the experied time.
In set_next_event:
write CMP_CR to disable CMP EVENT
write CMP_HI
write CMP_LO
write CMP_CR to enable CMP EVENT (a)
After step (a) CMP_HI value was unexpected changed to a very large value.
So broadcast timer interrupt not trigger in time.
Per HW team:
CR 101100 -> Writing to CR can end up updating to HI/LO or address 0x0
HI 100100 -> Writing to HI can end up updating LO or 0x0.
LO 100000 -> Writing to LO can end up updating 0x0.
register address 0x0 is write ignored, so no need handle it.
The fix for errata ERR052268 is:
before the upper step (a), disable sysctr interrupt
after upper step a:
write CMP_HI, in case step (a) wrongly updates CMP_HI
write CMP_LO, in case step (a) or updating CMP_HI wrongly updates CMP_LO
read back CMP_HI and CMP_LO to check, but this should always be correct
value.
enable sysctr interrupt.
Because step (a) may wrongly update CMP_HI and CMP_LO, so need disable
interrupt to avoid interrupt firing immediately.
[1]:
gst-launch-1.0 videotestsrc ! waylandsink window-width=800
window-height=600 > /dev/null &
while true; do glmark2-es2-wayland > /dev/null; done &
Reviewed-by: Ranjani Vaidyanathan <ranjani.vaidyanathan@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
To i.MX95 System counter module, we use Read register space to get
the counter, not the Control register space to get the counter, because
System Manager firmware not allow Linux to read Control register space.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Acked-by: Nitin Garg <nitin.garg_3@nxp.com>
Allow imx system counter timer driver to be loaded as a module.
Signed-off-by: Jindong <jindong.yue@nxp.com>
Change-Id: Iad43c71a955fe806649ad317b3642470803fb9ea
The previous hardware design embedds a internal divider for base clock.
New design not has that divider, so check the nxp,no-divider property,
if true, directly use base clock input, otherwise divide by 3 as before.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Link: https://lore.kernel.org/r/20220902111207.2902493-3-peng.fan@oss.nxp.com
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Per the Documentation,
IRQF_IRQPOLL is used for polling (only the interrupt that is registered
first in a shared interrupt is considered for performance reasons)
But this timer is not sharing interrupt line with others, and
actually irqpoll not work with this timer with IRQF_IRQPOLL set, so
drop the flag.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Link: https://lore.kernel.org/r/20211214120737.1611955-2-peng.fan@oss.nxp.com
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
The syctr interrupt could set the affinity to any cores in the
SoC. However, the default affinity is set to cpu 0.
This timer will be used as broadcast timer on all the i.MX
SoCs. Because DYNIRQ flag is set, the core time framework will runtime
set the interrupt affinity to the cores that needs to wake up and the
cpumask will runtime set to the core that will be wake up. So even the
sysctr initialization use cpumask 0, there is no issue, the current
patch is just use cpu_possible_mask to show the fact that the timer
supports routed to all the cpu cores and nothing else.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Link: https://lore.kernel.org/r/20211201125030.2307746-2-peng.fan@oss.nxp.com
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
The variables 'sys_ctr_base' and 'cmpcr' are not be updated after
init, so mark them as __ro_after_init.
Cc: Kees Cook <keescook@chromium.org>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20211201125030.2307746-1-peng.fan@oss.nxp.com
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
The system counter block guide states that the base clock is
internally divided by 3 before use, that means the clock input of
system counter defined in DT should be base clock which is normally
from OSC, and then internally divided by 3 before use.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
The system counter (sys_ctr) is a programmable system counter
which provides a shared time base to the Cortex A15, A7, A53 etc cores.
It is intended for use in applications where the counter is always
powered on and supports multiple, unrelated clocks. The sys_ctr hardware
supports:
- 56-bit counter width (roll-over time greater than 40 years)
- compare frame(64-bit compare value) contains programmable interrupt
generation when compare value <= counter value.
[dlezcano] Fixed over 80 chars length warning
Signed-off-by: Bai Ping <ping.bai@nxp.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>