diff --git a/dts/bindings/mipi-dbi/mipi-dbi-device.yaml b/dts/bindings/mipi-dbi/mipi-dbi-device.yaml index c7e11745d83..57e2f42770b 100644 --- a/dts/bindings/mipi-dbi/mipi-dbi-device.yaml +++ b/dts/bindings/mipi-dbi/mipi-dbi-device.yaml @@ -26,3 +26,21 @@ properties: - "MIPI_DBI_MODE_8080_BUS_16_BIT" - "MIPI_DBI_MODE_8080_BUS_9_BIT" - "MIPI_DBI_MODE_8080_BUS_8_BIT" + + te-mode: + type: string + default: "MIPI_DBI_TE_NO_EDGE" + description: | + MIPI DBI tearing enable signal mode. Defaults to disabled. + enum: + - "MIPI_DBI_TE_NO_EDGE" + - "MIPI_DBI_TE_RISING_EDGE" + - "MIPI_DBI_TE_FALLING_EDGE" + + te-delay: + type: int + default: 0 + description: | + Delay in microseconds to wait before transmitting display data after a + tearing enable synchronization signal is seen. Defaults to 0 since most + controllers will not need a delay. diff --git a/include/zephyr/drivers/mipi_dbi.h b/include/zephyr/drivers/mipi_dbi.h index 79f26d3d71f..109741e3d84 100644 --- a/include/zephyr/drivers/mipi_dbi.h +++ b/include/zephyr/drivers/mipi_dbi.h @@ -112,6 +112,30 @@ extern "C" { #define MIPI_DBI_CONFIG_DT_INST(inst, operation_, delay_) \ MIPI_DBI_CONFIG_DT(DT_DRV_INST(inst), operation_, delay_) +/** + * @brief Get the MIPI DBI TE mode from devicetree + * + * Gets the MIPI DBI TE mode from a devicetree property. + * @param node_id Devicetree node identifier for the MIPI DBI device with the + * TE mode property + * @param edge_prop Property name for the TE mode that should be read from + * devicetree + */ +#define MIPI_DBI_TE_MODE_DT(node_id, edge_prop) \ + DT_STRING_UPPER_TOKEN(node_id, edge_prop) + +/** + * @brief Get the MIPI DBI TE mode for device instance + * + * Gets the MIPI DBI TE mode from a devicetree property. Equivalent to + * MIPI_DBI_TE_MODE_DT(DT_DRV_INST(inst), edge_mode). + * @param inst Instance of the device to get the TE mode for + * @param edge_prop Property name for the TE mode that should be read from + * devicetree + */ +#define MIPI_DBI_TE_MODE_DT_INST(inst, edge_prop) \ + DT_STRING_UPPER_TOKEN(DT_DRV_INST(inst), edge_prop) + /** * @brief MIPI DBI controller configuration * @@ -141,6 +165,9 @@ __subsystem struct mipi_dbi_driver_api { int (*reset)(const struct device *dev, k_timeout_t delay); int (*release)(const struct device *dev, const struct mipi_dbi_config *config); + int (*configure_te)(const struct device *dev, + uint8_t edge, + k_timeout_t delay); }; /** @@ -293,6 +320,45 @@ static inline int mipi_dbi_release(const struct device *dev, return api->release(dev, config); } +/** + * @brief Configures MIPI DBI tearing effect signal + * + * Many displays provide a tearing effect signal, which can be configured + * to pulse at each vsync interval or each hsync interval. This signal can be + * used by the MCU to determine when to transmit a new frame so that the + * read pointer of the display never overlaps with the write pointer from the + * MCU. This function configures the MIPI DBI controller to delay transmitting + * display frames until the selected tearing effect signal edge occurs. + * + * The delay will occur on the on each call to @ref mipi_dbi_write_display + * where the ``frame_incomplete`` flag was set within the buffer descriptor + * provided with the prior call, as this indicates the buffer being written + * in this call is the first buffer of a new frame. + * + * Note that most display controllers will need to enable the TE signal + * using vendor specific commands before the MIPI DBI controller can react + * to it. + * + * @param dev mipi dbi controller + * @param edge which edge of the TE signal to start transmitting on + * @param delay_us how many microseconds after TE edge to start transmission + * @retval -EIO I/O error + * @retval -ENOSYS not implemented + * @retval -ENOTSUP not supported + */ +static inline int mipi_dbi_configure_te(const struct device *dev, + uint8_t edge, + uint32_t delay_us) +{ + const struct mipi_dbi_driver_api *api = + (const struct mipi_dbi_driver_api *)dev->api; + + if (api->configure_te == NULL) { + return -ENOSYS; + } + return api->configure_te(dev, edge, K_USEC(delay_us)); +} + #ifdef __cplusplus } #endif diff --git a/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h b/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h index c079b694a5e..cb3eae16512 100644 --- a/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h +++ b/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h @@ -110,6 +110,40 @@ #define MIPI_DBI_MODE_8080_BUS_9_BIT 0x7 #define MIPI_DBI_MODE_8080_BUS_8_BIT 0x8 +/** MIPI DBI tearing enable synchronization is disabled. */ +#define MIPI_DBI_TE_NO_EDGE 0x0 + +/** + * MIPI DBI tearing enable synchronization on rising edge of TE signal. + * The controller will only send display write data on a rising edge of TE. + * This should be used when the controller can send a frame worth of data + * data to the display panel faster than the display panel can read a frame + * from its RAM + * + * .------. .------. + * TE -----' '------------------------' '------------- + * -----. .----------------------. + * CS '--------' '-------------------- + */ +#define MIPI_DBI_TE_RISING_EDGE 0x1 + +/** + * MIPI DBI tearing enable synchronization on falling edge of TE signal. + * The controller will only send display write data on a falling edge of TE. + * This should be used when the controller sends a frame worth of data + * data to the display panel slower than the display panel can read a frame + * from its RAM. TE synchronization in this mode will only work if the + * controller can complete the write before the display panel completes 2 + * read cycles, otherwise the read pointer will "catch up" with the write + * pointer. + * + * .------. .------. + * TE -----' '------------------------' '------------- + * ------------. .----- + * CS '---------------------------------------' + */ +#define MIPI_DBI_TE_FALLING_EDGE 0x2 + /** * SPI transfer of DBI commands as 8-bit blocks, the default behaviour in * SPI 4 wire (Type C3) mode. The clocking diagram corresponds exactly to