From c044f5d0c4dee0fb83551e92a97d20e59a07cb6a Mon Sep 17 00:00:00 2001 From: Richard Oliver Date: Tue, 16 Dec 2025 14:54:05 +0000 Subject: [PATCH 1/2] spi: rp2040-gpio-bridge: Grow MAX_TRANSFER_SIZE Increase the maximum SPI transfer size from an arbitrary 1 MiB to ~4 MiB (the amount of data that can be referenced by a single manifest). Signed-off-by: Richard Oliver --- drivers/spi/spi-rp2040-gpio-bridge.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-rp2040-gpio-bridge.c b/drivers/spi/spi-rp2040-gpio-bridge.c index 304e34f1dbf227..ab6349c9e15c0d 100644 --- a/drivers/spi/spi-rp2040-gpio-bridge.c +++ b/drivers/spi/spi-rp2040-gpio-bridge.c @@ -31,10 +31,19 @@ #define RP2040_GBDG_BLOCK_SIZE (RP2040_GBDG_FLASH_BLOCK_SIZE - MD5_SUFFIX_SIZE) /* - * 1MiB transfer size is an arbitrary limit * Max value is 4173330 (using a single manifest) + * + * Internal page-size is 8KiB - 9 = 8183 bytes + * Manifests address data by a series of 16-byte MD5 sums (following a 16-byte + * manifest header) + * + * Max permissible data using a single manifest: + * 8183 * (8183//16 - 1) = 4173330 + * + * CMD_DAT_EMIT in fast_xfer/bypass_cache mode could potentially allow a max + * transfer size of 4GiB, but this is not currently implemented. */ -#define MAX_TRANSFER_SIZE (1024U * ONE_KIB) +#define MAX_TRANSFER_SIZE 4173330 #define HALF_BUFFER (4U * ONE_KIB) From da7f1f55a01b1c1ec90955b8d86d28dbf833ae32 Mon Sep 17 00:00:00 2001 From: Richard Oliver Date: Tue, 16 Dec 2025 15:23:59 +0000 Subject: [PATCH 2/2] media: i2c: imx500: Allow larger SPI transfers Remove the arbitrary 1 MiB transfer limit from imx500_spi_write() as the 1 MiB chunk limitation for firmware / network transfers is already upheld by imx500_state_transition(). This allows for larger input tensors to be injected via imx500_inject_input_tensor() (where there is no 1 MiB chunk limitation). Increase the number of poll attempts whilst waiting for the injection handshake register to be TRANS_COMP to allow more time for the checksum of larger input tensors to be calculated. Alter error messages in imx500_inject_input_tensor() so that imx500_spi_write() and imx500_injection_wait_transfer_complete() errors may be more easily differentiated. Signed-off-by: Richard Oliver --- drivers/media/i2c/imx500.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/imx500.c b/drivers/media/i2c/imx500.c index 60f3b0eef62195..c5a0e1d1491bb6 100644 --- a/drivers/media/i2c/imx500.c +++ b/drivers/media/i2c/imx500.c @@ -1937,7 +1937,7 @@ static void imx500_clear_fw_network(struct imx500 *imx500) static int __must_check imx500_spi_write(struct imx500 *state, const u8 *data, size_t size) { - if (size % 4 || size > ONE_MIB) + if (size % 4) return -EINVAL; if (!state->spi_device) @@ -1957,7 +1957,7 @@ static int imx500_injection_wait_transfer_complete(struct imx500 *imx500) /* Continue polling until we reach the final TRANS_COMP state */ while (hndsk_reg.val != IMX500_DD_DAT_INJECTION_HNDSK_TRANS_COMP) { - ret = imx500_poll_status_reg(imx500, &hndsk_reg, 5); + ret = imx500_poll_status_reg(imx500, &hndsk_reg, 10); if (ret) { dev_err(&client->dev, "Handshake register did not update from state %llu\n", @@ -2085,7 +2085,7 @@ static int imx500_inject_input_tensor(struct imx500 *imx500, const u32 *data, ret = imx500_injection_wait_transfer_complete(imx500); if (ret) { - dev_err(&client->dev, "SPI transfer of input tensor failed\n"); + dev_err(&client->dev, "Input tensor transfer failed to complete\n"); return ret; }