-
Notifications
You must be signed in to change notification settings - Fork 5.2k
spi-bcm2708 may calculates wrong clock frequency if RPi2 is overclocked to 1Ghz. #974
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
Comments
If overclocking changes the core frequency, then you have to change the SPI clock in Device Tree. It should be possible to do this with a DT overlay. There is ongoing work to make it automatic: |
As I discovered with the sdhost driver, overclocking the VPU (core_freq) doesn't result in a fixed frequency unless you either use force_turbo or the performance governor; without these, the core frequency changes with ARM load. I'd be happy to tweak the firmware to patch the SPI clock frequency in DT, as it does for sdhost, but we may need to place some heavy caveats on using SPI while overclocking. |
Reading the firmware code, there is a core_freq_min parameter, which if kept equal to core_freq should allow the ARM frequency to change without affecting the SPI (and sdhost) clock. |
What is the exact problem? Is it the switching of the arm or core frequency when going from higher to lower frequency? Where is the critical code in spi-bcm2708. I have no experience with the kernel, but it would be interesting for me. Thanks |
When arm is busy it requests the arm clock is increased. If you leave core_freq at the default you shouldn't have any issues with spi. I believe we are saying that use of SPI is not compatible with overclocking of core_freq, because its clock is directly divided down from core_freq. If it turns out that spi is happy with clock changing (as long as it doesn't exceed some level), then that would be possible, but you would obviously get lower throughput when the arm (and hence core_freq) is not in turbo mode. core_freq_min can't exceed stock (250MHz), so probably is not useful. |
Weird thing in my case - RPi2 is overclocked using raspi-config RPi2 preset (including core_freq), force_turbo=1 is enabled. SPI works correctly - SCLK has the same clock frequency on the oscillator as specified in a transfer call (but I did not change the value in dtsi). |
|
http://community.emlid.com/t/ak8963-bad-device-id-error-during-ardupilot-start/267/46 |
@popcornmix thanks! I don't really understand what's going on, info in cpufreq differs from vngencmd. Here's what I have in config.txt:
And here is what cpufreq and vcgencmd output:
So if vngencmd is to be trusted, then my RPi2 isn't overclocked and that explains why SPI works fine in my case. But why isn't it overclocked and info in cpufreq differs? |
"vcgencmd measure_clock arm" is the definitive answer. It connects the clock to a counter and reports the count. It will always be correct. Seems force_turbo isn't enabled. Can you report output of |
Here it is:
|
That look okay. Are you sure you don't have an under voltage or over temperature warning (https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=82373) which would cause the overclock to be disabled? |
Ah, that's what was causing this. But in that case even if core_clock is specified in the dts SPI still may break when RPi decides to disable force_turbo. Are there any problems checking the core clock right before starting the transfer (would that be a big overhead?) ? |
Checking core_freq before starting the transfer doesn't really fix the issue. The clock can still change during the transfer. |
kernel: vcsm: Add ioctl for custom cache flushing firmware: arm_loader: Add new vpu+qpu multi execute api firmware: arm_loader: Set the SPI clock in DT to core_freq See: raspberrypi/linux#974
kernel: vcsm: Add ioctl for custom cache flushing firmware: arm_loader: Add new vpu+qpu multi execute api firmware: arm_loader: Set the SPI clock in DT to core_freq See: raspberrypi/linux#974
"The clock can still change during the transfer." --- bcm2835-cpufreq.c.old 2015-06-29 23:58:54.785712448 +0200 +DEFINE_MUTEX(bcm2835_cpufreq_chgclk);
|
Eric Arnholt has a proposal for a proper clock driver that controls the firmware clocks: With that in place, the SPI driver can clk_notifier_register() a callback to detect clock rate changes. This allows it to accept or reject the change. Example: cadence i2c driver clk callback: http://lxr.free-electrons.com/ident?i=cdns_i2c_clk_notifier_cb: Perhaps we could start to use his clock driver in rpi-4.1.y, even if it's not accepted upstream yet. |
Thanks for the info, sounds very promising .. |
I don't believe it's as simple as a mutex on the cpufreq driver. core freq can still change asynchronously to this. e.g. overclock is disabled on firmware side when over-temperature or under-voltage. We also have plans to trigger turbo mode form the gpu side when we know it is useful (e.g. MVC, 1080p60, 1080i60 with deinterlace). I think it's safest to assume that dynamic overclock is not supported when using hardware that is clocked from the core clock. |
Sure, I'm aware that this simple mutex protects against cpufreq-triggered core freq changes only. Then the interesting question is whether there's a way for the firmware to inform the new clock driver about such asynchronous clock changes. |
@dgrat has your issue been resolved? If so, please close this issue. Thanks. |
kernel: vcsm: Add ioctl for custom cache flushing firmware: arm_loader: Add new vpu+qpu multi execute api firmware: arm_loader: Set the SPI clock in DT to core_freq See: raspberrypi/linux#974
Closing due to lack of activity. Reopen if you feel this issue is still relevant. |
…h panic [ Upstream commit 06e629c ] In panic path, fadump is triggered via a panic notifier function. Before calling panic notifier functions, smp_send_stop() gets called, which stops all CPUs except the panic'ing CPU. Commit 8389b37 ("powerpc: stop_this_cpu: remove the cpu from the online map.") and again commit bab2623 ("powerpc: Offline CPU in stop_this_cpu()") started marking CPUs as offline while stopping them. So, if a kernel has either of the above commits, vmcore captured with fadump via panic path would not process register data for all CPUs except the panic'ing CPU. Sample output of crash-utility with such vmcore: # crash vmlinux vmcore ... KERNEL: vmlinux DUMPFILE: vmcore [PARTIAL DUMP] CPUS: 1 DATE: Wed Nov 10 09:56:34 EST 2021 UPTIME: 00:00:42 LOAD AVERAGE: 2.27, 0.69, 0.24 TASKS: 183 NODENAME: XXXXXXXXX RELEASE: 5.15.0+ VERSION: #974 SMP Wed Nov 10 04:18:19 CST 2021 MACHINE: ppc64le (2500 Mhz) MEMORY: 8 GB PANIC: "Kernel panic - not syncing: sysrq triggered crash" PID: 3394 COMMAND: "bash" TASK: c0000000150a5f80 [THREAD_INFO: c0000000150a5f80] CPU: 1 STATE: TASK_RUNNING (PANIC) crash> p -x __cpu_online_mask __cpu_online_mask = $1 = { bits = {0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} } crash> crash> crash> p -x __cpu_active_mask __cpu_active_mask = $2 = { bits = {0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} } crash> While this has been the case since fadump was introduced, the issue was not identified for two probable reasons: - In general, the bulk of the vmcores analyzed were from crash due to exception. - The above did change since commit 8341f2f ("sysrq: Use panic() to force a crash") started using panic() instead of deferencing NULL pointer to force a kernel crash. But then commit de6e5d3 ("powerpc: smp_send_stop do not offline stopped CPUs") stopped marking CPUs as offline till kernel commit bab2623 ("powerpc: Offline CPU in stop_this_cpu()") reverted that change. To ensure post processing register data of all other CPUs happens as intended, let panic() function take the crash friendly path (read crash_smp_send_stop()) with the help of crash_kexec_post_notifiers option. Also, as register data for all CPUs is captured by f/w, skip IPI callbacks here for fadump, to avoid any complications in finding the right backtraces. Signed-off-by: Hari Bathini <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sasha Levin <[email protected]>
…h panic [ Upstream commit 06e629c ] In panic path, fadump is triggered via a panic notifier function. Before calling panic notifier functions, smp_send_stop() gets called, which stops all CPUs except the panic'ing CPU. Commit 8389b37 ("powerpc: stop_this_cpu: remove the cpu from the online map.") and again commit bab2623 ("powerpc: Offline CPU in stop_this_cpu()") started marking CPUs as offline while stopping them. So, if a kernel has either of the above commits, vmcore captured with fadump via panic path would not process register data for all CPUs except the panic'ing CPU. Sample output of crash-utility with such vmcore: # crash vmlinux vmcore ... KERNEL: vmlinux DUMPFILE: vmcore [PARTIAL DUMP] CPUS: 1 DATE: Wed Nov 10 09:56:34 EST 2021 UPTIME: 00:00:42 LOAD AVERAGE: 2.27, 0.69, 0.24 TASKS: 183 NODENAME: XXXXXXXXX RELEASE: 5.15.0+ VERSION: #974 SMP Wed Nov 10 04:18:19 CST 2021 MACHINE: ppc64le (2500 Mhz) MEMORY: 8 GB PANIC: "Kernel panic - not syncing: sysrq triggered crash" PID: 3394 COMMAND: "bash" TASK: c0000000150a5f80 [THREAD_INFO: c0000000150a5f80] CPU: 1 STATE: TASK_RUNNING (PANIC) crash> p -x __cpu_online_mask __cpu_online_mask = $1 = { bits = {0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} } crash> crash> crash> p -x __cpu_active_mask __cpu_active_mask = $2 = { bits = {0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} } crash> While this has been the case since fadump was introduced, the issue was not identified for two probable reasons: - In general, the bulk of the vmcores analyzed were from crash due to exception. - The above did change since commit 8341f2f ("sysrq: Use panic() to force a crash") started using panic() instead of deferencing NULL pointer to force a kernel crash. But then commit de6e5d3 ("powerpc: smp_send_stop do not offline stopped CPUs") stopped marking CPUs as offline till kernel commit bab2623 ("powerpc: Offline CPU in stop_this_cpu()") reverted that change. To ensure post processing register data of all other CPUs happens as intended, let panic() function take the crash friendly path (read crash_smp_send_stop()) with the help of crash_kexec_post_notifiers option. Also, as register data for all CPUs is captured by f/w, skip IPI callbacks here for fadump, to avoid any complications in finding the right backtraces. Signed-off-by: Hari Bathini <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sasha Levin <[email protected]>
…h panic [ Upstream commit 06e629c ] In panic path, fadump is triggered via a panic notifier function. Before calling panic notifier functions, smp_send_stop() gets called, which stops all CPUs except the panic'ing CPU. Commit 8389b37 ("powerpc: stop_this_cpu: remove the cpu from the online map.") and again commit bab2623 ("powerpc: Offline CPU in stop_this_cpu()") started marking CPUs as offline while stopping them. So, if a kernel has either of the above commits, vmcore captured with fadump via panic path would not process register data for all CPUs except the panic'ing CPU. Sample output of crash-utility with such vmcore: # crash vmlinux vmcore ... KERNEL: vmlinux DUMPFILE: vmcore [PARTIAL DUMP] CPUS: 1 DATE: Wed Nov 10 09:56:34 EST 2021 UPTIME: 00:00:42 LOAD AVERAGE: 2.27, 0.69, 0.24 TASKS: 183 NODENAME: XXXXXXXXX RELEASE: 5.15.0+ VERSION: #974 SMP Wed Nov 10 04:18:19 CST 2021 MACHINE: ppc64le (2500 Mhz) MEMORY: 8 GB PANIC: "Kernel panic - not syncing: sysrq triggered crash" PID: 3394 COMMAND: "bash" TASK: c0000000150a5f80 [THREAD_INFO: c0000000150a5f80] CPU: 1 STATE: TASK_RUNNING (PANIC) crash> p -x __cpu_online_mask __cpu_online_mask = $1 = { bits = {0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} } crash> crash> crash> p -x __cpu_active_mask __cpu_active_mask = $2 = { bits = {0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} } crash> While this has been the case since fadump was introduced, the issue was not identified for two probable reasons: - In general, the bulk of the vmcores analyzed were from crash due to exception. - The above did change since commit 8341f2f ("sysrq: Use panic() to force a crash") started using panic() instead of deferencing NULL pointer to force a kernel crash. But then commit de6e5d3 ("powerpc: smp_send_stop do not offline stopped CPUs") stopped marking CPUs as offline till kernel commit bab2623 ("powerpc: Offline CPU in stop_this_cpu()") reverted that change. To ensure post processing register data of all other CPUs happens as intended, let panic() function take the crash friendly path (read crash_smp_send_stop()) with the help of crash_kexec_post_notifiers option. Also, as register data for all CPUs is captured by f/w, skip IPI callbacks here for fadump, to avoid any complications in finding the right backtraces. Signed-off-by: Hari Bathini <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sasha Levin <[email protected]>
…h panic [ Upstream commit 06e629c ] In panic path, fadump is triggered via a panic notifier function. Before calling panic notifier functions, smp_send_stop() gets called, which stops all CPUs except the panic'ing CPU. Commit 8389b37 ("powerpc: stop_this_cpu: remove the cpu from the online map.") and again commit bab2623 ("powerpc: Offline CPU in stop_this_cpu()") started marking CPUs as offline while stopping them. So, if a kernel has either of the above commits, vmcore captured with fadump via panic path would not process register data for all CPUs except the panic'ing CPU. Sample output of crash-utility with such vmcore: # crash vmlinux vmcore ... KERNEL: vmlinux DUMPFILE: vmcore [PARTIAL DUMP] CPUS: 1 DATE: Wed Nov 10 09:56:34 EST 2021 UPTIME: 00:00:42 LOAD AVERAGE: 2.27, 0.69, 0.24 TASKS: 183 NODENAME: XXXXXXXXX RELEASE: 5.15.0+ VERSION: raspberrypi#974 SMP Wed Nov 10 04:18:19 CST 2021 MACHINE: ppc64le (2500 Mhz) MEMORY: 8 GB PANIC: "Kernel panic - not syncing: sysrq triggered crash" PID: 3394 COMMAND: "bash" TASK: c0000000150a5f80 [THREAD_INFO: c0000000150a5f80] CPU: 1 STATE: TASK_RUNNING (PANIC) crash> p -x __cpu_online_mask __cpu_online_mask = $1 = { bits = {0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} } crash> crash> crash> p -x __cpu_active_mask __cpu_active_mask = $2 = { bits = {0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} } crash> While this has been the case since fadump was introduced, the issue was not identified for two probable reasons: - In general, the bulk of the vmcores analyzed were from crash due to exception. - The above did change since commit 8341f2f ("sysrq: Use panic() to force a crash") started using panic() instead of deferencing NULL pointer to force a kernel crash. But then commit de6e5d3 ("powerpc: smp_send_stop do not offline stopped CPUs") stopped marking CPUs as offline till kernel commit bab2623 ("powerpc: Offline CPU in stop_this_cpu()") reverted that change. To ensure post processing register data of all other CPUs happens as intended, let panic() function take the crash friendly path (read crash_smp_send_stop()) with the help of crash_kexec_post_notifiers option. Also, as register data for all CPUs is captured by f/w, skip IPI callbacks here for fadump, to avoid any complications in finding the right backtraces. Signed-off-by: Hari Bathini <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sasha Levin <[email protected]>
Get a fail of the init procedure if I overclock and use this SPI based driver with Raspbian.
https://github.com/diydrones/ardupilot/blob/master/libraries/AP_Compass/AP_Compass_AK8963.h
The text was updated successfully, but these errors were encountered: