-
Notifications
You must be signed in to change notification settings - Fork 6.6k
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
Enable LPSPI RTIO Support #62057
Enable LPSPI RTIO Support #62057
Conversation
c29c69c
to
658d54e
Compare
Probably should also add the VMU_RT1170 to the test. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unclear if this works in an asynchronous (event driven) way as would be expected, some clarification is needed
drivers/spi/spi_mcux_lpspi.c
Outdated
rx.count = 1; | ||
|
||
transceive(dev, &dt_spec->config, &tx, &rx, 0, 0, 0); | ||
if (ret == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when would this not be 0? It seems like this implies a blocking flow at all times.
What should happen is the transceive above should be asynchronously started here and upon completion the next transceive started.
Or maybe better is the entire transaction is loaded into a hardware queue and started asynchronously, then upon completion things are marked as such.
The only reason this is a blocking operation in the sam driver for small transfers is that it effectively needs to spin tightly on writing/reading out to the spi tx/rx registers... because of the way the IP works without any sort of sensible hardware FIFO available. Doing that with interrupts enabled caused SPI to behave incorrectly. It's a uniquely sam spi issue. LPSPI shouldn't have any of these problems from what I understand of the IP block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, driver should enable dma and spi async if using rtio and call transceive_dma with asynchronous=1 here instead of regular blocking transceive
edit: looks like this driver was never supported with async+dma, so in this case only async is necessary for RTIO, not necessarily DMA, if that is not the focus of this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m working on adding polling support as well, so if for small transfers it makes more sense to have a tight poll loop, rtio will be able to support that. It should fix the Sam spi issue as well.
for larger transfers dma or peripheral fifos are of course going to be much better.
@@ -19,4 +19,18 @@ config SPI_MCUX_LPSPI_DMA | |||
help |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add also default y if SPI_RTIO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and maybe select SPI_ASYNC if SPI_RTIO
otherwise it seems like the spi_wait_for_completion
will block no matter what
drivers/spi/spi_mcux_lpspi.c
Outdated
} | ||
|
||
spi_context_cs_control(&data->ctx, true); | ||
spi_context_cs_control(&data->ctx, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why these switch on/off of the CS line?
and why the spi_mcux_configure() call, since it's already called below at line 520 ?
Fidally, how these changes fit with RTIO addition in this driver?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, I don't know where this came from, I have removed this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI you just pushed and it's not removed dont know if it's intentional
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you again, it is now removed.
658d54e
to
40d0310
Compare
I have now added this to the testcase.yaml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a race in the submit call that needs correcting
Please carefully look over the way submit is written for the sam spi driver and replicate the structure there for now.
https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/spi/spi_sam.c#L685
Note that a spin lock is taken (serialized single consumer of the request queue), checks if there's ongoing work. If no work is ongoing then pop and start, otherwise do nothing.
struct spi_mcux_data *data = dev->data; | ||
struct rtio_mpsc_node *next = rtio_mpsc_pop(&data->iodev.iodev_sq); | ||
|
||
if (next != NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
next needs to be serialized in a spin lock as it is in the sam driver
It also needs to verify there's no ongoing current work before popping and starting the next thing on the queue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wondered about that, but when the LPSPI driver reaches the transceive function, would this not stop the race condition?
https://github.com/zephyrproject-rtos/zephyr/blob/9686f6e000c746538ec7ab78f6d8abf299d24e95/drivers/spi/spi_mcux_lpspi.c#L488C1-L488C1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wondered about that, but when the LPSPI driver reaches the transceive function, would this not stop the race condition?
looks like it would not, a lot of data is already read and changed before getting to this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you both, I have fixed this and there should no longer be a race condition.
cb51bde
to
fdb807f
Compare
drivers/spi/spi_mcux_lpspi.c
Outdated
int ret = 0; | ||
|
||
switch (sqe->op) { | ||
case RTIO_OP_TX: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be mixing transmit and receive in the same spi_buf setup which looks a bit wrong to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should no longer be the case.
fdb807f
to
066ca93
Compare
&transfer); | ||
spi_spin_unlock(dev, key); | ||
if (status != kStatus_Success) { | ||
LOG_ERR("Transfer could not start"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rtio_iodev_sqe_err(txn_head, -EIO); or something likely needed here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
understood, added this call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool!
9a637d6
9a637d6
to
0a305d6
Compare
@@ -19,4 +19,18 @@ config SPI_MCUX_LPSPI_DMA | |||
help | |||
Enable the SPI DMA mode for SPI instances | |||
that enable dma channels in their device tree node. | |||
|
|||
if SPI_RTIO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could have a "depends on SPI_RTIO instead of such if/endif.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the if/endif is more scalable syntax
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you help me understand the advantage of "depends on" over "if/endif"?
Perhaps I missed something here.
0a305d6
to
63de139
Compare
Added Kconfig that switches RTIO Support in the LPSPI driver. Signed-off-by: Emilio Benavente <emilio.benavente@nxp.com>
Provided APIs to support RTIO with the LPSPI driver. Signed-off-by: Emilio Benavente <emilio.benavente@nxp.com>
Added an overlay file for mimxrt1170_evk_cm33 to test rtio with the spi_loopback test. Added mimxrt1170_evk_cm7 to the testcase.yml file Signed-off-by: Emilio Benavente <emilio.benavente@nxp.com>
63de139
to
25204ef
Compare
@tbursztyka any remaining issues still? it would be nice to have at least two parts supporting this API to further validate it, and I'd love to use something other than a sam e70 :-) Thanks! |
@tbursztyka, can you return to this PR to see if @EmilioCBen has addressed your change request? We would like to get this merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs maintainer approval but refreshing my +1
@tbursztyka please review the changes to determine if your requests have been dealt with |
Tested with the mimxrt1170_evk_cm7 using the tests/spi/spi_loopback test.