-
Notifications
You must be signed in to change notification settings - Fork 6.9k
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
[RFC] Introduce MIPI DBI driver class #64587
[RFC] Introduce MIPI DBI driver class #64587
Conversation
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.
Overall it looks really good, please address the potential issue with the GPIO polarity properties :)
DNM'ing for now, since it's flagged as RFC, @danieldegrasse please untag once it's ready, I imagine other long time reviewers should approve first. Thanks for working on this! |
I am ok with the state of the PR- @ioannis-karachalios, can you provide a review here? If the API looks good to you, I am ok to move forwards with it. |
No further comments from my side. The API looks good to me. |
@bjarki-trackunit anything to add? |
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.
Looks good, I have two suggestions, non of which are blocking :)
return -ENODEV; | ||
} | ||
|
||
if (config->cmd_data.port) { |
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 should check that the GPIO is ready as well if it is included, you can use
if (!gpio_is_ready_dt(&config->cmd_data))
{
return -ENODEV;
}
const struct mipi_dbi_spi_config *config = dev->config; | ||
int ret; | ||
|
||
if (config->reset.port == 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.
you can make this a bit prettier with an inline function
static inline bool mipi_dbi_has_pin(const struct gpio_dt_spec *spec)
{
return spec->port != NULL;
}
Cool, let's merge this and keep those for a followup since we are close to RC1. |
0fc0c0f
into
zephyrproject-rtos:main
As per #68408, it looks like this PR should have also included release notes/migration guide for out-of-tree users to know what changes they need to make? |
@kartben Have you seen this https://github.com/zephyrproject-rtos/zephyr/pull/64587/files#diff-46acdbef30e5a958f187ab7343b38d74fcf91152d28ae99b267cd4bc80b92cc3 ? |
I am so sorry, you are right of course. I just somehow missed it when going through the contents of this PR. |
I've just seen this and adapted my out-of-tree board DTS to use it. One thing I find quite confusing is the definition of the reset pin. Namely the fact that it is defined as active low in the binding, so that the DTS must be set as Thanks. |
Glad you were able to transition your board- hopefully the changes weren't too much churn :)
This was intentional- the reset pin is set low by the MIPI DBI driver. This is a similar pattern to how other reset pins in tree work, see the GT911 touchscreen driver for example: https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/input/input_gt911.c#L259 |
It was straightforward. And it seems to work fine :)
To me, if the binding is defined as "reset", the driver should set the pin to 1 to enter reset and to 0 to release from reset (and then you use Edit: actually after re-reading the gt911 code you linked, isn't that doing what I'm saying (i.e. 1 while in reset and 0 to release from reset)? |
So it does, probably should have read my own example closer 🤦. It does not really seem like we have a clear story for this in Zephyr, since there are some places where we drive an active low reset pin to 0 to reset the device: https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/video/ov2640.c#L997 (hopefully I've read this one right). The reason I lean towards I'm totally fine to rename the pin to |
The above is what I would call a bug, reset should be set to 1 to reset it then set to 0, and is also how it is in linux from what I can see and zephyr should be using the same style as linux unless there is a very good reason not to, @mbolivar-ampere @galak @gmarull for comment |
agreed |
Well yeah that's the whole intent of the logical "active low" flag, setting to 1 asserts the condition (i.e. enter reset state) whatever that means on the hardware, that's just how the APi is meant to be used. |
@danieldegrasse since everyone seems to be agree here, can you submit a PR fixing the issue so that it sets it to 1 (which would be the GPIO_ACTIVE state) then sets it back to 0 (which would be the GPIO_INACTIVE state). If there are other drivers not following that then issues should be raised against them |
Sure- I wasn't aware that Linux had a convention here, thanks for highlighting this. #68563 should fix the issue. Just a note- I've changed the reset pin, but left the MIPI DBI command/data pin as |
Thanks. I've provided a comment in that PR.
Previously, it was defined as Thanks. |
Hi - the ili9xxx changes here broke the bl5340_dvk. The change moved the SPI device from spi4 to spi2 (Unintentionally I assume). This breaks display entirely. IE
Fixes it. |
Yes, this was by mistake. Thank you for catching this! I made an issue to track this here: #75991 |
Introduction
This PR introduces a MIPI DBI driver class. This driver class is based off the MIPI DBI definitions present in Linux: https://elixir.bootlin.com/linux/latest/source/include/drm/drm_mipi_dbi.h, which is used by the tinydrm driver to enable TFT SPI displays.
Although the driver included in the PR simply uses a SPI peripheral to emulate a MIPI DBI Type C interface, peripherals such as the LCD controller on the Renesas DA1469x implement MIPI DBI Type C directly in hardware. Furthermore, the MIPI driver API will pave the way for supporting Type B (8080 based) interfaces in Zephyr, which are supported by several NXP peripherals (such as the SEMC or FlexIO)
At a high level, this PR includes the following changes:
Problem Description
Currently, Zephyr supports SPI based displays using the SPI API directly. Most SPI displays use a data format often called 3/4 Wire SPI. The interface for 4 wire SPI utilizes the following signals:
For SPI display controllers, a SPI device can easily drive SCLK, DOUT, and CS. Most display controllers only need data sent to them to support displaying data, so this scheme works well. The C/D and RST pins can be implemented using a GPIO.
However, LCD controller specific IP that implements support for SPI 3/4 wire mode does not map well into the current solution for SPI displays. This IP often supports setting the C/D and RST pins directly, and sometimes will not support reading and writing data simultaneously via SPI (making it a poor fit for the SPI API). Therefore, I would like to introduce the MIPI DBI API in order to better abstract LCD controllers specifically designed for 3/4 wire SPI mode.
Detailed RFC
The MIPI DBI API includes the following 4 functions, loosely based on the API definition in Linux:
mipi_dbi_command_write
: Write a command (and optionally a data buffer) to the displaymipi_dbi_command_read
: Write a command, and read the display's response into a buffermipi_dbi_write_display
: Write display buffer data to a controller. This API is included because some MIPI DBI peripherals need awareness of the display buffer descriptor or pixel format in use.mipi_dbi_reset
: reset the attached display via the RST pinThe
command_write
,command_read
, andwrite_display
APIs all take a pointer to amipi_dbi_config
structure. This approach was chosen in order to map well onto the SPI APIs in zephyr. The alternative to this would be to provide a discretemipi_dbi_attach
function, like Linux does. I chose to deviate from Linux here because mapping well onto the SPI API will enable this MIPI DBI abstraction layer to consume less ROM/RAM space, since nomipi_dbi_attach
function is needed.It should be noted that the MIPI DBI is somewhat similar to the MIPI DSI API. I believe we should have a distinct driver interface here for a few reasons:
Alternatives
Another option I considered here was somehow extending the SPI API to support these 3/4 wire display peripherals. The reasons I chose not to go down this path were: