|
| 1 | +# SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | + |
| 3 | +# Config for Raspberry Pi used as a bitbang adapter. |
| 4 | +# https://www.raspberrypi.com/documentation/computers/raspberry-pi.html |
| 5 | + |
| 6 | +# Supports all models with 40-pin or 26-pin GPIO connector up to Raspberry Pi 4 B |
| 7 | +# also supports Raspberry Pi Zero, Zero W and Zero 2 W. |
| 8 | + |
| 9 | +# Adapter speed calibration is computed from cpufreq/scaling_max_freq. |
| 10 | +# Adjusts automatically if CPU is overclocked. |
| 11 | + |
| 12 | +adapter driver bcm2835gpio |
| 13 | + |
| 14 | +proc read_file { name } { |
| 15 | + if {[catch {open $name r} fd]} { |
| 16 | + return "" |
| 17 | + } |
| 18 | + set result [read $fd] |
| 19 | + close $fd |
| 20 | + return $result |
| 21 | +} |
| 22 | + |
| 23 | +proc measure_clock {} { |
| 24 | + set result [exec vcgencmd measure_clock arm] |
| 25 | + set clock_hz [lindex [split $result "="] 1] |
| 26 | + expr { $clock_hz / 1000 } |
| 27 | +} |
| 28 | + |
| 29 | +proc get_max_cpu_clock { default } { |
| 30 | + set clock [read_file /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq] |
| 31 | + if { $clock > 100000 } { |
| 32 | + return $clock |
| 33 | + } |
| 34 | + |
| 35 | + # cpufreq not available. As the last resort try Broadcom's proprietary utility |
| 36 | + if {![catch measure_clock clock] && $clock > 100000} { |
| 37 | + return $clock |
| 38 | + } |
| 39 | + |
| 40 | + echo "WARNING: Host CPU clock unknown." |
| 41 | + echo "WARNING: Using the highest possible value $default kHz as a safe default." |
| 42 | + echo "WARNING: Expect JTAG/SWD clock significantly slower than requested." |
| 43 | + |
| 44 | + return $default |
| 45 | +} |
| 46 | + |
| 47 | +set compat [read_file /proc/device-tree/compatible] |
| 48 | +set clocks_per_timing_loop 4 |
| 49 | + |
| 50 | +if {[string match *bcm2711* $compat]} { |
| 51 | + set speed_offset 52 |
| 52 | +} elseif {[string match *bcm2837* $compat] || [string match *bcm2710* $compat]} { |
| 53 | + set speed_offset 34 |
| 54 | +} elseif {[string match *bcm2836* $compat] || [string match *bcm2709* $compat]} { |
| 55 | + set speed_offset 36 |
| 56 | +} elseif {[string match *bcm2835* $compat] || [string match *bcm2708* $compat]} { |
| 57 | + set clocks_per_timing_loop 6 |
| 58 | + set speed_offset 32 |
| 59 | +} else { |
| 60 | + set speed_offset 32 |
| 61 | + echo "WARNING: Unknown type of the host SoC. Expect JTAG/SWD clock slower than requested." |
| 62 | +} |
| 63 | + |
| 64 | +set clock [get_max_cpu_clock 2000000] |
| 65 | +set speed_coeff [expr { $clock / $clocks_per_timing_loop }] |
| 66 | + |
| 67 | +# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET |
| 68 | +# The coefficients depend on system clock and CPU frequency scaling. |
| 69 | +bcm2835gpio speed_coeffs $speed_coeff $speed_offset |
| 70 | + |
| 71 | +transport select swd |
| 72 | +adapter gpio swclk -chip 0 27 |
| 73 | +adapter gpio swdio -chip 0 22 |
| 74 | + |
0 commit comments