I had problem to start receiving spi messages with the orin configured as spi slave using spi-tegra124-slave.c, complaining about not being able to configure the clock.
Looking at the code I saw this in tegra_spi_start_transfer_one :
speed = t->speed_hz ? t->speed_hz : spi->max_speed_hz;
/* Set slave controller clk 1.5 times the bus frequency */
if (!speed)
speed = spi->max_speed_hz;
The last two lines are useless, as the same test is also done above, with the same result.
Is there a typo in that block of code ? Should one of the βspiβ be βtspiβ ?
Simply replacing spi with tspi is insufficient: the inspected driverβs struct tegra_spi_data has no max_speed_hz member.
The clock calculation also appears to conflate the SPI bus-speed limit with the internal controller-clock limit. These should be reviewed separately.
Please provide:
β’ The exact clock-error message.
β’ Both controller and child-device DT nodes.
β’ The transferβs requested speed and measured external-master SCK frequency.
If the error is Cannot set requested clk freq, the ratio check above explains a likely failure mechanism. As a diagnostic, lower both the external master clock and requested
transfer speed while keeping the configured maximum unchanged. For example, a 5 MHz transfer with a 10 MHz configured maximum passes this particular check. This would help
distinguish the software limit check from an actual clock-provider failure.
I did not specify a frequency in my user-level listener client, thus setting the field βspeed_hzβ of the βstruct spi_ioc_transferβ to 0. My program failed immediately with EINVAL.
With βdmesgβ, I saw βCannot set requested clk freq XXXβ but I do not remember which XXX frequency was displayed.
To make my program work, I had to specify a low frequency in my user-program, but thatβs not an ideal situation as the frequency is chosen by the external master.
Thanksβthe DT and error message clarify the problem.
You are correct that the external master determines SCK. However, the slave driver still needs the expected maximum SCK frequency to configure its internal controller clock.
Setting speed_hz = 0 selects the configured default; it does not enable automatic clock-frequency detection.
The current implementation incorrectly couples two limits:
β’ The external SPI bus frequency.
β’ The internal controller clock, which must run faster than that bus frequency.
Your parent-node spi-max-frequency = <51000000> does not supply a separate internal-clock limit in the inspected implementation. Raising only the childβs maximum will also not fix
the default-speed case, because the default transfer speed rises with it.
The driver should retain the childβs bus-frequency limit and use a separate, validated controller-clock limit when calculating and checking core_speed.
Please confirm the external masterβs maximum SCK frequency. Avoid using an arbitrarily low userspace speed merely to bypass the check: the resulting internal clock could be
insufficient for the actual incoming SCK.
could you also clarify where in the device-tree for a spi-slave node we must put a βspi-max-frequencyβ property, and which value it must have for an Orin NX. I read in the TRM that the maximum frequency in master mode is 80 MHz, but 51 MHz in slave mode. Is that related to the 3/2 rule in spi-tegra124-slave.c ?
Here, 10000000 describes the intended maximum external SCK frequency for your planned 10 MHz connection. It does not configure the slaveβs internal clock directly. The inspected
driver does not read the parent-node spi-max-frequency as a separate controller-clock limit.
However, this DT change alone does not resolve the driver issue. With a 10 MHz child limit:
Likewise, leaving userspace speed_hz = 0 selects the default 10 MHz and reaches the failing case.
The driver therefore needs to distinguish the bus-frequency limit from the internal controller-clock limit. For nvidia,tegra186-spi-slave, it requests 2Γ the configured transfer
frequency to provide margin above the 1.5Γ minimum.
Regarding the TRMβs 80 MHz master and 51 MHz slave figures: these should not be treated as the internal core-clock limit or derived from each other using the 3/2 rule. The exact
TRM table and its timing conditions need checking. The softwareβs internal-clock ratio requirement and the interfaceβs maximum SCK specification are separate constraints.
At present, test with the actual 1 MHz master clock and explicitly request 1 MHz in userspace. The planned 10 MHz/default-speed case needs the clock-limit handling corrected and
validated.