Part Number: AM625
Hello TI,
I Hope you can help me with the following issue:
I have build a Driver for controlling Leds that can be chained together similiar to apa102 leds.
So My Driver works, with PIO but my kernel thread uses a lot of cycles, I wanted to switch to DMA but noticed an issue, if I look at my logic analyzer output i see that in PIO mode the data isn't nicely packed up but it's there all complete (sometimes a gap as the processor is probably interrupting the kernel process), and everything is all fine and good.
how ever when switching to DMA the stream of data has big gaps between transmissions and that gap is almost exactly 1 second give or take a few milliseconds.
I don't know why this is happening exactly and hope you can help me out.
The Driver is a framebuffer driver and a led driver,
I have setup the framebuffer driver to be memory mapable, and it uses a kernel thread that is triggerd by a timer every 33ms or so (to get a 30 packets per second roughtly)
This happens through the frame_timer_callback
which wakes up the frame_task (which is the frame_thread_fn)
The data is the coppied inside the rgbled_write(); into a private buffer which is used to encode the format for the data and then transmit it via spi.
this private buffer is allocated with devm_kzalloc()
the spi is setup with 8 bits per word and transmits a total of 248 bytes, it does transmit only is that an issue? did i maybe get my dmas setup wrong, it was very difficult to find the right numbers.
is it because i use a gpio as chip select?
/* thread */
static int frame_thread_fn(void *data) {
// struct kitt_fb_par *par = data;
set_freezable();
while (!kthread_should_stop()) {
try_to_freeze();
set_current_state(TASK_INTERRUPTIBLE);
schedule();
if (kthread_should_stop())
break;
/* do frame work */
if (led_spi)
rgbled_write(led_spi, (uint32_t *)videomemory, 60);
}
return 0;
}
static unsigned long setup_frame_thread(struct kitt_fb_par *par) {
pr_info("Setting up a frame thread.\n");
frame_thread = kthread_create(frame_thread_fn, par, "frame thread");
if(frame_thread) {
par->frame_task = frame_thread;
wake_up_process(frame_thread);
return 0;
}
pr_err("Could not create and run the frame thread.");
return -ENOMEM;
}
static int probe(..) {
..
hrtimer_init(&par->frame_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
par->frame_timer.function = frame_timer_callback;
hrtimer_start(&par->frame_timer, ms_to_ktime(33), HRTIMER_MODE_REL);
..
}
There are no error messages in dmesg log.
and the way i found the issue was around spi_sync() was by timing it with ktime()
further device info:
Linux version 6.6.138-7.2.0-devel (oe-user@oe-host) (aarch64-tdx-linux-gcc (GCC) 13.3.0, GNU ld (GNU Binutils) 2.42.0.20240723) #1 SMP PREEMPT Fri May 8 07:27:41 UTC 2026
Machine model: Toradex Verdin AM62 WB on Verdin Development Board
root@verdin-am62-15599560:~# tdx-info
Software summary
------------------------------------------------------------
Bootloader: U-Boot
Kernel version: 6.6.138-7.2.0-devel #1 SMP PREEMPT Fri May 8 07:27:41 UTC 2026
Kernel command line: root=PARTUUID=076c4a2a-01 ro rootwait console=tty1 console=ttyS2,115200 no_console_suspend rauc.slot=A
Distro name: NAME="TDX Wayland with XWayland"
Distro version: VERSION_ID=7.2.0-devel-20251204100250-build.0
Distro variant: -
Hostname: verdin-am62-15599560
------------------------------------------------------------
Hardware info
------------------------------------------------------------
HW model: Toradex Verdin AM62 WB on Verdin Development Board
Toradex version: 0072 V1.2A
Serial number: 15599560
Processor arch: aarch64
------------------------------------------------------------
root@verdin-am62-15599560:~#
root@verdin-am62-15599560:~# cat /sys/kernel/debug/dmaengine/summary
dma0 (485c0100.dma-controller): number of channels: 48
dma0chan0 | 2b00000.audio-controller:tx (MEM_TO_DEV, tchan0 [0x2000 -> 0xc500], PDMA[ ACC32 BURST ], TR mode)
dma0chan1 | 2b00000.audio-controller:rx (DEV_TO_MEM, rchan6 [0x4500 -> 0xa006], PDMA[ ACC32 BURST ], TR mode)
dma0chan2 | in-use (MEM_TO_MEM, bchan0)
dma1 (485c0000.dma-controller): number of channels: 35
dma1chan0 | 20110000.spi:rx0 (DEV_TO_MEM, rchan0 [0x4304 -> 0x9000], rflow0, PDMA, Packet mode)
dma1chan1 | 20110000.spi:tx0 (MEM_TO_DEV, tchan0 [0x1000 -> 0xc304], tflow0, PDMA, Packet mode)
dma1chan2 | 40900000.crypto:rx1 (DEV_TO_MEM, rchan22 [0x7506 -> 0x9016], rflow43, PSI-L Native[ EPIB PSDsize:64 ], Packet mode)
dma1chan3 | 40900000.crypto:rx2 (DEV_TO_MEM, rchan23 [0x7507 -> 0x9017], rflow44, PSI-L Native[ EPIB PSDsize:64 ], Packet mode)
dma1chan4 | 40900000.crypto:tx (MEM_TO_DEV, tchan28 [0x101c -> 0xf501], tflow91, PSI-L Native[ EPIB PSDsize:64 ], Packet mode)
root@verdin-am62-15599560:~#
this is in my devicetree for the spi device:
&main_spi1 {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
dmas = <&main_pktdma 0xC304 0>, <&main_pktdma 0x4304 0>;
dma-names = "tx0", "rx0";
sparkled: spark-led@0 {
compatible = "wurth,spark-led";
reg = <0>;
spi-max-frequency = <115264>;
num-cs = <1>;
cs-gpios = <&main_gpio1 93 GPIO_ACTIVE_HIGH>;
spi-cs-high;
vled-supply = <®_V5V0_LED>;
};
};
Hopefully you can help me in the right direction or have any ideas why this might happen