diff --git a/drivers/rz/CMakeLists.txt b/drivers/rz/CMakeLists.txt index 91f9ba7e..a610aeb9 100644 --- a/drivers/rz/CMakeLists.txt +++ b/drivers/rz/CMakeLists.txt @@ -89,6 +89,9 @@ zephyr_library_sources_ifdef(CONFIG_USE_RZ_FSP_DMAC zephyr_library_sources_ifdef(CONFIG_USE_RZ_FSP_DMAC_B fsp/src/${SOC_SERIES_PREFIX}/r_dmac_b/r_dmac_b.c) +zephyr_library_sources_ifdef(CONFIG_USE_RZ_FSP_DISPLAY + fsp/src/${SOC_SERIES_PREFIX}/r_lcdc/r_lcdc.c) + if(CONFIG_DT_HAS_RENESAS_RZ_SCI_B_ENABLED) zephyr_library_sources_ifdef(CONFIG_USE_RZ_FSP_SCI_UART fsp/src/${SOC_SERIES_PREFIX}/r_sci_b_uart/r_sci_b_uart.c) @@ -111,3 +114,7 @@ zephyr_library_sources_ifdef(CONFIG_USE_RZ_FSP_QSPI_SPIBSC zephyr_library_sources_ifdef(CONFIG_USE_RZ_FSP_QSPI_XSPI fsp/src/${SOC_SERIES_PREFIX}/r_xspi_qspi/r_xspi_qspi.c) + +zephyr_library_sources_ifdef(CONFIG_USE_RZ_FSP_MIPI_DSI + fsp/src/${SOC_SERIES_PREFIX}/r_mipi_dsi_b/r_mipi_dsi_b.c + fsp/src/${SOC_SERIES_PREFIX}/r_mipi_phy_b/r_mipi_phy_b.c) diff --git a/drivers/rz/README b/drivers/rz/README index 21ffa35a..d6210555 100644 --- a/drivers/rz/README +++ b/drivers/rz/README @@ -93,10 +93,11 @@ Patch List: Impacted files: drivers/rz/fsp/inc/api/r_transfer_api.h - * Disable the BSP_FEATURE_BSP_HAS_MMU_SUPPORT configuration of the RZ/A3UL to avoid using + * Disable the BSP_FEATURE_BSP_HAS_MMU_SUPPORT configuration of the RZ/A3UL, A3M to avoid using FSP MMU functions and let Zephyr handle MMU Impacted files: drivers/rz/fsp/src/rza/bsp/mcu/rza3ul/bsp_feature.h + drivers/rz/fsp/src/rza/bsp/mcu/rza3m/bsp_feature.h * Change the cast type from uint32_t to uintptr_t when assigning an address to a register in the DMAC FSP driver of the RZ/A3UL to avoid build warnings diff --git a/drivers/rz/fsp/inc/api/r_display_api.h b/drivers/rz/fsp/inc/api/r_display_api.h new file mode 100644 index 00000000..f652c883 --- /dev/null +++ b/drivers/rz/fsp/inc/api/r_display_api.h @@ -0,0 +1,453 @@ +/* +* Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +/*******************************************************************************************************************//** + * @ingroup RENESAS_GRAPHICS_INTERFACES + * @defgroup DISPLAY_API Display Interface + * @brief Interface for LCD panel displays. + * + * @section DISPLAY_API_SUMMARY Summary + * The display interface provides standard display functionality: + * - Signal timing configuration for LCD panels with RGB interface. + * - Dot clock source selection (internal or external) and frequency divider. + * - Blending of multiple graphics layers on the background screen. + * - Color correction (brightness/configuration/gamma correction). + * - Interrupts and callback function. + * + * + * @{ + **********************************************************************************************************************/ + +#ifndef R_DISPLAY_API_H +#define R_DISPLAY_API_H + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ + +/* Includes board and MCU related header files. */ +#include "bsp_api.h" + +/* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ +FSP_HEADER + +/********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ + +#define DISPLAY_GAMMA_CURVE_ELEMENT_NUM (16) + +/********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ + +/** Display frame number */ +typedef enum e_display_frame_layer +{ + DISPLAY_FRAME_LAYER_1 = 0, ///< Frame layer 1 + DISPLAY_FRAME_LAYER_2 = 1 ///< Frame layer 2 +} display_frame_layer_t; + +/** Display interface operation state */ +typedef enum e_display_state +{ + DISPLAY_STATE_CLOSED = 0, ///< Display closed + DISPLAY_STATE_OPENED = 1, ///< Display opened + DISPLAY_STATE_DISPLAYING = 2 ///< Displaying +} display_state_t; + +/** Display event codes */ +typedef enum e_display_event +{ + DISPLAY_EVENT_GR1_UNDERFLOW = 1, ///< Graphics frame1 underflow occurs + DISPLAY_EVENT_GR2_UNDERFLOW = 2, ///< Graphics frame2 underflow occurs + DISPLAY_EVENT_LINE_DETECTION = 3, ///< Designated line is processed + DISPLAY_EVENT_FRAME_END = 4, ///< Frame end is processed +} display_event_t; + +#ifndef BSP_OVERRIDE_DISPLAY_IN_FORMAT_T + +/** Input format setting */ +typedef enum e_display_in_format +{ + DISPLAY_IN_FORMAT_32BITS_ARGB8888 = 0, ///< ARGB8888, 32 bits + DISPLAY_IN_FORMAT_32BITS_RGB888 = 1, ///< RGB888, 32 bits + DISPLAY_IN_FORMAT_16BITS_RGB565 = 2, ///< RGB565, 16 bits + DISPLAY_IN_FORMAT_16BITS_ARGB1555 = 3, ///< ARGB1555, 16 bits + DISPLAY_IN_FORMAT_16BITS_ARGB4444 = 4, ///< ARGB4444, 16 bits + DISPLAY_IN_FORMAT_CLUT8 = 5, ///< CLUT8 + DISPLAY_IN_FORMAT_CLUT4 = 6, ///< CLUT4 + DISPLAY_IN_FORMAT_CLUT1 = 7, ///< CLUT1 +} display_in_format_t; + +#endif + +/** Output format setting */ +typedef enum e_display_out_format +{ + DISPLAY_OUT_FORMAT_24BITS_RGB888 = 0, ///< RGB888, 24 bits + DISPLAY_OUT_FORMAT_18BITS_RGB666 = 1, ///< RGB666, 18 bits + DISPLAY_OUT_FORMAT_16BITS_RGB565 = 2, ///< RGB565, 16 bits + DISPLAY_OUT_FORMAT_8BITS_SERIAL = 3, ///< SERIAL, 8 bits +} display_out_format_t; + +/** Data endian select */ +typedef enum e_display_endian +{ + DISPLAY_ENDIAN_LITTLE, ///< Little-endian + DISPLAY_ENDIAN_BIG, ///< Big-endian +} display_endian_t; + +/** RGB color order select */ +typedef enum e_display_color_order +{ + DISPLAY_COLOR_ORDER_RGB, ///< Color order RGB + DISPLAY_COLOR_ORDER_BGR ///< Color order BGR +} display_color_order_t; + +/** Polarity of a signal select */ +typedef enum e_display_signal_polarity +{ + DISPLAY_SIGNAL_POLARITY_LOACTIVE, ///< Low active signal + DISPLAY_SIGNAL_POLARITY_HIACTIVE, ///< High active signal +} display_signal_polarity_t; + +/** Signal synchronization edge select */ +typedef enum e_display_sync_edge +{ + DISPLAY_SIGNAL_SYNC_EDGE_RISING, ///< Signal is synchronized to rising edge + DISPLAY_SIGNAL_SYNC_EDGE_FALLING, ///< Signal is synchronized to falling edge +} display_sync_edge_t; + +/** Fading control */ +typedef enum e_display_fade_control +{ + DISPLAY_FADE_CONTROL_NONE, ///< Applying no fading control + DISPLAY_FADE_CONTROL_FADEIN, ///< Applying fade-in control + DISPLAY_FADE_CONTROL_FADEOUT, ///< Applying fade-out control +} display_fade_control_t; + +/** Fading status */ +typedef enum e_display_fade_status +{ + DISPLAY_FADE_STATUS_NOT_UNDERWAY, ///< Fade-in/fade-out is not in progress + DISPLAY_FADE_STATUS_FADING_UNDERWAY, ///< Fade-in or fade-out is in progress + DISPLAY_FADE_STATUS_PENDING ///< Fade-in/fade-out is configured but not yet started +} display_fade_status_t; + +/** Color Keying enable or disable */ +typedef enum e_display_color_keying +{ + DISPLAY_COLOR_KEYING_DISABLE = 0, ///< Color keying disable + DISPLAY_COLOR_KEYING_ENABLE = 1 ///< Color keying enable +} display_color_keying_t; + +#ifndef BSP_OVERRIDE_DISPLAY_DATA_SWAP_T + +/** Data swap settings */ +typedef enum e_display_data_swap +{ + DISPLAY_DATA_SWAP_8BIT = 1, + DISPLAY_DATA_SWAP_16BIT = 2, + DISPLAY_DATA_SWAP_32BIT = 4, + DISPLAY_DATA_SWAP_64BIT = 8, +} display_data_swap_t; + +#endif + +/** Display signal timing setting */ +typedef struct st_display_timing +{ + uint16_t total_cyc; ///< Total cycles in one line or total lines in one frame + uint16_t display_cyc; ///< Active video cycles or lines + uint16_t back_porch; ///< Back porch cycles or lines + uint16_t sync_width; ///< Sync signal asserting width + display_signal_polarity_t sync_polarity; ///< Sync signal polarity +} display_timing_t; + +/** RGB Color setting */ +typedef struct st_display_color +{ + union + { + uint32_t argb; ///< Entire color + struct + { + uint8_t b; ///< blue + uint8_t g; ///< green + uint8_t r; ///< red + uint8_t a; ///< alpha + } byte; + }; +} display_color_t; + +/** Contrast (gain) correction setting */ +typedef struct st_display_coordinate +{ + int16_t x; ///< Coordinate X, this allows to set signed value. + int16_t y; ///< Coordinate Y, this allows to set signed value. +} display_coordinate_t; + +/** Brightness (DC) correction setting */ +typedef struct st_display_brightness +{ + bool enable; ///< Brightness Correction On/Off + uint16_t r; ///< Brightness (DC) adjustment for R channel + uint16_t g; ///< Brightness (DC) adjustment for G channel + uint16_t b; ///< Brightness (DC) adjustment for B channel +} display_brightness_t; + +/** Contrast (gain) correction setting */ +typedef struct st_display_contrast +{ + bool enable; ///< Contrast Correction On/Off + uint8_t r; ///< Contrast (gain) adjustment for R channel + uint8_t g; ///< Contrast (gain) adjustment for G channel + uint8_t b; ///< Contrast (gain) adjustment for B channel +} display_contrast_t; + +/** Color correction setting */ +typedef struct st_display_correction +{ + display_brightness_t brightness; ///< Brightness + display_contrast_t contrast; ///< Contrast +} display_correction_t; + +/** Gamma correction setting for each color */ +typedef struct st_gamma_correction +{ + bool enable; ///< Gamma Correction On/Off + uint16_t * gain; ///< Gain adjustment + uint16_t * threshold; ///< Start threshold +} gamma_correction_t; + +/** Gamma correction setting */ +typedef struct st_display_gamma_correction +{ + gamma_correction_t r; ///< Gamma correction for R channel + gamma_correction_t g; ///< Gamma correction for G channel + gamma_correction_t b; ///< Gamma correction for B channel +} display_gamma_correction_t; + +/** CLUT setting */ +typedef struct st_display_clut +{ + uint32_t color_num; ///< The number of colors in CLUT + const uint32_t * p_clut; ///< Address of the area storing the CLUT data (in ARGB8888 format) +} display_clut_t; + +/** Color Keying setting */ +typedef struct st_display_colorkeying_cfg +{ + display_color_t src_color; ///< Source color + display_color_t dst_color; ///< Destination color + display_color_keying_t enable_ckey; ///< Select enable or disable +} display_colorkeying_cfg_t; + +/** Color Keying layer setting */ +typedef struct st_display_colorkeying_layer +{ + display_colorkeying_cfg_t layer[2]; +} display_colorkeying_layer_t; + +#ifndef BSP_OVERRIDE_DISPLAY_INPUT_CFG_T + +/** Graphics plane input configuration structure */ +typedef struct st_display_input_cfg +{ + uint32_t * p_base; ///< Base address to the frame buffer + uint16_t hsize; ///< Horizontal pixel size in a line + uint16_t vsize; ///< Vertical pixel size in a frame + uint32_t hstride; ///< Memory stride (bytes) in a line + display_in_format_t format; ///< Input format setting + bool line_descending_enable; ///< Line descending enable + bool lines_repeat_enable; ///< Line repeat enable + uint16_t lines_repeat_times; ///< Expected number of line repeating +} display_input_cfg_t; + +#endif + +/** Display output configuration structure */ +typedef struct st_display_output_cfg +{ + display_timing_t htiming; ///< Horizontal display cycle setting + display_timing_t vtiming; ///< Vertical display cycle setting + display_out_format_t format; ///< Output format setting + display_endian_t endian; ///< Bit order of output data + display_color_order_t color_order; ///< Color order in pixel + display_signal_polarity_t data_enable_polarity; ///< Data Enable signal polarity + display_sync_edge_t sync_edge; ///< Signal sync edge selection + display_color_t bg_color; ///< Background color + display_brightness_t brightness; ///< Brightness setting + display_contrast_t contrast; ///< Contrast setting + display_gamma_correction_t * p_gamma_correction; ///< Pointer to gamma correction setting + bool dithering_on; ///< Dithering on/off +} display_output_cfg_t; + +/** Graphics layer blend setup parameter structure */ +typedef struct st_display_layer +{ + display_coordinate_t coordinate; ///< Blending location (starting point of image) + display_color_t bg_color; ///< Color outside region + display_fade_control_t fade_control; ///< Layer fade-in/out control on/off + uint8_t fade_speed; ///< Layer fade-in/out frame rate +} display_layer_t; + +/** Display callback parameter definition */ +typedef struct st_display_callback_args +{ + display_event_t event; ///< Event code + void const * p_context; ///< Context provided to user during callback +} display_callback_args_t; + +/** Display main configuration structure */ +typedef struct st_display_cfg +{ + /** Generic configuration for display devices */ + display_input_cfg_t input[2]; ///< Graphics input frame setting + display_output_cfg_t output; ///< Graphics output frame setting + display_layer_t layer[2]; ///< Graphics layer blend setting + uint8_t line_detect_ipl; ///< Line detect interrupt priority + uint8_t underflow_1_ipl; ///< Underflow 1 interrupt priority + uint8_t underflow_2_ipl; ///< Underflow 2 interrupt priority + IRQn_Type line_detect_irq; ///< Line detect interrupt vector + IRQn_Type underflow_1_irq; ///< Underflow 1 interrupt vector + IRQn_Type underflow_2_irq; ///< Underflow 2 interrupt vector + + /** Configuration for display event processing */ + void (* p_callback)(display_callback_args_t * p_args); ///< Pointer to callback function + void const * p_context; ///< User defined context passed into callback function + + /** Pointer to display peripheral specific configuration */ + void const * p_extend; ///< Display hardware dependent configuration +} display_cfg_t; + +/** Display main configuration structure */ +typedef struct st_display_runtime_cfg +{ + /** Generic configuration for display devices */ + display_input_cfg_t input; ///< Graphics input frame setting + display_layer_t layer; ///< Graphics layer alpha blending setting +} display_runtime_cfg_t; + +/** Display CLUT configuration structure */ +typedef struct st_display_clut_cfg +{ + uint32_t * p_base; ///< Pointer to CLUT source data + uint16_t start; ///< Beginning of CLUT entry to be updated + uint16_t size; ///< Size of CLUT entry to be updated +} display_clut_cfg_t; + +/** Display control block. Allocate an instance specific control block to pass into the display API calls. + */ + +/** Display control block */ +typedef void display_ctrl_t; + +/** Display Status */ +typedef struct st_display_status +{ + display_state_t state; ///< Status of display module + display_fade_status_t fade_status[DISPLAY_FRAME_LAYER_2 + 1]; ///< Status of fade-in/fade-out status +} display_status_t; + +/** Shared Interface definition for display peripheral */ +typedef struct st_display_api +{ + /** Open display device. + * @param[in,out] p_ctrl Pointer to display interface control block. Must be declared by user. Value set + * here. + * @param[in] p_cfg Pointer to display configuration structure. All elements of this structure must be + * set by user. + */ + fsp_err_t (* open)(display_ctrl_t * const p_ctrl, display_cfg_t const * const p_cfg); + + /** Close display device. + * @param[in] p_ctrl Pointer to display interface control block. + */ + fsp_err_t (* close)(display_ctrl_t * const p_ctrl); + + /** Display start. + * @param[in] p_ctrl Pointer to display interface control block. + */ + fsp_err_t (* start)(display_ctrl_t * const p_ctrl); + + /** Display stop. + * @param[in] p_ctrl Pointer to display interface control block. + */ + fsp_err_t (* stop)(display_ctrl_t * const p_ctrl); + + /** Change layer parameters at runtime. + * @param[in] p_ctrl Pointer to display interface control block. + * @param[in] p_cfg Pointer to run-time layer configuration structure. + * @param[in] frame Number of graphic frames. + */ + fsp_err_t (* layerChange)(display_ctrl_t const * const p_ctrl, display_runtime_cfg_t const * const p_cfg, + display_frame_layer_t frame); + + /** Change layer framebuffer pointer. + * @param[in] p_ctrl Pointer to display interface control block. + * @param[in] framebuffer Pointer to desired framebuffer. + * @param[in] frame Number of graphic frames. + */ + fsp_err_t (* bufferChange)(display_ctrl_t const * const p_ctrl, uint8_t * const framebuffer, + display_frame_layer_t frame); + + /** Color correction. + * @param[in] p_ctrl Pointer to display interface control block. + * @param[in] param Pointer to color correction configuration structure. + */ + fsp_err_t (* correction)(display_ctrl_t const * const p_ctrl, display_correction_t const * const p_param); + + /** Set CLUT for display device. + * @param[in] p_ctrl Pointer to display interface control block. + * @param[in] p_clut_cfg Pointer to CLUT configuration structure. + * @param[in] layer Layer number corresponding to the CLUT. + */ + fsp_err_t (* clut)(display_ctrl_t const * const p_ctrl, display_clut_cfg_t const * const p_clut_cfg, + display_frame_layer_t layer); + + /** Set CLUT element for display device. + * @param[in] p_ctrl Pointer to display interface control block. + * @param[in] layer Layer number corresponding to the CLUT. + * @param[in] index CLUT element index. + * @param[in] color Desired CLUT index color. + */ + fsp_err_t (* clutEdit)(display_ctrl_t const * const p_ctrl, display_frame_layer_t layer, uint8_t index, + uint32_t color); + + /** Configure color keying. + * @param[in] p_ctrl Pointer to display interface control block. + * @param[in] key_cfg Pointer to color keying configuration. + * @param[in] layer Layer to apply color keying. + */ + fsp_err_t (* colorKeySet)(display_ctrl_t const * const p_ctrl, display_colorkeying_layer_t key_cfg, + display_frame_layer_t layer); + + /** Get status for display device. + * @param[in] p_ctrl Pointer to display interface control block. + * @param[in] status Pointer to display interface status structure. + */ + fsp_err_t (* statusGet)(display_ctrl_t const * const p_ctrl, display_status_t * const p_status); +} display_api_t; + +/** This structure encompasses everything that is needed to use an instance of this interface. */ +typedef struct st_display_instance +{ + display_ctrl_t * p_ctrl; ///< Pointer to the control structure for this instance + display_cfg_t const * p_cfg; ///< Pointer to the configuration structure for this instance + display_api_t const * p_api; ///< Pointer to the API structure for this instance +} display_instance_t; + +/********************************************************************************************************************** + * Public Functions + **********************************************************************************************************************/ + +/* @} (end defgroup DISPLAY_API) */ + +/* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ +FSP_FOOTER +#endif diff --git a/drivers/rz/fsp/inc/api/r_mipi_dsi_api.h b/drivers/rz/fsp/inc/api/r_mipi_dsi_api.h new file mode 100644 index 00000000..822f0540 --- /dev/null +++ b/drivers/rz/fsp/inc/api/r_mipi_dsi_api.h @@ -0,0 +1,546 @@ +/* +* Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +/*******************************************************************************************************************//** + * @ingroup RENESAS_GRAPHICS_INTERFACES + * @defgroup MIPI_DSI_API MIPI DSI Interface + * @brief Interface for MIPI DSI communications. + * + * @section MIPI_DSI_API_SUMMARY Summary + * The MIPI DSI interface provides functionality involved with driving display panels over MIPI. + * + * @{ + **********************************************************************************************************************/ + +#ifndef R_MIPI_DSI_API_H +#define R_MIPI_DSI_API_H + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ + +/* Includes board and MCU related header files. */ +#include "bsp_api.h" +#include "r_mipi_dsi_cfg.h" + +#include "r_mipi_phy.h" + +/* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ +FSP_HEADER + +/********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ + +/********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ + +/** MIPI DSI packet Data Type (commands) - See MIPI specification for additional information */ +typedef enum e_mipi_dsi_cmd_id +{ + MIPI_DSI_CMD_ID_V_SYNC_START = 0x01, ///< (Short) Sync Event, V Sync Start + MIPI_DSI_CMD_ID_V_SYNC_END = 0x11, ///< (Short) Sync Event, V Sync End + MIPI_DSI_CMD_ID_H_SYNC_START = 0x21, ///< (Short) Sync Event, H Sync Start + MIPI_DSI_CMD_ID_H_SYNC_END = 0x31, ///< (Short) Sync Event, H Sync End + + MIPI_DSI_CMD_ID_COMPRESSION_MODE = 0x07, ///< (Short) Compression Mode Command + MIPI_DSI_CMD_ID_END_OF_TRANSMISSION = 0x08, ///< (Short) End of Transmission packet (EoTp) + + MIPI_DSI_CMD_ID_COLOR_MODE_OFF = 0x02, ///< (Short) Color Mode (CM) Off Command + MIPI_DSI_CMD_ID_COLOR_MODE_ON = 0x12, ///< (Short) Color Mode (CM) On Command + MIPI_DSI_CMD_ID_SHUTDOWN_PERIPHERAL = 0x22, ///< (Short) Shut Down Peripheral Command + MIPI_DSI_CMD_ID_TURN_ON_PERIPHERAL = 0x32, ///< (Short) Turn On Peripheral Command + + MIPI_DSI_CMD_ID_GENERIC_SHORT_WRITE_0_PARAM = 0x03, ///< (Short) Generic Short WRITE, no parameters + MIPI_DSI_CMD_ID_GENERIC_SHORT_WRITE_1_PARAM = 0x13, ///< (Short) Generic Short WRITE, 1 parameter + MIPI_DSI_CMD_ID_GENERIC_SHORT_WRITE_2_PARAM = 0x23, ///< (Short) Generic Short WRITE, 2 parameters + + MIPI_DSI_CMD_ID_GENERIC_READ_REQUEST_0_PARAM = 0x04, ///< (Short) Generic READ, no parameters + MIPI_DSI_CMD_ID_GENERIC_READ_REQUEST_1_PARAM = 0x14, ///< (Short) Generic READ, 1 parameter + MIPI_DSI_CMD_ID_GENERIC_READ_REQUEST_2_PARAM = 0x24, ///< (Short) Generic READ, 2 parameters + + MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_0_PARAM = 0x05, ///< (Short) DCS Short WRITE, no parameters + MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM = 0x15, ///< (Short) DCS Short WRITE, 1 parameter + + MIPI_DSI_CMD_ID_DCS_READ = 0x06, ///< (Short) DCS READ, no parameters + MIPI_DSI_CMD_ID_EXECUTE_QUEUE = 0x16, ///< (Short) Execute Queue + + MIPI_DSI_CMD_ID_SET_MAXIMUM_RETURN_PACKET_SIZE = 0x37, ///< (Short) Set Maximum Return Packet Size + + MIPI_DSI_CMD_ID_NULL_PACKET = 0x09, ///< (Long) Null Packet, no data + MIPI_DSI_CMD_ID_BLANKING_PACKET = 0x19, ///< (Long) Blanking Packet, no data + MIPI_DSI_CMD_ID_GENERIC_LONG_WRITE = 0x29, ///< (Long) Generic Long Write + MIPI_DSI_CMD_ID_DCS_LONG_WRITE = 0x39, ///< (Long) DCS Long Write/write_LUT Command Packet + + MIPI_DSI_CMD_ID_PICTURE_PARAMETER_SET = 0x0A, ///< (Long) Picture Parameter Set + MIPI_DSI_CMD_ID_COMPRESSED_PIXEL_STREAM = 0x0B, ///< (Long) Compressed Pixel Stream + + MIPI_DSI_CMD_ID_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20 = 0x0C, ///< (Long) Loosely Packed Pixel Stream, 20-bit YCbCr, 4:2:2 Format + MIPI_DSI_CMD_ID_PACKED_PIXEL_STREAM_YCBCR24 = 0x1C, ///< (Long) Packed Pixel Stream, 24-bit YCbCr, 4:2:2 Format + MIPI_DSI_CMD_ID_PACKED_PIXEL_STREAM_YCBCR16 = 0x2C, ///< (Long) Packed Pixel Stream, 16-bit YCbCr, 4:2:2 Format + + MIPI_DSI_CMD_ID_PACKED_PIXEL_STREAM_30 = 0x0D, ///< (Long) Packed Pixel Stream, 30-bit RGB, 10-10-10 Format + MIPI_DSI_CMD_ID_PACKED_PIXEL_STREAM_36 = 0x1D, ///< (Long) Packed Pixel Stream, 36-bit RGB, 12-12-12 Format + MIPI_DSI_CMD_ID_PACKED_PIXEL_STREAM_YCBCR12 = 0x3D, ///< (Long) Packed Pixel Stream, 12-bit YCbCr, 4:2:0 Format + + MIPI_DSI_CMD_ID_PACKED_PIXEL_STREAM_16 = 0x0E, ///< (Long) Packed Pixel Stream, 16-bit RGB, 5-6-5 Format + MIPI_DSI_CMD_ID_PACKED_PIXEL_STREAM_18 = 0x1E, ///< (Long) Packed Pixel Stream, 18-bit RGB, 6-6-6 Format + MIPI_DSI_CMD_ID_LOOSELY_PACKED_PIXEL_STREAM_18 = 0x2E, ///< (Long) Loosely Packed Pixel Stream, 18-bit RGB, 6-6-6 Format + MIPI_DSI_CMD_ID_PACKED_PIXEL_STREAM_24 = 0x3E, ///< (Long) Packed Pixel Stream, 24-bit RGB, 8-8-8 Format +} mipi_dsi_cmd_id_t; + +/** MIPI DCS ID types - See MIPI DCS specification for additional information */ +typedef enum e_mipi_dsi_dcs_id +{ + MIPI_DSI_DCS_ID_ENTER_IDLE_MODE = 0x39, ///< Enter idle mode + MIPI_DSI_DCS_ID_ENTER_INVERT_MODE = 0x21, ///< Displayed image colors inverted + MIPI_DSI_DCS_ID_ENTER_NORMAL_MODE = 0x13, ///< Whole display area used for image + MIPI_DSI_DCS_ID_ENTER_PARTIAL_MODE = 0x12, ///< Part of display area used for image + MIPI_DSI_DCS_ID_ENTER_SLEEP_MODE = 0x10, ///< Power off the display panel + MIPI_DSI_DCS_ID_EXIT_IDLE_MODE = 0x38, ///< Full color depth used + MIPI_DSI_DCS_ID_EXIT_INVERT_MODE = 0x20, ///< Displayed image colors not inverted + MIPI_DSI_DCS_ID_EXIT_SLEEP_MODE = 0x11, ///< Power on the display panel + MIPI_DSI_DCS_ID_GET_3D_CONTROL = 0x3F, ///< Get display module 3D mode + MIPI_DSI_DCS_ID_GET_ADDRESS_MODE = 0x0B, ///< Get data order for transfers from host to the display device + MIPI_DSI_DCS_ID_GET_BLUE_CHANNEL = 0x08, ///< Get blue component of pixel at 0,0 + MIPI_DSI_DCS_ID_GET_CABC_MIN_BRIGHTNESS = 0x5F, ///< Get current minimum brightness level of the active CABC mode + MIPI_DSI_DCS_ID_GET_COMPRESSION_MODE = 0x03, ///< Get current compression mode + MIPI_DSI_DCS_ID_GET_CONTROL_DISPLAY = 0x54, ///< Get control display mode + MIPI_DSI_DCS_ID_GET_DIAGNOSTIC_RESULT = 0x0F, ///< Get peripheral self-diagnostic result + MIPI_DSI_DCS_ID_GET_DISPLAY_BRIGHTNESS = 0x52, ///< Get current display brightness level + MIPI_DSI_DCS_ID_GET_DISPLAY_MODE = 0x0D, ///< Get current display mode from the peripheral + MIPI_DSI_DCS_ID_GET_DSI_MODE = 0x70, ///< Get DSI operation mode + MIPI_DSI_DCS_ID_GET_ERROR_COUNT_ON_DSI = 0x05, ///< Get number of corrupted packets on DSI + MIPI_DSI_DCS_ID_GET_GREEN_CHANNEL = 0x07, ///< Get green component of pixel at 0,0 + MIPI_DSI_DCS_ID_GET_IMAGE_CHECKSUM_CT = 0x15, ///< Returns checksum of frame of color-transformed pixel data + MIPI_DSI_DCS_ID_GET_IMAGE_CHECKSUM_RGB = 0x14, ///< Returns checksum of frame of RGB pixel data + MIPI_DSI_DCS_ID_GET_PIXEL_FORMAT = 0x0C, ///< Get current pixel format + MIPI_DSI_DCS_ID_GET_POWER_MODE = 0x0A, ///< Get current power mode + MIPI_DSI_DCS_ID_GET_POWER_SAVE = 0x56, ///< Get current power-save mode + MIPI_DSI_DCS_ID_GET_RED_CHANNEL = 0x06, ///< Get red component of pixel at 0,0 + MIPI_DSI_DCS_ID_GET_SCANLINE = 0x45, ///< Get current scanline + MIPI_DSI_DCS_ID_GET_SIGNAL_MODE = 0x0E, ///< Get display module signaling mode + MIPI_DSI_DCS_ID_NOP = 0x00, ///< No operation + MIPI_DSI_DCS_ID_READ_ACMD = 0x62, ///< Perform read access to the ACMD registers + MIPI_DSI_DCS_ID_READ_DDB_CONTINUE = 0xA8, ///< Continue reading the DDB from the last read location + MIPI_DSI_DCS_ID_READ_DDB_START = 0xA1, ///< Read the DDB from the provided location + MIPI_DSI_DCS_ID_READ_DSE_MAILBOX = 0x57, ///< Read access to the registers of the DSE read or write control mailbox + MIPI_DSI_DCS_ID_READ_MEMORY_CONTINUE = 0x3E, ///< Read image data from peripheral, continuing after last read + MIPI_DSI_DCS_ID_READ_MEMORY_START = 0x2E, ///< Read image data from the peripheral to the host + MIPI_DSI_DCS_ID_READ_PPS_CONTINUE = 0xA9, ///< Continue reading the specified length of PPS data + MIPI_DSI_DCS_ID_READ_PPS_START = 0xA2, ///< Read PPS data + MIPI_DSI_DCS_ID_SET_3D_CONTROL = 0x3D, ///< 3D is used on the display panel + MIPI_DSI_DCS_ID_SET_ADDRESS_MODE = 0x36, ///< Set data order for transfers from host to peripheral + MIPI_DSI_DCS_ID_SET_ARP_OFF = 0x60, ///< Disable ARP + MIPI_DSI_DCS_ID_SET_ARP_ON = 0x61, ///< Enable ARP and set T2 timer + MIPI_DSI_DCS_ID_SET_CABC_MIN_BRIGHTNESS = 0x5E, ///< Set minimum brightness level for CABC mode + MIPI_DSI_DCS_ID_SET_COLUMN_ADDRESS = 0x2A, ///< Set column extent + MIPI_DSI_DCS_ID_SET_DISPLAY_BRIGHTNESS = 0x51, ///< Set display brightness level + MIPI_DSI_DCS_ID_SET_DISPLAY_OFF = 0x28, ///< Blank the display device + MIPI_DSI_DCS_ID_SET_DISPLAY_ON = 0x29, ///< Show image on display device + MIPI_DSI_DCS_ID_SET_DSI_MODE = 0x71, ///< Set DSI operation mode + MIPI_DSI_DCS_ID_SET_GAMMA_CURVE = 0x26, ///< Select gamma curve used by display + MIPI_DSI_DCS_ID_SET_PAGE_ADDRESS = 0x2B, ///< Set page extent + MIPI_DSI_DCS_ID_SET_PARTIAL_COLUMNS = 0x31, ///< Define the number of columns in the partial display area + MIPI_DSI_DCS_ID_SET_PARTIAL_ROWS = 0x30, ///< Define the number of rows in the partial display area + MIPI_DSI_DCS_ID_SET_PIXEL_FORMAT = 0x3A, ///< Define how many bits per pixel are used + MIPI_DSI_DCS_ID_SET_SCROLL_AREA = 0x33, ///< Define vertical scrolling and fixed area + MIPI_DSI_DCS_ID_SET_SCROLL_START = 0x37, ///< Define vertical scrolling starting point + MIPI_DSI_DCS_ID_SET_TEAR_OFF = 0x34, ///< Sync information not sent from the display module to the host + MIPI_DSI_DCS_ID_SET_TEAR_ON = 0x35, ///< Sync information is sent from the display module to the host + MIPI_DSI_DCS_ID_SET_TEAR_SCANLINE = 0x44, ///< Sync information is sent from display to the host when display refresh reaches profivided scan line + MIPI_DSI_DCS_ID_SET_VSYNC_TIMING = 0x40, ///< Set VSYNC timing to the specified length of PPS data + MIPI_DSI_DCS_ID_SOFT_RESET = 0x01, ///< Software reset + MIPI_DSI_DCS_ID_WRITE_ACMD = 0x63, ///< Write access to ACMD registers + MIPI_DSI_DCS_ID_WRITE_CONTROL_DISPLAY = 0x53, ///< Write control mode of display brightness + MIPI_DSI_DCS_ID_WRITE_DSE_MAILBOX = 0x58, ///< Write registers of DSE read or write control mailbox + MIPI_DSI_DCS_ID_WRITE_LUT = 0x2D, ///< Fill peripheral look-up table with provided data + MIPI_DSI_DCS_ID_WRITE_MEMORY_CONTINUE = 0x3C, ///< Continue image information transfer from last address + MIPI_DSI_DCS_ID_WRITE_MEMORY_START = 0x2C, ///< Transfer image information from host to peripheral + MIPI_DSI_DCS_ID_WRITE_POWER_SAVE = 0x55, ///< Writes power save mode +} mipi_dsi_dcs_id_t; + +/** MIPI DSI Video Data type */ +typedef enum e_mipi_dsi_video_data +{ + MIPI_DSI_VIDEO_DATA_16RGB_PIXEL_STREAM = 0x0E, ///< 16-bit RGB Packed Pixel Stream + MIPI_DSI_VIDEO_DATA_18RGB_PIXEL_STREAM = 0x1E, ///< 18-bit RGB Packed Pixel Stream + MIPI_DSI_VIDEO_DATA_18RGB_LOOSELY_PIXEL_STREAM = 0x2E, ///< 18-bit RGB Loosely Packed Pixel Stream + MIPI_DSI_VIDEO_DATA_24RGB_PIXEL_STREAM = 0x3E, ///< 24-bit RGB Packed Pixel Stream +} mipi_dsi_video_data_t; + +/** MIPI DSI Acknowledge and Error type */ +typedef enum e_mipi_dsi_ack_err +{ + MIPI_DSI_ACK_ERR_NONE = 0x0000, ///< No Errors + MIPI_DSI_ACK_ERR_SOT_ERROR = 0x0001, ///< SoT Error + MIPI_DSI_ACK_ERR_SOT_SYNC_ERROR = 0x0002, ///< SoT Sync Error + MIPI_DSI_ACK_ERR_EOT_SYNC_ERROR = 0x0004, ///< EoT Sync Error + MIPI_DSI_ACK_ERR_ESCAPE_ENTRY_ERROR = 0x0008, ///< Escape Mode Entry Error + MIPI_DSI_ACK_ERR_LOW_POWER_SYNC_ERROR = 0x0010, ///< Low-Power Transmit Sync Error + MIPI_DSI_ACK_ERR_PERIPHERAL_TIMEOUT_ERROR = 0x0020, ///< Peripheral Timeout Error + MIPI_DSI_ACK_ERR_FALSE_CONTROL_ERROR = 0x0040, ///< False Control Error + MIPI_DSI_ACK_ERR_CONTENTION_DETECTED = 0x0080, ///< Contention Detected Error + MIPI_DSI_ACK_ERR_ECC_SINGLE = 0x0100, ///< ECC Error, single-bit + MIPI_DSI_ACK_ERR_ECC_MULTI = 0x0200, ///< ECC Error, multi-bit + MIPI_DSI_ACK_ERR_CKSM_ERROR = 0x0400, ///< Checksum Error (Long packet only) + MIPI_DSI_ACK_ERR_DSI_DATA_ERROR = 0x0800, ///< DSI Data Type Not Recognized + MIPI_DSI_ACK_ERR_DSI_VC_ID_ERROR = 0x1000, ///< DSI VC ID Invalid + MIPI_DSI_ACK_ERR_INVALID_TX_LEN = 0x2000, ///< Invalid Transmission Length + MIPI_DSI_ACK_ERR_DSI_PROTOCOL_VIOLATION = 0x8000, ///< DSI Protocol Violation +} mipi_dsi_ack_err_t; + +/* MIPI DSI Virtual Channel ID Type*/ +typedef enum e_mipi_dsi_vc +{ + MIPI_DSI_VC_NONE = 0x0, ///< No channels selected + MIPI_DSI_VC_0 = 0x1, ///< Virtual channel 0 + MIPI_DSI_VC_1 = 0x2, ///< Virtual channel 1 + MIPI_DSI_VC_2 = 0x4, ///< Virtual channel 2 + MIPI_DSI_VC_3 = 0x8, ///< Virtual channel 3 +} mipi_dsi_vc_t; + +/** MIPI DSI Message Flags */ +typedef enum e_mipi_dsi_cmd_flag +{ + MIPI_DSI_CMD_FLAG_NONE = 0x00, ///< No flags + MIPI_DSI_CMD_FLAG_BTA = 0x01, ///< Assert bus turnaround at end of transfer + MIPI_DSI_CMD_FLAG_BTA_READ = 0x02, ///< Assert bus turnaround followed by read request (No WRITE request before BTA) + MIPI_DSI_CMD_FLAG_BTA_NO_WRITE = 0x03, ///< Immediately assert bus turnaround (No WRITE request before BTA) + MIPI_DSI_CMD_FLAG_AUX_OPERATION = 0x20, ///< Execute auxiliary operation command + MIPI_DSI_CMD_FLAG_ACT_CODE_RESET_TRIGGER = 0x20, ///< Send action code reset trigger message. + MIPI_DSI_CMD_FLAG_ACT_CODE_INITIAL_SKEW_CAL = 0x24, ///< Send action code initial skew calibration message. + MIPI_DSI_CMD_FLAG_ACT_CODE_PERIODIC_SKEW_CAL = 0x25, ///< Send action code periodic skew message. + MIPI_DSI_CMD_FLAG_ACT_CODE_NO_OPERATION = 0x28, ///< Send action code NOOP message. + MIPI_DSI_CMD_FLAG_LOW_POWER = 0x40, ///< Transmit in low-power mode +} mipi_dsi_cmd_flag_t; + +/** MIPI DSI event codes */ +typedef enum e_mipi_dsi_event +{ + MIPI_DSI_EVENT_SEQUENCE_0, ///< Sequence 0 event (Low-Power) + MIPI_DSI_EVENT_SEQUENCE_1, ///< Sequence 1 event (High-Speed) + MIPI_DSI_EVENT_VIDEO, ///< Video event + MIPI_DSI_EVENT_RECEIVE, ///< Receive event + MIPI_DSI_EVENT_FATAL, ///< Fatal event + MIPI_DSI_EVENT_PHY, ///< Physical layer event + + /* Software triggered events - To allow application specific processing */ + MIPI_DSI_EVENT_POST_OPEN, ///< Interface has been opened. Perform post-open application processing + MIPI_DSI_EVENT_PRE_START, ///< Video is about to start. Perform pre-video application processing +} mipi_dsi_event_t; + +/** MIPI DSI Sequence status */ +typedef enum e_mipi_dsi_sequence_status +{ + MIPI_DSI_SEQUENCE_STATUS_NONE = 0X00000000, ///< Sequence status not set + MIPI_DSI_SEQUENCE_STATUS_RUNNING = 0x00000004, ///< Sequence operation in progress + MIPI_DSI_SEQUENCE_STATUS_ACTIONS_FINISHED = 0x00000010, ///< All descriptor actions finished + MIPI_DSI_SEQUENCE_STATUS_DESCRIPTORS_FINISHED = 0x00000100, ///< All descriptors finished + MIPI_DSI_SEQUENCE_STATUS_DESCRIPTOR_ABORT = 0x00010000, ///< Descriptor abort interrupt + MIPI_DSI_SEQUENCE_STATUS_SIZE_ERROR = 0x00080000, ///< Packet size error + MIPI_DSI_SEQUENCE_STATUS_TX_INTERNAL_BUS_ERROR = 0x01000000, ///< Tx internal bus error + MIPI_DSI_SEQUENCE_STATUS_RX_FATAL_ERROR = 0x04800000, ///< Receive fatal error + MIPI_DSI_SEQUENCE_STATUS_RX_FAIL = 0x08000000, ///< Receive fail + MIPI_DSI_SEQUENCE_STATUS_RX_PACKET_DATA_FAIL = 0x10000000, ///< Receive packet data fail + MIPI_DSI_SEQUENCE_STATUS_RX_CORRECTABLE_ERROR = 0x20000000, ///< Receive correctable error + MIPI_DSI_SEQUENCE_STATUS_RX_ACK_AND_ERROR = 0x40000000, ///< Receive acknowledge and error report +} mipi_dsi_sequence_status_t; + +/** MIPI DSI video status errors */ +typedef enum e_mipi_dsi_video_status +{ + MIPI_DSI_VIDEO_STATUS_NONE = 0x00000000, ///< Video status not set + MIPI_DSI_VIDEO_STATUS_START = 0x00000001, ///< Video started event + MIPI_DSI_VIDEO_STATUS_STOP = 0x00000002, ///< Video stopped event + MIPI_DSI_VIDEO_STATUS_RUNNING = 0x00000004, ///< Video running status + MIPI_DSI_VIDEO_STATUS_READY = 0x00000008, ///< Video ready event + MIPI_DSI_VIDEO_STATUS_TIMING_ERROR = 0x00100000, ///< Video timing error event + MIPI_DSI_VIDEO_STATUS_UNDERFLOW = 0x00400000, ///< Video buffer underflow event + MIPI_DSI_VIDEO_STATUS_OVERFLOW = 0x00800000, ///< Video buffer overflow event +} mipi_dsi_video_status_t; + +/** MIPI DSI receive status errors */ +typedef enum e_mipi_dsi_receive_status +{ + MIPI_DSI_RECEIVE_STATUS_NONE = 0x00000000, ///< Receive status not set + MIPI_DSI_RECEIVE_STATUS_BTA_REQUEST_END = 0x00000001, ///< Receive BTA request end + MIPI_DSI_RECEIVE_STATUS_LP_RX_HOST_TIMEOUT = 0x00000002, ///< Receive low power receive timeout + MIPI_DSI_RECEIVE_STATUS_BTA_ACK_TIMEOUT = 0x00000004, ///< Receive BTA ack timeout + MIPI_DSI_RECEIVE_STATUS_RESPONSE_PACKET = 0x00000100, ///< Receive response + MIPI_DSI_RECEIVE_STATUS_EOTP = 0x00000400, ///< Receive end of transmission packet + MIPI_DSI_RECEIVE_STATUS_TEARING_TRIGGER = 0x00002000, ///< Receive tearing trigger + MIPI_DSI_RECEIVE_STATUS_ACK_TRIGGER = 0x00004000, ///< Receive ack trigger + MIPI_DSI_RECEIVE_STATUS_TEARING_DETECT = 0x00008000, ///< Receive tearing detect + MIPI_DSI_RECEIVE_STATUS_MALFORM_ERROR = 0x00010000, ///< Receive malform error + MIPI_DSI_RECEIVE_STATUS_ECC_MULTI = 0x00020000, ///< Receive ecc multi-bit error + MIPI_DSI_RECEIVE_STATUS_UNEXPECTED_PACKET = 0x00040000, ///< Receive unexpected packet + MIPI_DSI_RECEIVE_STATUS_WORD_COUNT = 0x00100000, ///< Receive word count + MIPI_DSI_RECEIVE_STATUS_CRC = 0x00200000, ///< Receive crc error + MIPI_DSI_RECEIVE_STATUS_INTERNAL_BUS = 0x00400000, ///< Receive internal bus error + MIPI_DSI_RECEIVE_STATUS_BUFFER_OVERFLOW = 0x00800000, ///< Receive buffer overflow + MIPI_DSI_RECEIVE_STATUS_TIMEOUT = 0x01000000, ///< Receive timeout + MIPI_DSI_RECEIVE_STATUS_NO_RESPONSE = 0x02000000, ///< Receive no response + MIPI_DSI_RECEIVE_STATUS_PACKET_SIZE = 0x04000000, ///< Receive packet size error + MIPI_DSI_RECEIVE_STATUS_ECC_SINGLE = 0x10000000, ///< Receive ecc single bit error + MIPI_DSI_RECEIVE_STATUS_ACK_AND_ERROR = 0x40000000, ///< Receive ack and error +} mipi_dsi_receive_status_t; + +/** MIPI DSI fatal status errors */ +typedef enum e_mipi_dsi_fatal_status +{ + MIPI_DSI_FATAL_STATUS_NONE = 0x00000000, ///< Fatal status not set + MIPI_DSI_FATAL_STATUS_HS_TX_TIMEOUT = 0x00000001, ///< Fatal high speed transmit timeout + MIPI_DSI_FATAL_STATUS_LP_RX_TIMEOUT = 0x00000002, ///< Fatal low power receive timeout + MIPI_DSI_FATAL_STATUS_BTA_ACK_TIMEOUT = 0x00000004, ///< Fatal BTA ack timeout + MIPI_DSI_FATAL_STATUS_ESCAPE_ENTRY_ERROR = 0x00010000, ///< Fatal escape mode entry error + MIPI_DSI_FATAL_STATUS_LPDT_SYNC_ERROR = 0x00020000, ///< Fatal low power data transmission synchronization error + MIPI_DSI_FATAL_STATUS_CTRL_ERROR = 0x00040000, ///< Fatal control error + MIPI_DSI_FATAL_STATUS_LP0_CONTENTION_DETECT = 0x00080000, ///< Fatal lane 0 low power contention detect + MIPI_DSI_FATAL_STATUS_LP1_CONTENTION_DETECT = 0x00100000, ///< Fatal lane 1 low power contention detect + MIPI_DSI_FATAL_STATUS_LP0_CONTENTION = 0x80000000, ///< Fatal lane 0 low power contention status + MIPI_DSI_FATAL_STATUS_LP1_CONTENTION = 0x10000000, ///< Fatal lane 1 low power contention status +} mipi_dsi_fatal_status_t; + +/** MIPI DSI physical lane status */ +typedef enum e_mipi_dsi_phy_status +{ + MIPI_DSI_PHY_STATUS_NONE = 0x00000000, ///< Physical lane status not set + MIPI_DSI_PHY_STATUS_ULP_NOT_ACTIVE = 0x00000001, ///< Physical lane ULP not active + MIPI_DSI_PHY_STATUS_CLOCK_LANE_STOP = 0x00000002, ///< Clock lane in stopped state + MIPI_DSI_PHY_STATUS_DATA_LANE0_LP_RX = 0x00000004, ///< Data lane low power receive mode + MIPI_DSI_PHY_STATUS_DATA_LANE0_ULP_RX = 0x00000008, ///< Data lane ultra low power receive mode + MIPI_DSI_PHY_STATUS_DATA_LANE0_NOT_ULP = 0x00000010, ///< Data lane 0 not in ULP mode + MIPI_DSI_PHY_STATUS_DATA_LANE1_NOT_ULP = 0x00000020, ///< Data lane 1 not in ULP mode + MIPI_DSI_PHY_STATUS_DATA_LANE2_NOT_ULP = 0x00000040, ///< Data lane 2 not in ULP mode + MIPI_DSI_PHY_STATUS_DATA_LANE3_NOT_ULP = 0x00000080, ///< Data lane 3 not in ULP mode + MIPI_DSI_PHY_STATUS_DATA_LANE0_STOP = 0x00000100, ///< Data lane 0 stop state + MIPI_DSI_PHY_STATUS_DATA_LANE1_STOP = 0x00000200, ///< Data lane 1 stop state + MIPI_DSI_PHY_STATUS_DATA_LANE2_STOP = 0x00000400, ///< Data lane 2 stop state + MIPI_DSI_PHY_STATUS_DATA_LANE3_STOP = 0x00000800, ///< Data lane 3 stop state + MIPI_DSI_PHY_STATUS_DATA_LANE0_RX_TO_TX = 0x00001000, ///< Data lane Rx to Tx transition event + MIPI_DSI_PHY_STATUS_DATA_LANE0_TX_TO_RX = 0x00002000, ///< Data lane Tx to Rx transition event + MIPI_DSI_PHY_STATUS_DATA_LANE0_RX_STATE = 0x00008000, ///< Data lane Rx active state + MIPI_DSI_PHY_STATUS_CLOCK_ULPS_ENTER = 0x01000000, ///< Clock lane ULPS enter event + MIPI_DSI_PHY_STATUS_CLOCK_ULPS_EXIT = 0x02000000, ///< Clock lane ULPS exit event + MIPI_DSI_PHY_STATUS_CLOCK_LP_TO_HS = 0x04000000, ///< Clock lane LP to HS transition event + MIPI_DSI_PHY_STATUS_CLOCK_HS_TO_LP = 0x08000000, ///< Clock lane HS to LP transition event + MIPI_DSI_PHY_STATUS_DATA_LANE_ULPS_ENTER = 0x10000000, ///< Data lane ULPS enter event + MIPI_DSI_PHY_STATUS_DATA_LANE_ULPS_EXIT = 0x20000000, ///< Data lane ULPS exit event +} mipi_dsi_phy_status_t; + +/** MIPI DSI link status bits */ +typedef enum e_mipi_dsi_link_status +{ + MIPI_DSI_LINK_STATUS_IDLE = 0x0000, ///< Link idle or uninitialized + MIPI_DSI_LINK_STATUS_CH0_RUNNING = 0x0001, ///< Channel 0 running + MIPI_DSI_LINK_STATUS_CH1_RUNNING = 0x0010, ///< Channel 1 running + MIPI_DSI_LINK_STATUS_VIDEO_RUNNING = 0x0100, ///< Video output running + MIPI_DSI_LINK_STATUS_HP_MODE_BUSY = 0x1000, ///< HP operation busy + MIPI_DSI_LINK_STATUS_LP_MODE_BUSY = 0x2000, ///< LP operation busy +} mipi_dsi_link_status_t; + +/** MIPI DSI Lane Type */ +typedef enum e_mipi_dsi_lane +{ + MIPI_DSI_LANE_CLOCK = 0x01, ///< Clock Lanes + MIPI_DSI_LANE_DATA_ALL = 0x02, ///< All Data Lanes +} mipi_dsi_lane_t; + +/** MIPI DSI Command */ +typedef struct st_mipi_dsi_cmd +{ + uint8_t channel; ///< Virtual Channel ID + mipi_dsi_cmd_id_t cmd_id; ///< Message ID + mipi_dsi_cmd_flag_t flags; ///< Flags controlling this message transition + uint16_t tx_len; ///< Transmit buffer size + const uint8_t * p_tx_buffer; ///< Transmit buffer pointer + const uint8_t * p_rx_buffer; ///< Receive buffer pointer +} mipi_dsi_cmd_t; + +/** MIPI DSI Acknowledge and Error status type */ +typedef union st_mipi_dsi_ack_err_status_t +{ + __PACKED_STRUCT + { + mipi_dsi_ack_err_t error_report : 16; ///< Error report bits + mipi_dsi_vc_t virtual_channel : 4; ///< Virtual Channel ID + uint32_t : 12; // Padding + }; + uint32_t bits; +} mipi_dsi_ack_err_status_t; + +/** MIPI DSI status type */ +typedef struct st_mipi_dsi_status_t +{ + mipi_dsi_link_status_t link_status; ///< Link status + mipi_dsi_ack_err_status_t ack_err_latest; ///< Latest Acknowledge and Error Report Packet Latest Info + mipi_dsi_ack_err_status_t ack_err_accumulated; ///< Accumulated Acknowledge and Error Report Packet Latest Info +} mipi_dsi_status_t; + +/** MIPI DSI Result */ +typedef __PACKED_STRUCT st_mipi_dsi_result +{ + uint8_t data[2]; ///< Data of received packet header + mipi_dsi_cmd_id_t cmd_id : 6; ///< Data type + uint8_t virtual_channel_id : 2; ///< Virtual channel ID + uint8_t long_packet : 1; ///< Sort packet (0) or Long packet (1) + uint8_t rx_success : 1; ///< Response packet or ack trigger received + uint8_t timeout : 1; ///< Fatal timeout error + uint8_t rx_fail : 1; ///< Expected receive not done + uint8_t rx_data_fail : 1; ///< Receive packet data fail + uint8_t rx_correctable_error : 1; ///< Correctable error detected + uint8_t rx_ack_err : 1; ///< Rx acknowledge and error report packet received + uint8_t info_overwrite : 1; ///< This information was overwritten +} mipi_dsi_receive_result_t; + +/** MIPI DSI callback parameter definition */ +typedef struct st_mipi_dsi_callback_args +{ + mipi_dsi_event_t event; ///< Event code + union + { + mipi_dsi_sequence_status_t tx_status; ///< Sequence status + mipi_dsi_receive_status_t rx_status; ///< Receive status + mipi_dsi_fatal_status_t fatal_status; ///< Fatal status + mipi_dsi_video_status_t video_status; ///< Video status + mipi_dsi_phy_status_t phy_status; ///< Phy Status + }; + mipi_dsi_receive_result_t * p_result; ///< Receive result pointer + void const * p_context; ///< Context provided to user during callback +} mipi_dsi_callback_args_t; + +/** MIPI DSI transition timing */ +typedef struct st_mipi_dsi_timing +{ + uint32_t clock_stop_time; ///< Clock stop time + uint32_t clock_beforehand_time; ///< Clock beforehand time + uint32_t clock_keep_time; ///< Clock Keep time + uint32_t go_lp_and_back; ///< Go LP and Back time +} mipi_dsi_timing_t; + +/** MIPI DSI main configuration structure */ +typedef struct st_mipi_dsi_cfg +{ + mipi_phy_instance_t const * p_mipi_phy_instance; ///< Pointer to mipi physical layer instance + + mipi_dsi_timing_t const * p_timing; ///< Pointer to MIPI DSI timing configuration + + bool hsa_no_lp; ///< Suppress the transition to LP during HSA period and keep HS + bool hbp_no_lp; ///< Suppress the transition to LP during HBP period and keep HS + bool hfp_no_lp; ///< Suppress the transition to LP during HFP period and keep HS + uint8_t num_lanes; ///< Number of MIPI lanes to use. + uint8_t ulps_wakeup_period; ///< ULPS wakeup period + uint8_t continuous_clock; ///< Always run HS clock on/off + uint32_t hs_tx_timeout; ///< HS-Tx Timeout value + uint32_t lp_rx_timeout; ///< LP-Rx host processor timeout + uint32_t turnaround_timeout; ///< Turnaround Acknowledge Timeout + uint32_t bta_timeout; ///< Peripheral Response Timeout + uint32_t lprw_timeout; ///< LP Read and Write Timeouts + uint32_t hsrw_timeout; ///< HS Read and Write Timeouts + uint32_t max_return_packet_size; ///< Maximum return packet size + bool ecc_enable; ///< ECC Check enable + mipi_dsi_vc_t crc_check_mask; ///< Virtual channel CRC check enable + bool scramble_enable; ///< Scramble on/off + bool tearing_detect; ///< External tearing effect detection mode (0:rising, 1:falling edge) + bool eotp_enable; ///< End of Transmit Packet (EoTP) on/off + bool sync_pulse; ///< Enable for Non-Burst Mode with Sync Pulse sequence + mipi_dsi_video_data_t data_type; ///< Video mode data type: 16-bit RGB, 18-bit RGB, 24-bit RGB + uint8_t virtual_channel_id; ///< Video mode virtual channel to use (from 0x0 to 0x3) + uint32_t vertical_sync_lines; ///< Number of vertical sync active lines + bool vertical_sync_polarity; ///< V-Sync Polarity + uint32_t vertical_active_lines; ///< Number of vertical active lines + uint32_t vertical_back_porch; ///< Vertical back porch + uint32_t vertical_front_porch; ///< Vertical front porch + uint32_t horizontal_sync_lines; ///< Number of horizontal sync active lines + bool horizontal_sync_polarity; ///< H-Sync Polarity + uint32_t horizontal_active_lines; ///< Number of horizontal active lines + uint32_t horizontal_back_porch; ///< Horizontal back porch + uint32_t horizontal_front_porch; ///< Horizontal front porch + uint32_t video_mode_delay; + + /** Callback configuration */ + void (* p_callback)(mipi_dsi_callback_args_t * p_args); ///< Pointer to callback function + void const * p_context; ///< User defined context passed into callback function + + /** Pointer to display peripheral specific configuration */ + void const * p_extend; ///< MIPI hardware dependent configuration +} mipi_dsi_cfg_t; + +/** MIPI DSI control block. Allocate an instance specific control block to pass into the MIPI DSI API calls. */ +typedef void mipi_dsi_ctrl_t; + +/** Shared Interface definition for MIPI DSI peripheral */ +typedef struct st_mipi_dsi_api +{ + /** Open MIPI DSI device. + * + * @param[in,out] p_ctrl Pointer to MIPI DSI interface control block. Must be declared by user. Value set here. + * @param[in] p_cfg Pointer to MIPI DSI configuration structure. All elements of this structure must be set by user. + */ + fsp_err_t (* open)(mipi_dsi_ctrl_t * const p_ctrl, mipi_dsi_cfg_t const * const p_cfg); + + /** Close MIPI DSI device. + * + * @param[in] p_ctrl Pointer to MIPI DSI interface control block. + */ + fsp_err_t (* close)(mipi_dsi_ctrl_t * const p_ctrl); + + /** Start pixel data output. + * + * @param[in] p_ctrl Pointer to MIPI DSI interface control block. + */ + fsp_err_t (* start)(mipi_dsi_ctrl_t * const p_ctrl); + + /** Stop pixel data output. + * + * @param[in] p_ctrl Pointer to MIPI DSI interface control block. + */ + fsp_err_t (* stop)(mipi_dsi_ctrl_t * const p_ctrl); + + /** Enter Ultra-low Power State (ULPS). + * + * @param[in] p_ctrl Pointer to MIPI DSI interface control block. + * @param[in] lane Physical lane(s) to transition into ULPS + */ + fsp_err_t (* ulpsEnter)(mipi_dsi_ctrl_t * const p_ctrl, mipi_dsi_lane_t lane); + + /** Exit Ultra-low Power State (ULPS). + * + * @param[in] p_ctrl Pointer to MIPI DSI interface control block. + * @param[in] lane Physical lane(s) to transition from ULPS + */ + fsp_err_t (* ulpsExit)(mipi_dsi_ctrl_t * const p_ctrl, mipi_dsi_lane_t lane); + + /** Send a command to the display. + * + * @param[in] p_ctrl Pointer to MIPI DSI interface control block. + * @param[in] p_cmd Pointer to a command structure + */ + fsp_err_t (* command)(mipi_dsi_ctrl_t * const p_api_ctrl, mipi_dsi_cmd_t * p_cmd); + + /** Get status of MIPI link. + * + * @param[in] p_ctrl Pointer to MIPI DSI interface control block. + * @param[in] p_status Pointer to MIPI DSI interface status structure. + */ + fsp_err_t (* statusGet)(mipi_dsi_ctrl_t * const p_ctrl, mipi_dsi_status_t * p_status); +} mipi_dsi_api_t; + +/** This structure encompasses everything that is needed to use an instance of this interface. */ +typedef struct st_mipi_dsi_instance +{ + mipi_dsi_ctrl_t * p_ctrl; ///< Pointer to the control structure for this instance + mipi_dsi_cfg_t const * p_cfg; ///< Pointer to the configuration structure for this instance + mipi_dsi_api_t const * p_api; ///< Pointer to the API structure for this instance +} mipi_dsi_instance_t; + +/* @} (end defgroup MIPI_DSI_API) */ + +/* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ +FSP_FOOTER +#endif diff --git a/drivers/rz/fsp/inc/instances/rza/r_lcdc.h b/drivers/rz/fsp/inc/instances/rza/r_lcdc.h new file mode 100644 index 00000000..14b68d83 --- /dev/null +++ b/drivers/rz/fsp/inc/instances/rza/r_lcdc.h @@ -0,0 +1,94 @@ +/* +* Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +/*******************************************************************************************************************//** + * @addtogroup LCDC + * @{ + **********************************************************************************************************************/ +#ifndef R_LCDC_H_ +#define R_LCDC_H_ + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ +#include "bsp_api.h" +#include "r_display_api.h" + +/*********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ + +/** LCDC hardware specific configuration */ +typedef struct st_lcdc_extended_cfg +{ + uint8_t frame_end_ipl; ///< Frame end interrupt priority + uint8_t underrun_ipl; ///< Under run interrupt priority + IRQn_Type frame_end_irq; ///< Frame end interrupt vector + IRQn_Type underrun_irq; ///< Under run interrupt vector +} lcdc_extended_cfg_t; + +/* CRU context struct for callback function */ +typedef struct st_display_ctrl +{ + void const * p_context; +} lcdc_ctrl_t; + +/** Display control block. DO NOT INITIALIZE. */ +typedef struct st_lcdc_instance_ctrl +{ + display_state_t state; // Status of LCDC module + + /* Parameters to Event processing for display devices */ + void (* p_callback)(display_callback_args_t * p_args); // Pointer to callback function + void const * p_context; // Pointer to the higher level device context + const display_cfg_t * p_cfg; // Pointer to initial configurations +} lcdc_instance_ctrl_t; + +/********************************************************************************************************************** + * Exported global variables + **********************************************************************************************************************/ +extern const display_api_t g_display_on_lcdc; + +/** @cond INC_HEADER_DEFS_SEC */ + +/** @endcond */ + +/*********************************************************************************************************************** + * Public APIs + **********************************************************************************************************************/ +fsp_err_t R_LCDC_Open(display_ctrl_t * const p_api_ctrl, display_cfg_t const * const p_cfg); +fsp_err_t R_LCDC_Close(display_ctrl_t * const p_api_ctrl); +fsp_err_t R_LCDC_Start(display_ctrl_t * const p_api_ctrl); +fsp_err_t R_LCDC_Stop(display_ctrl_t * const p_api_ctrl); +fsp_err_t R_LCDC_LayerChange(display_ctrl_t const * const p_api_ctrl, + display_runtime_cfg_t const * const p_cfg, + display_frame_layer_t layer); +fsp_err_t R_LCDC_BufferChange(display_ctrl_t const * const p_api_ctrl, + uint8_t * const framebuffer, + display_frame_layer_t layer); +fsp_err_t R_LCDC_ColorCorrection(display_ctrl_t const * const p_api_ctrl, + display_correction_t const * const p_correction); +fsp_err_t R_LCDC_ClutUpdate(display_ctrl_t const * const p_api_ctrl, + display_clut_cfg_t const * const p_clut_cfg, + display_frame_layer_t layer); +fsp_err_t R_LCDC_ClutEdit(display_ctrl_t const * const p_api_ctrl, + display_frame_layer_t layer, + uint8_t index, + uint32_t color); +fsp_err_t R_LCDC_ColorKeySet(display_ctrl_t const * const p_api_ctrl, + display_colorkeying_layer_t ck_cfg, + display_frame_layer_t layer); +fsp_err_t R_LCDC_StatusGet(display_ctrl_t const * const p_api_ctrl, display_status_t * const p_status); + +/*******************************************************************************************************************//** + * @} (end defgroup LCDC) + **********************************************************************************************************************/ + +#endif /* R_LCDC_H_ */ diff --git a/drivers/rz/fsp/inc/instances/rza/r_mipi_dsi_b.h b/drivers/rz/fsp/inc/instances/rza/r_mipi_dsi_b.h new file mode 100644 index 00000000..a5fd63fb --- /dev/null +++ b/drivers/rz/fsp/inc/instances/rza/r_mipi_dsi_b.h @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef R_MIPI_DSI_B_H +#define R_MIPI_DSI_B_H + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ + +#include "bsp_api.h" +#include "r_mipi_dsi_api.h" + +/* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ +FSP_HEADER + +/*******************************************************************************************************************//** + * @addtogroup MIPI_DSI_B + * @{ + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ +typedef enum e_mipi_dsi_clock_state +{ + MIPI_DSI_CLOCK_STATE_IDLE, ///< MIPI DSI Clock is off + MIPI_DSI_CLOCK_STATE_STARTING, ///< MIPI DSI Clock starting + MIPI_DSI_CLOCK_STATE_STARTED, ///< MIPI DSI Clock is started + MIPI_DSI_CLOCK_STATE_STOPPING, ///< MIPI DSI Clock is stopping +} mipi_dsi_clock_state_t; + +/** MIPI DSI interrupt configuration */ +typedef struct st_mipi_dsi_b_irq_cfg +{ + uint8_t ipl; ///< Interrupt priority + IRQn_Type irq; ///< Interrupt vector number +} mipi_dsi_b_irq_cfg_t; + +/** Extended configuration structure for MIPI DSI. */ +typedef struct st_mipi_dsi_b_extended_cfg +{ + /* Interrupt configuration */ + mipi_dsi_b_irq_cfg_t dsi_seq0; ///< Sequence 0 interrupt + mipi_dsi_b_irq_cfg_t dsi_seq1; ///< Sequence 1 interrupt + mipi_dsi_b_irq_cfg_t dsi_ferr; ///< DSI Fatal Error interrupt + mipi_dsi_b_irq_cfg_t dsi_ppi; ///< D-PHY PPI interrupt + mipi_dsi_b_irq_cfg_t dsi_rcv; ///< Receive interrupt + mipi_dsi_b_irq_cfg_t dsi_vin1; ///< Video Input Operation interrupt + + uint32_t dsi_rxie; ///< Receive interrupt enable configuration + uint32_t dsi_ferrie; ///< Fatal error interrupt enable configuration + uint32_t dsi_plie; ///< Physical lane interrupt enable configuration + uint32_t dsi_vmie; ///< Video mode interrupt enable configuration + uint32_t dsi_sqch0ie; ///< Sequence Channel 0 interrupt enable configuration + uint32_t dsi_sqch1ie; ///< Sequence Channel 1 interrupt enable configuration +} mipi_dsi_b_extended_cfg_t; + +/** MIPI DSI instance control block. */ +typedef struct st_mipi_dsi_b_instance_ctrl +{ + uint32_t open; ///< Interface is open + bool data_ulps_active; ///< Data lane ULPS status + bool clock_ulps_active; ///< Data lane ULPS status + bool video_started; ///< If video started or not + mipi_dsi_clock_state_t clock_state; ///< Clock state + mipi_dsi_lane_t ulps_status; ///< Ultra-low Power State active status + mipi_dsi_cfg_t const * p_cfg; ///< Pointer to configuration structure used to open the interface + void (* p_callback)(mipi_dsi_callback_args_t *); ///< Pointer to callback that is called when an adc_event_t occurs. + void const * p_context; ///< Pointer to context to be passed into callback function + mipi_dsi_callback_args_t * p_callback_memory; ///< Pointer to non-secure memory that can be used to pass arguments to a callback in non-secure memory. +} mipi_dsi_b_instance_ctrl_t; + +/********************************************************************************************************************** + * Exported global variables + **********************************************************************************************************************/ + +/** @cond INC_HEADER_DEFS_SEC */ +/** Filled in Interface API structure for this Instance. */ +extern const mipi_dsi_api_t g_mipi_dsi; + +/** @endcond */ + +/*********************************************************************************************************************** + * Exported global functions (to be accessed by other files) + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Public APIs + **********************************************************************************************************************/ +fsp_err_t R_MIPI_DSI_B_Open(mipi_dsi_ctrl_t * const p_api_ctrl, mipi_dsi_cfg_t const * const p_cfg); +fsp_err_t R_MIPI_DSI_B_Close(mipi_dsi_ctrl_t * const p_api_ctrl); +fsp_err_t R_MIPI_DSI_B_Start(mipi_dsi_ctrl_t * const p_api_ctrl); +fsp_err_t R_MIPI_DSI_B_UlpsEnter(mipi_dsi_ctrl_t * const p_api_ctrl, mipi_dsi_lane_t lane); +fsp_err_t R_MIPI_DSI_B_UlpsExit(mipi_dsi_ctrl_t * const p_api_ctrl, mipi_dsi_lane_t lane); +fsp_err_t R_MIPI_DSI_B_Stop(mipi_dsi_ctrl_t * const p_api_ctrl); +fsp_err_t R_MIPI_DSI_B_Command(mipi_dsi_ctrl_t * const p_api_ctrl, mipi_dsi_cmd_t * p_cmd); +fsp_err_t R_MIPI_DSI_B_StatusGet(mipi_dsi_ctrl_t * const p_api_ctrl, mipi_dsi_status_t * p_status); + +/*******************************************************************************************************************//** + * @} (end defgroup MIPI_DSI_B) + **********************************************************************************************************************/ + +/* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ +FSP_FOOTER + +#endif // R_MIPI_DSI_B_H diff --git a/drivers/rz/fsp/inc/instances/rza/r_mipi_phy.h b/drivers/rz/fsp/inc/instances/rza/r_mipi_phy.h new file mode 100644 index 00000000..96019623 --- /dev/null +++ b/drivers/rz/fsp/inc/instances/rza/r_mipi_phy.h @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef R_MIPI_PHY_H +#define R_MIPI_PHY_H + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ + +#include "r_mipi_phy_b.h" + +/* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ +FSP_HEADER + +/*********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ + +/********************************************************************************************************************** + * Exported global variables + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Exported global functions (to be accessed by other files) + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Instance Functions (Note: This is not a public API and should not be called directly) + **********************************************************************************************************************/ + +/* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ + FSP_FOOTER + +#endif // R_MIPI_PHY_H diff --git a/drivers/rz/fsp/inc/instances/rza/r_mipi_phy_b.h b/drivers/rz/fsp/inc/instances/rza/r_mipi_phy_b.h new file mode 100644 index 00000000..35d90527 --- /dev/null +++ b/drivers/rz/fsp/inc/instances/rza/r_mipi_phy_b.h @@ -0,0 +1,105 @@ +/* +* Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef R_MIPI_PHY_B_H +#define R_MIPI_PHY_B_H + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ + +#include "bsp_api.h" + +/* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ +FSP_HEADER + +/*********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif + +/*********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ + +/** MIPI PHY D-PHY power mode transition timing */ +typedef struct st_mipi_phy_b_timing +{ + uint32_t t_init; ///< Minimum duration of the TINIT state (Units: PCLKA cycles) + uint8_t t_clk_prep; ///< Duration of the clock lane LP-00 state (immediately before entry to the HS-0 state) + uint8_t t_hs_prep; ///< Duration of the data lane LP-00 state (immediately before entry to the HS-0 state) + uint8_t t_clk_zero; ///< TCLKZERO setting. + uint8_t t_clk_pre; ///< TCLKPRE setting. + uint8_t t_clk_post; ///< TCLKPOST setting. + uint8_t t_clk_trail; ///< TCLKTRAIL setting. + uint8_t t_hs_zero; ///< THSZERO setting. + uint8_t t_hs_trail; ///< THSTRAIL setting. + uint8_t t_hs_exit; ///< THSEXIT setting. + uint8_t t_lp_exit; ///< Low-power transition time to High-Speed mode +} mipi_phy_b_timing_t; + +/** MIPI_PHY configuration structure. */ +typedef struct st_mipi_phy_b_cfg +{ + mipi_phy_b_timing_t const * p_timing; ///< Pointer to D-PHY HS/LP transition timing values +} mipi_phy_b_cfg_t; + +/** MIPI_PHY instance control block. */ +typedef struct st_mipi_phy_b_ctrl +{ + uint32_t open; + mipi_phy_b_cfg_t const * p_cfg; +} mipi_phy_b_ctrl_t; + +/** Private Interface definition for MIPI PHY peripheral */ +typedef struct st_mipi_phy_b_api +{ + /** Open MIPI PHY device. + * @param[in,out] p_ctrl Pointer to MIPI PHY interface control block. + * @param[in] p_cfg Pointer to MIPI PHY configuration structure. + */ + fsp_err_t (* open)(mipi_phy_b_ctrl_t * const p_ctrl, mipi_phy_b_cfg_t const * const p_cfg); + + /** Close MIPI PHY device. + * @param[in] p_ctrl Pointer to MIPI PHY interface control block. + */ + fsp_err_t (* close)(mipi_phy_b_ctrl_t * const p_ctrl); +} mipi_phy_b_api_t; + +/** This structure encompasses everything that is needed to use an instance of this interface. */ +typedef struct st_mipi_phy_b_instance +{ + mipi_phy_b_ctrl_t * p_ctrl; ///< Pointer to the control structure for this instance + mipi_phy_b_cfg_t const * p_cfg; ///< Pointer to the configuration structure for this instance + mipi_phy_b_api_t const * p_api; ///< Pointer to the API structure for this instance +} mipi_phy_instance_t; + +/********************************************************************************************************************** + * Exported global variables + **********************************************************************************************************************/ + +/** @cond INC_HEADER_DEFS_SEC */ +/** Filled in Interface API structure for this Instance. */ +extern const mipi_phy_b_api_t g_mipi_phy; + +/** @endcond */ + +/*********************************************************************************************************************** + * Exported global functions (to be accessed by other files) + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Instance Functions (Note: This is not a public API and should not be called directly) + **********************************************************************************************************************/ +fsp_err_t r_mipi_phy_b_open(mipi_phy_b_ctrl_t * const p_api_ctrl, mipi_phy_b_cfg_t const * const p_cfg); +fsp_err_t r_mipi_phy_b_close(mipi_phy_b_ctrl_t * const p_api_ctrl); + +/* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ +FSP_FOOTER + +#endif // R_MIPI_PHY_B_H diff --git a/drivers/rz/fsp/src/rza/bsp/mcu/rza3m/bsp_feature.h b/drivers/rz/fsp/src/rza/bsp/mcu/rza3m/bsp_feature.h index 9c2a7af0..be718f43 100644 --- a/drivers/rz/fsp/src/rza/bsp/mcu/rza3m/bsp_feature.h +++ b/drivers/rz/fsp/src/rza/bsp/mcu/rza3m/bsp_feature.h @@ -27,7 +27,7 @@ * Private global variables and functions **********************************************************************************************************************/ -#define BSP_FEATURE_BSP_HAS_MMU_SUPPORT (1) +#define BSP_FEATURE_BSP_HAS_MMU_SUPPORT (0) #define BSP_FEATURE_BSP_HAS_MIPI_DSI (1U) diff --git a/drivers/rz/fsp/src/rza/r_lcdc/r_lcdc.c b/drivers/rz/fsp/src/rza/r_lcdc/r_lcdc.c new file mode 100644 index 00000000..e1f80290 --- /dev/null +++ b/drivers/rz/fsp/src/rza/r_lcdc/r_lcdc.c @@ -0,0 +1,1474 @@ +/* +* Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ +#include "r_lcdc.h" +#include "bsp_api.h" +#include "r_lcdc_cfg.h" + +/*********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ + +#define LCDC_DU_PBCR0 (0x0000001F) +#define LCDC_VSPD_CLK_CTRL0 (0x00000000) +#define LCDC_VSPD_CLK_CTRL1 (0x00000000) +#define LCDC_VSPD_CLK_DCSWT (0x00000808) +#define LCDC_VSPD_CLK_DCSM0 (0x00000000) +#define LCDC_VSPD_CLK_DCSM1 (0x00000000) +#define LCDC_VSPD_DL_CTRL (0x0100) +#define LCDC_VSPD_LIF_CTRL_OBTH (0x5DC) +#define LCDC_VSPD_LIF_CTRL_LBA1 (0x600) +#define LCDC_VSPD_DL_BODY_SIZE (200) +#define LCDC_VSPD_DPR_RPF0_ROUTE_RT_RPF0 (0x26) +#define LCDC_VSPD_DPR_RPF0_ROUTE_RT_RPF1 (0x27) +#define LCDC_VSPD_DPR_WPF0_FPROCH (0x05) +#define LCDC_VSPD_DPR_LUT_ROUTE (0x3F) +#define LCDC_VSPD_DPR_ILV_BRS_ROUTE_BRSSEL (1) +#define LCDC_VSPD_DPR_ILV_BRS_ROUTE_RT (0x38) +#define LCDC_VSPD_BRSA_CTRL_RBC (1) +#define LCDC_VSPD_BRSA_CTRL_DSTSEL (1) +#define LCDC_VSPD_BRSB_CTRL_SRCSEL (4) +#define LCDC_VSPD_BRSA_BLD_CCMDX (0) +#define LCDC_VSPD_BRSA_BLD_CCMDY (1) +#define LCDC_VSPD_BRSB_BLD_CCMDX (1) +#define LCDC_VSPD_BRSB_BLD_CCMDY (3) + +#define LAYER_STATUS_INIT (0x02000000) +#define LAYER_ENABLE_1 (0x02000001) +#define LAYER_ENABLE_2 (0x02000004) +#define LAYER_ENABLE_ALL (0x02000005) +#define LAYER_DISABLE_1 (0x02000004) +#define LAYER_DISABLE_2 (0x02000001) +#define LAYER_DISABLE_ALL (0x02000000) +#define COLOR_FOTMAT_CONVERT (0x00000100) + +#define TIMING_MAX_H (1920) +#define TIMING_MAX_V (1280) +#define LAYER_MAX_HSIZE (1280) +#define LAYER_MAX_VSIZE (1280) +#define LAYER_MAX_HCOOR (1280) +#define LAYER_MAX_VCOOR (1280) + +#define CAST_TO_UINT32 (0xFFFFFFFFU) +#define DL_NUM_CMD (25) + +/*********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ +typedef struct +{ + uint32_t set_address; + uint32_t set_data; +} set_address_data_t; + +typedef struct +{ + set_address_data_t cmd[DL_NUM_CMD]; +} display_list_data_type; + +/*********************************************************************************************************************** + * Private function prototypes + **********************************************************************************************************************/ +static void r_lcdc_du_set(display_cfg_t const * const p_cfg); +static void r_lcdc_clock_set(void); +static void r_lcdc_dl_set(void); +static void r_lcdc_dl_address_set(display_cfg_t const * const p_cfg); +static void r_lcdc_layer1_set(display_cfg_t const * const p_cfg); +static void r_lcdc_layer2_set(display_cfg_t const * const p_cfg); +static void r_lcdc_output_set(display_cfg_t const * const p_cfg); +static void r_lcdc_dpr_set(void); +static void r_lcdc_brs_set(void); +static void r_lcdc_layer_change(display_runtime_cfg_t const * const p_cfg, display_frame_layer_t layer); +static void r_lcdc_ckey_set(display_colorkeying_layer_t ck_cfg, display_frame_layer_t layer); +static void r_lcdc_interrupt_enable(display_cfg_t const * const p_cfg, lcdc_instance_ctrl_t * const p_instance_ctrl); +void lcdc_vspd_int(IRQn_Type const irq); + +#if (LCDC_CFG_PARAM_CHECKING_ENABLE) +static fsp_err_t r_lcdc_open_param_check(display_cfg_t const * const p_cfg); +static fsp_err_t r_lcdc_open_param_check_sync_signal(display_cfg_t const * const p_cfg); +static fsp_err_t r_lcdc_open_param_check_display_cycle(display_cfg_t const * const p_cfg); +static fsp_err_t r_lcdc_open_param_check_layer_setting(display_cfg_t const * const p_cfg); + +#endif + +/*********************************************************************************************************************** + * Private global variables + **********************************************************************************************************************/ +const display_api_t g_display_on_lcdc = +{ + .open = R_LCDC_Open, + .close = R_LCDC_Close, + .start = R_LCDC_Start, + .stop = R_LCDC_Stop, + .layerChange = R_LCDC_LayerChange, + .bufferChange = R_LCDC_BufferChange, + .clut = R_LCDC_ClutUpdate, + .clutEdit = R_LCDC_ClutEdit, + .correction = R_LCDC_ColorCorrection, + .colorKeySet = R_LCDC_ColorKeySet, + .statusGet = R_LCDC_StatusGet, +}; + +static const uint32_t display_format_table[] = +{ + /* This table is used for Color Format setting + * If you selected RGB565 as input format, 0x00000006 is written to the RDFMT bits in VI6_RPFn_INFMT */ + + /* Common input format */ + 0x00000013, /* ARGB8888, 32 bits */ + 0x00000000, /* RGB888, 32 bits */ + 0x00000006, /* RGB565, 16 bits */ + 0x00000000, /* ARGB1555 16 bits */ + 0x00000000, /* ARGB4444 16 bits */ + 0x00000000, /* CLUT8 */ + 0x00000000, /* CLUT4 */ + 0x00000000, /* CLUT1 */ + /* Extend input format */ + 0x00000014, /* RGBA8888, 24 bits */ + 0x00000015, /* RGB888, 24 bits */ + 0x00000018, /* BGR888, 24 bits */ + 0x00000022, /* ABGR8888, 24 bits */ + 0x00000146, /* YCbCr444 interleaved, 24 bits */ + 0x00000147, /* YCbCr422 interleaved type0 UYVY, 16 bits */ + 0x00008147, /* YCbCr422 interleaved type0 YUY2, 16 bits */ + 0x0000C147, /* YCbCr422 interleaved type0 YVYU, 16 bits */ + 0x00000148, /* YCbCr420 interleaved type1, 16 bits */ + 0x00000149, /* YCbCr420 interleaved, 16 bits */ + 0x0000014C, /* YCbCr420 Planar 16 bits */ +}; + +static lcdc_ctrl_t r_lcdc_blk = +{ + .p_context = NULL, +}; + +static display_list_data_type dl_body __attribute__((section(".nocache"), __aligned__(16))); +static uint32_t layer_status; + +/*********************************************************************************************************************** + * Global Variables + **********************************************************************************************************************/ + +/*******************************************************************************************************************//** + * + * @addtogroup LCDC + * @{ + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Functions + **********************************************************************************************************************/ + +/*******************************************************************************************************************//** + * Initializes the LCDC modules and enables interrupts + * + * @retval FSP_SUCCESS Initializes the LCDC modules. + * @retval FSP_ERR_ALREADY_OPEN LCDC module is open already. + * @retval FSP_ERR_ASSERTION Pointer to the control block is NULL. + * @retval FSP_ERR_INVALID_TIMING_SETTING Invalid timing parameter. + * @retval FSP_ERR_INVALID_LAYER_SETTING Invalid layer parameter. + **********************************************************************************************************************/ +fsp_err_t R_LCDC_Open (display_ctrl_t * const p_api_ctrl, display_cfg_t const * const p_cfg) +{ + fsp_err_t err = FSP_SUCCESS; + lcdc_instance_ctrl_t * p_ctrl = (lcdc_instance_ctrl_t *) p_api_ctrl; + + p_ctrl->p_cfg = p_cfg; + p_ctrl->p_context = p_cfg->p_context; + p_ctrl->p_callback = p_cfg->p_callback; + r_lcdc_blk.p_context = p_ctrl; + +#if (LCDC_CFG_PARAM_CHECKING_ENABLE) + + /* Check parameters */ + FSP_ASSERT(p_ctrl); + FSP_ERROR_RETURN(p_ctrl->state <= DISPLAY_STATE_CLOSED, FSP_ERR_ALREADY_OPEN); + err = r_lcdc_open_param_check(p_cfg); + if (FSP_SUCCESS != err) + { + return err; + } +#endif + R_BSP_MODULE_START(FSP_IP_LCDC, 0); + + /* FCPVD processing mode */ + R_LCDC->FCP_CFG0_b.FCPVSEL = 0; + + /* DU Initialization */ + r_lcdc_du_set(p_cfg); + + /* Clock Setting */ + r_lcdc_clock_set(); + + /* Display IRQ Setting */ + /* Interrupt Enable for Display Start */ + R_LCDC->VI6_DISP0_IRQ_STA_b.MAE = 1; + + /* Interrupt Enable for Display Read Data End */ + R_LCDC->VI6_DISP0_IRQ_STA_b.DST = 1; + + /* Enable LCDC Interrupt */ + r_lcdc_interrupt_enable(p_cfg, p_api_ctrl); + + /* Initialize Layer Status */ + layer_status = LAYER_STATUS_INIT; + + /* Layer 1 Setting (RPF0) */ + r_lcdc_layer1_set(p_cfg); + + /* Layer 2 Setting (RPF1) */ + r_lcdc_layer2_set(p_cfg); + + /* Output Setting */ + r_lcdc_output_set(p_cfg); + + /* Display List Initialization */ + r_lcdc_dl_set(); + + /* Display List Body Address Set */ + r_lcdc_dl_address_set(p_cfg); + + /* LIF Setting */ + /* Always specify 1500 */ + R_LCDC->VI6_LIF0_CTRL_b.OBTH = LCDC_VSPD_LIF_CTRL_OBTH; + + /* DU is selected as the destination external display module */ + R_LCDC->VI6_LIF0_CTRL_b.REQSEL = 1; + + /* Data output to the external display module is enabled */ + R_LCDC->VI6_LIF0_CTRL_b.LIF_EN = 1; + + /* Always specify 1 */ + R_LCDC->VI6_LIF0_LBA_b.LBA0 = 1; + + /* Always specify 1536 */ + R_LCDC->VI6_LIF0_LBA_b.LBA1 = LCDC_VSPD_LIF_CTRL_LBA1; + + /* DPR Setting */ + r_lcdc_dpr_set(); + + /* BRS Setting */ + r_lcdc_brs_set(); + + /* Start WPF */ + R_LCDC->VI6_CMD0_b.STRCMD = 1; + while (R_LCDC->VI6_DISP0_IRQ_STA_b.DST == 0) + { + /* + * No Operation + */ + } + + R_LCDC->DU_MCR0_b.DI_EN = 1; + + p_ctrl->state = DISPLAY_STATE_OPENED; + + return err; +} + +/*******************************************************************************************************************//** + * Close the display while the LCDC module is operating + * + * @retval FSP_SUCCESS Close the LCDC module + * @retval FSP_ERR_ASSERTION Pointer to the control block is NULL. + * @retval FSP_ERR_NOT_OPEN LCDC module is not open + **********************************************************************************************************************/ +fsp_err_t R_LCDC_Close (display_ctrl_t * const p_api_ctrl) +{ + lcdc_instance_ctrl_t * p_ctrl = (lcdc_instance_ctrl_t *) p_api_ctrl; + fsp_err_t err = FSP_SUCCESS; + +#if (LCDC_CFG_PARAM_CHECKING_ENABLE) + FSP_ASSERT(p_ctrl); + FSP_ERROR_RETURN(DISPLAY_STATE_CLOSED != p_ctrl->state, FSP_ERR_NOT_OPEN); +#endif + + /* Display Disable */ + R_LCDC->DU_MCR0_b.DI_EN = 0; + while (R_LCDC->DU_MSR0_b.ST_DI_BSY == 1) + { + /* + * No Operation + */ + } + + /* Software Reset */ + R_LCDC->VI6_SRESET_b.SRST0 = 1; + while (R_LCDC->VI6_WPF0_IRQ_STA_b.FRE == 0) + { + /* + * No Operation + */ + } + + p_ctrl->state = DISPLAY_STATE_CLOSED; + + return err; +} + +/*******************************************************************************************************************//** + * Start displaying a layer image. It is possible when LCDC state is open + * + * @retval FSP_SUCCESS Start display Normally + * @retval FSP_ERR_ASSERTION Pointer to the control block is NULL. + * @retval FSP_ERR_NOT_OPEN LCDC module is not open + **********************************************************************************************************************/ +fsp_err_t R_LCDC_Start (display_ctrl_t * const p_api_ctrl) +{ + lcdc_instance_ctrl_t * p_ctrl = (lcdc_instance_ctrl_t *) p_api_ctrl; + fsp_err_t err = FSP_SUCCESS; + +#if (LCDC_CFG_PARAM_CHECKING_ENABLE) + FSP_ASSERT(p_ctrl); + FSP_ERROR_RETURN(DISPLAY_STATE_OPENED == p_ctrl->state, FSP_ERR_NOT_OPEN); +#endif + + /* Set Data to Display List Body */ + dl_body.cmd[0].set_data = layer_status; + + /* Display List Update */ + R_LCDC->VI6_DL_BODY_SIZE0_b.UPD0 = 1; + + p_ctrl->state = DISPLAY_STATE_DISPLAYING; + + return err; +} + +/*******************************************************************************************************************//** + * Start displaying a layer image. It is possible when LCDC state is displaying + * + * @retval FSP_SUCCESS Stop the LCDC module + * @retval FSP_ERR_ASSERTION Pointer to the control block is NULL. + * @retval FSP_ERR_INVALID_MODE LCDC module status is invalid for R_LCDC_Stop API + **********************************************************************************************************************/ +fsp_err_t R_LCDC_Stop (display_ctrl_t * const p_api_ctrl) +{ + lcdc_instance_ctrl_t * p_ctrl = (lcdc_instance_ctrl_t *) p_api_ctrl; + fsp_err_t err = FSP_SUCCESS; + +#if (LCDC_CFG_PARAM_CHECKING_ENABLE) + FSP_ASSERT(p_ctrl); + FSP_ERROR_RETURN((DISPLAY_STATE_DISPLAYING == p_ctrl->state), FSP_ERR_INVALID_MODE); +#endif + + /* Disable All Layers */ + layer_status &= LAYER_DISABLE_ALL; + + /* Set data to Display List body */ + dl_body.cmd[0].set_data = layer_status; + + /* Display List Update */ + R_LCDC->VI6_DL_BODY_SIZE0_b.UPD0 = 1; + + if (!(layer_status)) + { + p_ctrl->state = DISPLAY_STATE_OPENED; + } + else + { + /* Do Nothing */ + } + + return err; +} + +/*******************************************************************************************************************//** + * Change layer configurations. It is possible when LCDC state is displaying + * + * @retval FSP_SUCCESS The LCDC layer is changed + * @retval FSP_ERR_INVALID_LAYER_SETTING Invalid layer parameter + * @retval FSP_ERR_ASSERTION Pointer to the control block and configuration structure is NULL. + * @retval FSP_ERR_INVALID_MODE LCDC module status is invalid for R_LCDC_LayerChange API + **********************************************************************************************************************/ +fsp_err_t R_LCDC_LayerChange (display_ctrl_t const * const p_api_ctrl, + display_runtime_cfg_t const * const p_cfg, + display_frame_layer_t layer) +{ + lcdc_instance_ctrl_t * p_ctrl = (lcdc_instance_ctrl_t *) p_api_ctrl; + FSP_PARAMETER_NOT_USED(p_ctrl); + +#if (LCDC_CFG_PARAM_CHECKING_ENABLE) + FSP_ASSERT(p_ctrl); + FSP_ASSERT(p_cfg); + FSP_ERROR_RETURN((DISPLAY_STATE_DISPLAYING == p_ctrl->state), FSP_ERR_INVALID_MODE); +#endif + + /* Check Layer runtime parameter */ + FSP_ERROR_RETURN((p_cfg->input.hsize <= LAYER_MAX_HSIZE), FSP_ERR_INVALID_LAYER_SETTING); + FSP_ERROR_RETURN((p_cfg->input.vsize <= LAYER_MAX_VSIZE), FSP_ERR_INVALID_LAYER_SETTING); + FSP_ERROR_RETURN((p_cfg->input.coordinate_x <= LAYER_MAX_HCOOR), FSP_ERR_INVALID_LAYER_SETTING); + FSP_ERROR_RETURN((p_cfg->input.coordinate_y <= LAYER_MAX_VCOOR), FSP_ERR_INVALID_LAYER_SETTING); + + /* Check layer number */ + FSP_ERROR_RETURN((layer == 0 || layer == 1), FSP_ERR_INVALID_LAYER_SETTING); + + /* Change Layer Parameters */ + r_lcdc_layer_change(p_cfg, layer); + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Change Buffer configuration. It is possible when LCDC state is displaying + * + * @retval FSP_SUCCESS The Buffer read by LCDC is changed + * @retval FSP_ERR_INVALID_LAYER_SETTING Invalid layer parameter + * @retval FSP_ERR_ASSERTION Pointer to the control block is NULL. + * @retval FSP_ERR_INVALID_MODE LCDC module status is invalid for R_LCDC_BufferChange API + **********************************************************************************************************************/ +fsp_err_t R_LCDC_BufferChange (display_ctrl_t const * const p_api_ctrl, + uint8_t * const framebuffer, + display_frame_layer_t layer) +{ + lcdc_instance_ctrl_t * p_ctrl = (lcdc_instance_ctrl_t *) p_api_ctrl; + FSP_PARAMETER_NOT_USED(p_ctrl); + +#if (LCDC_CFG_PARAM_CHECKING_ENABLE) + FSP_ASSERT(p_ctrl); + FSP_ERROR_RETURN((DISPLAY_STATE_DISPLAYING == p_ctrl->state), FSP_ERR_INVALID_MODE); +#endif + +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + uint64_t pa; /* Physical Address */ + uint64_t va; /* Virtual Address */ +#endif + + /* Check layer number */ + FSP_ERROR_RETURN((layer == 0 || layer == 1), FSP_ERR_INVALID_LAYER_SETTING); + + /* Display List Setting */ + /* Set data to Display List Body */ + if (layer == DISPLAY_FRAME_LAYER_1) + { + if (framebuffer == NULL) + { + /* Disable Layer1 (RPF0) */ + layer_status &= LAYER_DISABLE_1; + } + else + { + /* Enable Layer1 (RPF0) */ + layer_status |= LAYER_ENABLE_1; + } + + /* Set layer1's buffer address to Display List Body */ + /* Set physical address of buffer to descriptor */ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + va = (uint64_t) framebuffer & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[1].set_data = pa & CAST_TO_UINT32; +#else + dl_body.cmd[1].set_data = (uint64_t) framebuffer & CAST_TO_UINT32; +#endif + } + else if (layer == DISPLAY_FRAME_LAYER_2) + { + if (framebuffer == NULL) + { + /* Disable Layer1 (RPF0) */ + layer_status &= LAYER_DISABLE_2; + } + else + { + /* Enable Layer1 (RPF0) */ + layer_status |= LAYER_ENABLE_2; + } + + /* Set layer2's buffer address to Display List Body */ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + va = (uint64_t) framebuffer & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[11].set_data = pa & CAST_TO_UINT32; +#else + dl_body.cmd[11].set_data = (uint64_t) framebuffer & CAST_TO_UINT32; +#endif + + // dl_body.cmd[11].set_data = (uint64_t) framebuffer & CAST_TO_UINT32; + } + else + { + /* Do Nothing */ + } + + /* Set Data to Display List Body */ + dl_body.cmd[0].set_data = layer_status; + + /* Display List Update */ + R_LCDC->VI6_DL_BODY_SIZE0_b.UPD0 = 1; + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Placeholder for unsupported color correction function. Implements display_api_t::correction. + * + * @retval FSP_ERR_UNSUPPORTED Color correction is not supported. + **********************************************************************************************************************/ +fsp_err_t R_LCDC_ColorCorrection (display_ctrl_t const * const p_api_ctrl, + display_correction_t const * const p_correction) +{ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(p_correction); + + return FSP_ERR_UNSUPPORTED; +} + +/*******************************************************************************************************************//** + * Placeholder for unsupported CLUT update function. Implements display_api_t::clut. + * + * @retval FSP_ERR_UNSUPPORTED CLUT update is not supported. + **********************************************************************************************************************/ +fsp_err_t R_LCDC_ClutUpdate (display_ctrl_t const * const p_api_ctrl, + display_clut_cfg_t const * const p_clut_cfg, + display_frame_layer_t layer) +{ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(p_clut_cfg); + FSP_PARAMETER_NOT_USED(layer); + + return FSP_ERR_UNSUPPORTED; +} + +/*******************************************************************************************************************//** + * Placeholder for unsupported CLUT edit function. Implements display_api_t::clutEdit. + * + * @retval FSP_ERR_UNSUPPORTED CLUT edit is not supported. + **********************************************************************************************************************/ +fsp_err_t R_LCDC_ClutEdit (display_ctrl_t const * const p_api_ctrl, + display_frame_layer_t layer, + uint8_t index, + uint32_t color) +{ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(layer); + FSP_PARAMETER_NOT_USED(index); + FSP_PARAMETER_NOT_USED(color); + + return FSP_ERR_UNSUPPORTED; +} + +/*******************************************************************************************************************//** + * Set the Color Keying Configuration. It is possible when LCDC state is displaying. + * + * @retval FSP_SUCCESS The source color is changed to destination color + * @retval FSP_ERR_INVALID_LAYER_SETTING Invalid layer parameter + * @retval FSP_ERR_ASSERTION Pointer to the control block is NULL. + * @retval FSP_ERR_INVALID_MODE LCDC module status is invalid for R_LCDC_ColorKeying API + **********************************************************************************************************************/ +fsp_err_t R_LCDC_ColorKeySet (display_ctrl_t const * const p_api_ctrl, + display_colorkeying_layer_t ck_cfg, + display_frame_layer_t layer) +{ + lcdc_instance_ctrl_t * p_ctrl = (lcdc_instance_ctrl_t *) p_api_ctrl; + FSP_PARAMETER_NOT_USED(p_ctrl); + +#if (LCDC_CFG_PARAM_CHECKING_ENABLE) + FSP_ASSERT(p_ctrl); + FSP_ERROR_RETURN((DISPLAY_STATE_DISPLAYING == p_ctrl->state), FSP_ERR_INVALID_MODE); +#endif + + /* Check layer number */ + FSP_ERROR_RETURN((layer == 0 || layer == 1), FSP_ERR_INVALID_LAYER_SETTING); + + /* Color Keying */ + r_lcdc_ckey_set(ck_cfg, layer); + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Get the current status of LCDC module. (close or open or displaying) + * + * @retval FSP_SUCCESS Get status of LCDC module + * @retval FSP_ERR_ASSERTION Pointer to the control block and status structure is NULL. + **********************************************************************************************************************/ +fsp_err_t R_LCDC_StatusGet (display_ctrl_t const * const p_api_ctrl, display_status_t * const p_status) +{ + lcdc_instance_ctrl_t * p_ctrl = (lcdc_instance_ctrl_t *) p_api_ctrl; + FSP_PARAMETER_NOT_USED(p_ctrl); + +#if (LCDC_CFG_PARAM_CHECKING_ENABLE) + FSP_ASSERT(p_ctrl); + FSP_ASSERT(p_status); +#endif + + p_status->state = p_ctrl->state; + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * @} (end addtogroup IOPORT) + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Private Functions + **********************************************************************************************************************/ + +/*******************************************************************************************************************//** + * Display Unit setting function. This function can set signal timing setting. + * + * @param[in] p_cfg LCDC configuration parameters. + * @retval none + **********************************************************************************************************************/ +static void r_lcdc_du_set (display_cfg_t const * const p_cfg) +{ + static uint32_t h_fp; + static uint32_t h_bp; + static uint32_t h_active; + static uint32_t h_sa; + static uint32_t v_fp; + static uint32_t v_bp; + static uint32_t v_active; + static uint32_t v_sa; + + if (p_cfg->output.data_enable_polarity == DISPLAY_SIGNAL_POLARITY_LOACTIVE) + { + /* DE output mode */ + R_LCDC->DU_DITR0_b.DEMD = 0; + } + else + { + /* Do Nothing */ + } + + if (p_cfg->output.htiming.sync_polarity == DISPLAY_SIGNAL_POLARITY_LOACTIVE) + { + /* hsync polarity */ + R_LCDC->DU_DITR0_b.HSPOL = 0; + } + else + { + /* Do Nothing */ + } + + if (p_cfg->output.vtiming.sync_polarity == DISPLAY_SIGNAL_POLARITY_LOACTIVE) + { + /* vsync polarity */ + R_LCDC->DU_DITR0_b.VSPOL = 0; + } + else + { + /* Do Nothing */ + } + + if (p_cfg->output.sync_edge == DISPLAY_SIGNAL_SYNC_EDGE_FALLING) + { + /* Display parallel interface clock mode */ + R_LCDC->DU_DITR0_b.DPI_CLKMD = 1; + } + else + { + /* Do Nothing */ + } + + h_active = (p_cfg->output.htiming.display_cyc); + h_sa = (p_cfg->output.htiming.sync_width); + h_bp = (uint32_t) (p_cfg->output.htiming.back_porch - p_cfg->output.htiming.sync_width); + h_fp = + (uint32_t) (p_cfg->output.htiming.total_cyc - p_cfg->output.htiming.back_porch - + p_cfg->output.htiming.display_cyc); + v_active = p_cfg->output.vtiming.display_cyc; + v_sa = p_cfg->output.vtiming.sync_width; + v_bp = (uint32_t) (p_cfg->output.vtiming.back_porch - p_cfg->output.vtiming.sync_width); + v_fp = + (uint32_t) (p_cfg->output.vtiming.total_cyc - p_cfg->output.vtiming.back_porch - + p_cfg->output.vtiming.display_cyc); + + R_LCDC->DU_DITR3 = h_active << 16 | h_sa; + R_LCDC->DU_DITR4 = h_fp << 16 | h_bp; + R_LCDC->DU_DITR1 = v_active << 16 | v_sa; + R_LCDC->DU_DITR2 = v_fp << 16 | v_bp; + + /* Fixed value */ + R_LCDC->DU_PBCR0 = LCDC_DU_PBCR0; +} + +/*******************************************************************************************************************//** + * Subroutine to configure dot clock setting + * + * @retval none + **********************************************************************************************************************/ +static void r_lcdc_clock_set (void) +{ + /* Fixed value */ + R_LCDC->VI6_CLK_CTRL0 = LCDC_VSPD_CLK_CTRL0; + R_LCDC->VI6_CLK_CTRL1 = LCDC_VSPD_CLK_CTRL1; + R_LCDC->VI6_CLK_DCSWT = LCDC_VSPD_CLK_DCSWT; + R_LCDC->VI6_CLK_DCSM0 = LCDC_VSPD_CLK_DCSM0; + R_LCDC->VI6_CLK_DCSM1 = LCDC_VSPD_CLK_DCSM1; +} + +/*******************************************************************************************************************//** + * Display list setting. + * + * @retval none + **********************************************************************************************************************/ +static void r_lcdc_dl_set (void) +{ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + uint64_t pa; /* Physical Address */ + uint64_t va; /* Virtual Address */ +#endif + + /* Fixed Value */ + R_LCDC->VI6_DL_CTRL_b.AR_WAIT = LCDC_VSPD_DL_CTRL; + + /* These bits doesn’t affect anything to VSPD */ + R_LCDC->VI6_DL_CTRL_b.DC2 = 1; + R_LCDC->VI6_DL_CTRL_b.DC1 = 1; + R_LCDC->VI6_DL_CTRL_b.DLE1 = 1; + + /* The next frame is automatically started */ + R_LCDC->VI6_DL_CTRL_b.CFM0 = 1; + + /* Don’t use Display List Header (Header-less Mode) */ + R_LCDC->VI6_DL_CTRL_b.NH0 = 1; + + /* The display list function is enabled */ + R_LCDC->VI6_DL_CTRL_b.DLE0 = 1; + + /* Display lsit body size setting */ + R_LCDC->VI6_DL_BODY_SIZE0_b.BS0 = LCDC_VSPD_DL_BODY_SIZE; + + /* Always specify 2 */ + R_LCDC->VI6_DL_EXT_CTRL0_b.POLINT = 0x02; + + /* Always specify 1. */ + R_LCDC->VI6_DL_EXT_CTRL0_b.DLPRI = 1; + + /* Display List Header Address */ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + va = (uint64_t) (&dl_body) & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + R_LCDC->VI6_DL_HDR_ADDR0 = pa & CAST_TO_UINT32; +#else + R_LCDC->VI6_DL_HDR_ADDR0 = (uint64_t) (&dl_body) & CAST_TO_UINT32; +#endif + + /* Data swapping in long word (32-bit) units is enabled */ + R_LCDC->VI6_DL_SWAP0_b.LWS = 1; +} + +/*******************************************************************************************************************//** + * Display List address setting. + * + * @param[in] p_cfg LCDC configuration parameters + * @retval none + **********************************************************************************************************************/ +static void r_lcdc_dl_address_set (display_cfg_t const * const p_cfg) +{ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + uint64_t pa; /* Physical Address */ + uint64_t va; /* Virtual Address */ +#endif + + /* set Display List Body address */ + dl_body.cmd[0].set_address = (uint64_t) (&(R_LCDC->VI6_WPF0_SRCRPF)) & CAST_TO_UINT32; + dl_body.cmd[1].set_address = (uint64_t) (&(R_LCDC->VI6_RPF0_SRCM_ADDR_Y)) & CAST_TO_UINT32; + dl_body.cmd[2].set_address = (uint64_t) (&(R_LCDC->VI6_RPF0_INFMT)) & CAST_TO_UINT32; + dl_body.cmd[3].set_address = (uint64_t) (&(R_LCDC->VI6_RPF0_SRC_BSIZE)) & CAST_TO_UINT32; + dl_body.cmd[4].set_address = (uint64_t) (&(R_LCDC->VI6_RPF0_SRC_ESIZE)) & CAST_TO_UINT32; + dl_body.cmd[5].set_address = (uint64_t) (&(R_LCDC->VI6_RPF0_SRCM_PSTRIDE)) & CAST_TO_UINT32; + dl_body.cmd[6].set_address = (uint64_t) (&(R_LCDC->VI6_RPF0_LOC)) & CAST_TO_UINT32; + dl_body.cmd[7].set_address = (uint64_t) (&(R_LCDC->VI6_RPF0_DSWAP)) & CAST_TO_UINT32; + dl_body.cmd[8].set_address = (uint64_t) (&(R_LCDC->VI6_RPF0_CKEY_CTRL)) & CAST_TO_UINT32; + dl_body.cmd[9].set_address = (uint64_t) (&(R_LCDC->VI6_RPF0_CKEY_SET0)) & CAST_TO_UINT32; + dl_body.cmd[10].set_address = (uint64_t) (&(R_LCDC->VI6_RPF0_CKEY_SET1)) & CAST_TO_UINT32; + dl_body.cmd[11].set_address = (uint64_t) (&(R_LCDC->VI6_RPF1_SRCM_ADDR_Y)) & CAST_TO_UINT32; + dl_body.cmd[12].set_address = (uint64_t) (&(R_LCDC->VI6_RPF1_INFMT)) & CAST_TO_UINT32; + dl_body.cmd[13].set_address = (uint64_t) (&(R_LCDC->VI6_RPF1_SRC_BSIZE)) & CAST_TO_UINT32; + dl_body.cmd[14].set_address = (uint64_t) (&(R_LCDC->VI6_RPF1_SRC_ESIZE)) & CAST_TO_UINT32; + dl_body.cmd[15].set_address = (uint64_t) (&(R_LCDC->VI6_RPF1_SRCM_PSTRIDE)) & CAST_TO_UINT32; + dl_body.cmd[16].set_address = (uint64_t) (&(R_LCDC->VI6_RPF1_LOC)) & CAST_TO_UINT32; + dl_body.cmd[17].set_address = (uint64_t) (&(R_LCDC->VI6_RPF1_DSWAP)) & CAST_TO_UINT32; + dl_body.cmd[18].set_address = (uint64_t) (&(R_LCDC->VI6_RPF1_CKEY_CTRL)) & CAST_TO_UINT32; + dl_body.cmd[19].set_address = (uint64_t) (&(R_LCDC->VI6_RPF1_CKEY_SET0)) & CAST_TO_UINT32; + dl_body.cmd[20].set_address = (uint64_t) (&(R_LCDC->VI6_RPF1_CKEY_SET1)) & CAST_TO_UINT32; + dl_body.cmd[21].set_address = (uint64_t) (&(R_LCDC->VI6_RPF0_SRCM_ADDR_C0)) & CAST_TO_UINT32; + dl_body.cmd[22].set_address = (uint64_t) (&(R_LCDC->VI6_RPF0_SRCM_ADDR_C1)) & CAST_TO_UINT32; + dl_body.cmd[23].set_address = (uint64_t) (&(R_LCDC->VI6_RPF1_SRCM_ADDR_C0)) & CAST_TO_UINT32; + dl_body.cmd[24].set_address = (uint64_t) (&(R_LCDC->VI6_RPF1_SRCM_ADDR_C1)) & CAST_TO_UINT32; + + /* set Display List Body data */ + dl_body.cmd[0].set_data = LAYER_STATUS_INIT; + + /* Set physical address of buffer to descriptor */ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + va = (uint64_t) (p_cfg->input[0].p_base) & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[1].set_data = pa & CAST_TO_UINT32; +#else + dl_body.cmd[1].set_data = (uint64_t) (p_cfg->input[0].p_base) & CAST_TO_UINT32; +#endif + dl_body.cmd[2].set_data = display_format_table[p_cfg->input[0].format]; + + /* input format : RGB - output format : YCbCr */ + if ((p_cfg->input[0].format <= 5) && ((p_cfg->output.format) >= 6)) + { + dl_body.cmd[2].set_data |= COLOR_FOTMAT_CONVERT; + } + /* input format : YCbCr - output format : RGB */ + else if ((p_cfg->output.format <= 5) && ((p_cfg->input[0].format) >= 6)) + { + dl_body.cmd[2].set_data |= COLOR_FOTMAT_CONVERT; + } + else + { + /* Do Nothing */ + } + + dl_body.cmd[3].set_data = (uint32_t) ((p_cfg->input[0].hsize << 16) + p_cfg->input[0].vsize); + dl_body.cmd[4].set_data = (uint32_t) ((p_cfg->input[0].hsize << 16) + p_cfg->input[0].vsize); + dl_body.cmd[5].set_data = (uint32_t) ((p_cfg->input[0].hstride) << 16 | (p_cfg->input[0].hstride_cbcr)); + dl_body.cmd[6].set_data = (uint32_t) ((p_cfg->input[0].coordinate_x << 16) + p_cfg->input[0].coordinate_y); + dl_body.cmd[7].set_data = (uint32_t) (p_cfg->input[0].data_swap); + dl_body.cmd[8].set_data = 0; + dl_body.cmd[9].set_data = 0; + dl_body.cmd[10].set_data = 0; + + /* Set physical address of buffer to descriptor */ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + va = (uint64_t) (p_cfg->input[1].p_base) & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[11].set_data = pa & CAST_TO_UINT32; +#else + dl_body.cmd[11].set_data = (uint64_t) (p_cfg->input[1].p_base) & CAST_TO_UINT32; +#endif + + dl_body.cmd[12].set_data = display_format_table[p_cfg->input[1].format]; + + /* input format : RGB - output format : YCbCr */ + if ((p_cfg->input[1].format <= 5) && ((p_cfg->output.format) >= 6)) + { + dl_body.cmd[12].set_data |= COLOR_FOTMAT_CONVERT; + } + /* input format : YCbCr - output format : RGB */ + else if ((p_cfg->output.format <= 5) && ((p_cfg->input[1].format) >= 6)) + { + dl_body.cmd[12].set_data |= COLOR_FOTMAT_CONVERT; + } + else + { + /* Do Nothing */ + } + + dl_body.cmd[13].set_data = (uint32_t) ((p_cfg->input[1].hsize << 16) + p_cfg->input[1].vsize); + dl_body.cmd[14].set_data = (uint32_t) ((p_cfg->input[1].hsize << 16) + p_cfg->input[1].vsize); + dl_body.cmd[15].set_data = (uint32_t) ((p_cfg->input[1].hstride) << 16 | (p_cfg->input[1].hstride)); + dl_body.cmd[16].set_data = (uint32_t) ((p_cfg->input[1].coordinate_x << 16) + p_cfg->input[1].coordinate_y); + dl_body.cmd[17].set_data = (uint32_t) (p_cfg->input[1].data_swap); + dl_body.cmd[18].set_data = 0; + dl_body.cmd[19].set_data = 0; + dl_body.cmd[20].set_data = 0; + + /* Set physical address of buffer to descriptor */ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + va = (uint64_t) (p_cfg->input[0].p_base_cb) & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[21].set_data = pa & CAST_TO_UINT32; + + va = (uint64_t) (p_cfg->input[0].p_base_cr) & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[22].set_data = pa & CAST_TO_UINT32; + + va = (uint64_t) (p_cfg->input[1].p_base_cb) & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[23].set_data = pa & CAST_TO_UINT32; + + va = (uint64_t) (p_cfg->input[1].p_base_cr) & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[24].set_data = pa & CAST_TO_UINT32; +#else + dl_body.cmd[21].set_data = (uint64_t) (p_cfg->input[0].p_base_cb) & CAST_TO_UINT32; + dl_body.cmd[22].set_data = (uint64_t) (p_cfg->input[0].p_base_cr) & CAST_TO_UINT32; + dl_body.cmd[23].set_data = (uint64_t) (p_cfg->input[1].p_base_cb) & CAST_TO_UINT32; + dl_body.cmd[24].set_data = (uint64_t) (p_cfg->input[1].p_base_cr) & CAST_TO_UINT32; +#endif +} + +/*******************************************************************************************************************//** + * Display for Layer1 settings. + * + * @param[in] p_cfg LCDC configuration parameters + * @retval none + **********************************************************************************************************************/ +static void r_lcdc_layer1_set (display_cfg_t const * const p_cfg) +{ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + uint64_t pa; /* Physical Address */ + uint64_t va; /* Virtual Address */ +#endif + static uint32_t hsize; + static uint32_t vsize; + static uint32_t coor_x; + static uint32_t coor_y; + + /* Format Setting */ + R_LCDC->VI6_RPF0_INFMT = display_format_table[p_cfg->input[0].format]; + + /* Size Setting */ + hsize = (uint32_t) p_cfg->input[0].hsize; + vsize = (uint32_t) p_cfg->input[0].vsize; + R_LCDC->VI6_RPF0_SRC_BSIZE = hsize << 16 | vsize; + R_LCDC->VI6_RPF0_SRC_ESIZE = hsize << 16 | vsize; + + /* Stride Setting */ + R_LCDC->VI6_RPF0_SRCM_PSTRIDE_b.PICT_STRD_Y = p_cfg->input[0].hstride; + R_LCDC->VI6_RPF0_SRCM_PSTRIDE_b.PICT_STRD_C = p_cfg->input[0].hstride_cbcr; + + /* Location Setting */ + coor_x = (uint32_t) p_cfg->input[0].coordinate_x; + coor_y = (uint32_t) p_cfg->input[0].coordinate_y; + R_LCDC->VI6_RPF0_LOC = coor_x << 16 | coor_y; + + /* Buffer address Setting */ + /* Set physical address of buffer to descriptor */ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + va = (uint64_t) p_cfg->input[0].p_base & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + R_LCDC->VI6_RPF0_SRCM_ADDR_Y = pa & CAST_TO_UINT32; + + va = (uint64_t) p_cfg->input[0].p_base_cb & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + R_LCDC->VI6_RPF0_SRCM_ADDR_C0 = pa & CAST_TO_UINT32; + + va = (uint64_t) p_cfg->input[0].p_base_cr & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + R_LCDC->VI6_RPF0_SRCM_ADDR_C1 = pa & CAST_TO_UINT32; +#else + R_LCDC->VI6_RPF0_SRCM_ADDR_Y = (uint64_t) p_cfg->input[0].p_base & CAST_TO_UINT32; + R_LCDC->VI6_RPF0_SRCM_ADDR_C0 = (uint64_t) p_cfg->input[0].p_base_cb & CAST_TO_UINT32; + R_LCDC->VI6_RPF0_SRCM_ADDR_C1 = (uint64_t) p_cfg->input[0].p_base_cr & CAST_TO_UINT32; +#endif + + /* Alpha Setting (RPF0 Alpha data is 0x00) */ + R_LCDC->VI6_RPF0_ALPH_SEL_b.ASEL = 0; + + /* Swap Setting */ + R_LCDC->VI6_RPF0_DSWAP = p_cfg->input[0].data_swap; + + if (p_cfg->input[0].p_base == NULL) + { + /* Disable Layer1 (RPF0) */ + layer_status &= LAYER_DISABLE_1; + } + else + { + /* Enable layer1 (RPF0) */ + layer_status |= LAYER_ENABLE_1; + } +} + +/*******************************************************************************************************************//** + * Display for Layer2 settings. + * + * @param[in] p_cfg LCDC configuration parameters + * @retval none + **********************************************************************************************************************/ +static void r_lcdc_layer2_set (display_cfg_t const * const p_cfg) +{ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + uint64_t pa; /* Physical Address */ + uint64_t va; /* Virtual Address */ +#endif + static uint32_t hsize; + static uint32_t vsize; + static uint32_t coor_x; + static uint32_t coor_y; + + /* Format Setting */ + R_LCDC->VI6_RPF1_INFMT = display_format_table[p_cfg->input[1].format]; + + /* Size Setting */ + hsize = (uint32_t) p_cfg->input[1].hsize; + vsize = (uint32_t) p_cfg->input[1].vsize; + R_LCDC->VI6_RPF1_SRC_BSIZE = hsize << 16 | vsize; + R_LCDC->VI6_RPF1_SRC_ESIZE = hsize << 16 | vsize; + + /* Stride Setting */ + R_LCDC->VI6_RPF1_SRCM_PSTRIDE_b.PICT_STRD_Y = p_cfg->input[1].hstride; + R_LCDC->VI6_RPF1_SRCM_PSTRIDE_b.PICT_STRD_C = p_cfg->input[1].hstride_cbcr; + + /* Location Setting */ + coor_x = (uint32_t) p_cfg->input[1].coordinate_x; + coor_y = (uint32_t) p_cfg->input[1].coordinate_y; + R_LCDC->VI6_RPF1_LOC = coor_x << 16 | coor_y; + + /* Buffer address Setting */ + /* Set physical address of buffer to descriptor */ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + va = (uint64_t) p_cfg->input[1].p_base & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + R_LCDC->VI6_RPF1_SRCM_ADDR_Y = pa & CAST_TO_UINT32; + + va = (uint64_t) p_cfg->input[1].p_base_cb & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + R_LCDC->VI6_RPF1_SRCM_ADDR_C0 = pa & CAST_TO_UINT32; + + va = (uint64_t) p_cfg->input[1].p_base_cr & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + R_LCDC->VI6_RPF1_SRCM_ADDR_C1 = pa & CAST_TO_UINT32; +#else + R_LCDC->VI6_RPF1_SRCM_ADDR_Y = (uint64_t) p_cfg->input[1].p_base & CAST_TO_UINT32; + R_LCDC->VI6_RPF1_SRCM_ADDR_C0 = (uint64_t) p_cfg->input[1].p_base_cb & CAST_TO_UINT32; + R_LCDC->VI6_RPF1_SRCM_ADDR_C1 = (uint64_t) p_cfg->input[1].p_base_cr & CAST_TO_UINT32; +#endif + + /* Alpha Setting */ + R_LCDC->VI6_RPF1_ALPH_SEL_b.ASEL = 0; + + /* Swap Setting */ + R_LCDC->VI6_RPF1_DSWAP = p_cfg->input[1].data_swap; + + if (p_cfg->input[1].p_base == NULL) + { + /* Disable Layer1 (RPF0) */ + layer_status &= LAYER_DISABLE_2; + } + else + { + /* Enable layer1 (RPF0) */ + layer_status |= LAYER_ENABLE_2; + } +} + +/*******************************************************************************************************************//** + * LCDC output settings + * + * @param[in] p_cfg LCDC configuration parameters + * @retval none + **********************************************************************************************************************/ +static void r_lcdc_output_set (display_cfg_t const * const p_cfg) +{ + static uint32_t hsize; + static uint32_t vsize; + + /* WPF IRQ Setting */ + R_LCDC->VI6_WPF0_IRQ_ENB_b.DFEE = 0; + R_LCDC->VI6_WPF0_IRQ_ENB_b.FREE = 1; + + /*Background layer Setting */ + R_LCDC->VI6_WPF0_SRCRPF = LAYER_DISABLE_ALL; + + /* Format Setting */ + R_LCDC->VI6_WPF0_OUTFMT = display_format_table[p_cfg->output.format]; + + /* Dithering Setting */ + R_LCDC->VI6_WPF0_OUTFMT |= + (uint32_t) ((((p_cfg->output.dithering_on) << 13) | ((p_cfg->output.dithering_on) << 12))); + + /* Background Color Setting */ + hsize = (uint32_t) p_cfg->output.htiming.display_cyc; + vsize = (uint32_t) p_cfg->output.vtiming.display_cyc; + R_LCDC->VI6_BRS_VIRRPF_SIZE = hsize << 16 | vsize; + + /* Set Background Layer Location */ + R_LCDC->VI6_BRS_VIRRPF_LOC = 0x00000000; + R_LCDC->VI6_BRS_VIRRPF_COL = p_cfg->output.bg_color.argb; + + /* Write Back setting */ + R_LCDC->VI6_WPF0_WRBCK_CTRL_b.WBMD = 0; +} + +/*******************************************************************************************************************//** + * Data Path Router settings. Select using modules. + * + * @retval none + **********************************************************************************************************************/ +static void r_lcdc_dpr_set (void) +{ + /* RPF0 -> BRSin0 */ + R_LCDC->VI6_DPR_RPF0_ROUTE_b.RT_RPF0 = LCDC_VSPD_DPR_RPF0_ROUTE_RT_RPF0; + + /* RPF1 -> BRSin1 */ + R_LCDC->VI6_DPR_RPF1_ROUTE_b.RT_RPF1 = LCDC_VSPD_DPR_RPF0_ROUTE_RT_RPF1; + + /* Fixed Value */ + R_LCDC->VI6_DPR_WPF0_FPORCH_b.FP_WPF0 = LCDC_VSPD_DPR_WPF0_FPROCH; + + /* Not Use LUT */ + R_LCDC->VI6_DPR_LUT_ROUTE_b.RT = LCDC_VSPD_DPR_LUT_ROUTE; + + /* Fixed Value */ + R_LCDC->VI6_DPR_ILV_BRS_ROUTE_b.BRSSEL = LCDC_VSPD_DPR_ILV_BRS_ROUTE_BRSSEL; + + /* BRS -> WPF0 */ + R_LCDC->VI6_DPR_ILV_BRS_ROUTE_b.RT = LCDC_VSPD_DPR_ILV_BRS_ROUTE_RT; +} + +/*******************************************************************************************************************//** + * Blend ROP Sub unit settings. Select ROP or alpha blending. + * + * @retval none + **********************************************************************************************************************/ +static void r_lcdc_brs_set (void) +{ + /*Blending operation in RPF0 and RPF1 */ + R_LCDC->VI6_BRSA_CTRL_b.RBC = LCDC_VSPD_BRSA_CTRL_RBC; + + /* BRS input 1 (BRSin1) is input to DST */ + R_LCDC->VI6_BRSA_CTRL_b.DSTSEL = LCDC_VSPD_BRSA_CTRL_DSTSEL; + + /* BRS input 0 (BRSin0) is input to SRC */ + R_LCDC->VI6_BRSA_CTRL_b.SRCSEL = 0x0; + + /* ROP (raster operation) */ + R_LCDC->VI6_BRSB_CTRL_b.RBC = 0; + + /* BRS input 0 (BRSin0) is input to DST */ + R_LCDC->VI6_BRSB_CTRL_b.DSTSEL = 0x1; + + /* Virtual RPF is input to SRC */ + R_LCDC->VI6_BRSB_CTRL_b.SRCSEL = LCDC_VSPD_BRSB_CTRL_SRCSEL; + + /* Blending Expression : */ + R_LCDC->VI6_BRSA_BLD_b.CBES = 0; + + /* (blending coefficient X) = (DST α data) */ + R_LCDC->VI6_BRSA_BLD_b.CCMDX = LCDC_VSPD_BRSA_BLD_CCMDX; + + /* (blending coefficient Y) = 255 - (DST α data) */ + R_LCDC->VI6_BRSA_BLD_b.CCMDY = LCDC_VSPD_BRSA_BLD_CCMDY; + + /* Blending α Creation Expression : X * (DST α data) + Y * (SRC α data) */ + R_LCDC->VI6_BRSA_BLD_b.ABES = 0; + + /* (α creation coefficient X) = 255 - (DST α data) */ + R_LCDC->VI6_BRSA_BLD_b.ACMDX = LCDC_VSPD_BRSB_BLD_CCMDX; + + /* (α creation coefficient Y) = 255 - (SRC α data) */ + R_LCDC->VI6_BRSA_BLD_b.ACMDY = LCDC_VSPD_BRSB_BLD_CCMDY; +} + +/*******************************************************************************************************************//** + * Change selected layer configuration + * + * @param[in] p_cfg LCDC configuration parameters + * @param[in] layer selected layer number + * @retval none + **********************************************************************************************************************/ +static void r_lcdc_layer_change (display_runtime_cfg_t const * const p_cfg, display_frame_layer_t layer) +{ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + uint64_t pa; /* Physical Address */ + uint64_t va; /* Virtual Address */ +#endif + + /* Display List Body Setting */ + /* Change Layer Setting */ + if (layer == DISPLAY_FRAME_LAYER_1) + { + if (p_cfg->input.p_base == NULL) + { + /* Disable Layer1 (RPF0) */ + layer_status &= LAYER_DISABLE_1; + } + else + { + /* Enable Layer1 (RPF0) */ + layer_status |= LAYER_ENABLE_1; + } + + /* Set physical address of buffer to descriptor */ +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + va = (uint64_t) (p_cfg->input.p_base) & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[1].set_data = pa & CAST_TO_UINT32; +#else + dl_body.cmd[1].set_data = (uint64_t) (p_cfg->input.p_base) & CAST_TO_UINT32; +#endif + dl_body.cmd[2].set_data = display_format_table[p_cfg->input.format]; + dl_body.cmd[3].set_data = (uint32_t) ((p_cfg->input.hsize << 16) + p_cfg->input.vsize); + dl_body.cmd[4].set_data = (uint32_t) ((p_cfg->input.hsize << 16) + p_cfg->input.vsize); + dl_body.cmd[5].set_data = (uint32_t) (((p_cfg->input.hstride) << 16) | (p_cfg->input.hstride_cbcr)); + dl_body.cmd[6].set_data = (uint32_t) ((p_cfg->input.coordinate_x << 16) + p_cfg->input.coordinate_y); + dl_body.cmd[7].set_data = (uint32_t) (p_cfg->input.data_swap); +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + va = (uint64_t) (p_cfg->input.p_base_cb) & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[21].set_data = pa & CAST_TO_UINT32; + + va = (uint64_t) (p_cfg->input.p_base_cr) & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[22].set_data = pa & CAST_TO_UINT32; +#else + dl_body.cmd[21].set_data = (uint64_t) (p_cfg->input.p_base_cb) & CAST_TO_UINT32; + dl_body.cmd[22].set_data = (uint64_t) (p_cfg->input.p_base_cr) & CAST_TO_UINT32; +#endif + } + else if (layer == DISPLAY_FRAME_LAYER_2) + { + if (p_cfg->input.p_base == NULL) + { + /* Disable Layer1 (RPF0) */ + layer_status &= LAYER_DISABLE_2; + } + else + { + /* Enable Layer1 (RPF0) */ + layer_status |= LAYER_ENABLE_2; + } + +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + va = (uint64_t) (p_cfg->input.p_base) & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[11].set_data = pa & CAST_TO_UINT32; +#else + dl_body.cmd[11].set_data = (uint64_t) (p_cfg->input.p_base) & CAST_TO_UINT32; +#endif + dl_body.cmd[12].set_data = display_format_table[p_cfg->input.format]; + dl_body.cmd[13].set_data = (uint32_t) ((p_cfg->input.hsize << 16) + p_cfg->input.vsize); + dl_body.cmd[14].set_data = (uint32_t) ((p_cfg->input.hsize << 16) + p_cfg->input.vsize); + dl_body.cmd[15].set_data = (uint32_t) (((p_cfg->input.hstride) << 16) | (p_cfg->input.hstride_cbcr)); + dl_body.cmd[16].set_data = (uint32_t) ((p_cfg->input.coordinate_x << 16) + p_cfg->input.coordinate_y); + dl_body.cmd[17].set_data = (uint32_t) (p_cfg->input.data_swap); +#if (BSP_FEATURE_BSP_HAS_MMU_SUPPORT) + va = (uint64_t) (p_cfg->input.p_base_cb) & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[23].set_data = pa & CAST_TO_UINT32; + + va = (uint64_t) (p_cfg->input.p_base_cr) & CAST_TO_UINT32; + R_MMU_VAtoPA(&g_mmu_ctrl, va, (void *) &pa); + dl_body.cmd[24].set_data = pa & CAST_TO_UINT32; +#else + dl_body.cmd[23].set_data = (uint64_t) (p_cfg->input.p_base_cb) & CAST_TO_UINT32; + dl_body.cmd[24].set_data = (uint64_t) (p_cfg->input.p_base_cr) & CAST_TO_UINT32; +#endif + } + else + { + /* Do Nothing */ + } + + dl_body.cmd[0].set_data = layer_status; + + /* Display List update */ + R_LCDC->VI6_DL_BODY_SIZE0_b.UPD0 = 1; +} + +/*******************************************************************************************************************//** + * Color Keying setting for selected layer + * + * @param[in] ck_cfg LCDC configuration parameters for color keying + * @param[in] layer selected layer number + * @retval none + **********************************************************************************************************************/ +static void r_lcdc_ckey_set (display_colorkeying_layer_t ck_cfg, display_frame_layer_t layer) +{ + /* Display List Body Setting */ + /* Change color keying setting */ + if (layer == DISPLAY_FRAME_LAYER_1) + { + dl_body.cmd[8].set_data = (uint32_t) (ck_cfg.layer[layer].enable_ckey << 4); + dl_body.cmd[9].set_data = ck_cfg.layer[layer].src_color.argb; + dl_body.cmd[10].set_data = ck_cfg.layer[layer].dst_color.argb; + } + else + { + /* Do Nothing */ + } + + if (layer == DISPLAY_FRAME_LAYER_2) + { + dl_body.cmd[18].set_data = (uint32_t) (ck_cfg.layer[layer].enable_ckey << 4); + dl_body.cmd[19].set_data = ck_cfg.layer[layer].src_color.argb; + dl_body.cmd[20].set_data = ck_cfg.layer[layer].dst_color.argb; + } + else + { + /* Do Nothing */ + } + + /* Display List update */ + R_LCDC->VI6_DL_BODY_SIZE0_b.UPD0 = 1; +} + +/*******************************************************************************************************************//** + * Set the interrupt setting for LCDC module + * + * @param[in] p_cfg LCDC configuration parameters + * @param[in] p_instance_ctrl instance pointer of LCDC control + * @retval none + **********************************************************************************************************************/ +static void r_lcdc_interrupt_enable (display_cfg_t const * const p_cfg, lcdc_instance_ctrl_t * const p_instance_ctrl) +{ + lcdc_extended_cfg_t * pextend = (lcdc_extended_cfg_t *) p_cfg->p_extend; + + /* LCDC Interrupt Setting */ + /* Interrupt Enable (or disable) for Frame End */ + R_LCDC->VI6_WPF0_IRQ_ENB_b.FREE = 1; + + /* Interrupt Enable (or disable) for DU Connection UnderRun Error */ + R_LCDC->VI6_WPF0_IRQ_ENB_b.UNDE = 1; + + if (pextend->frame_end_irq >= 0) + { + R_BSP_IrqCfgEnable(pextend->frame_end_irq, pextend->frame_end_ipl, p_instance_ctrl); + } + else + { + /* Do Nothing */ + } +} + +/*******************************************************************************************************************//** + * Interrupt function for LCDC VSPD interrupt + * + * @param[in] irq FSP error type + * @retval none + **********************************************************************************************************************/ +void lcdc_vspd_int (IRQn_Type const irq) +{ + FSP_CONTEXT_SAVE FSP_PARAMETER_NOT_USED(irq); + + display_callback_args_t args; + lcdc_instance_ctrl_t * p_ctrl = (lcdc_instance_ctrl_t *) r_lcdc_blk.p_context; + uint8_t event_flag; + + event_flag = 0; + + /* Check which interrupt is generated */ + if (1 == R_LCDC->VI6_WPF0_IRQ_STA_b.FRE) + { + event_flag = DISPLAY_EVENT_FRAME_END; + } + else + { + /* Do Nothing */ + } + + if (1 == R_LCDC->VI6_WPF0_IRQ_STA_b.UND) + { + event_flag = DISPLAY_EVENT_GR1_UNDERFLOW; + } + else + { + /* Do Nothing */ + } + + /* Call back callback function if it is registered */ + if (NULL != p_ctrl->p_callback) + { + args.event = event_flag; + args.p_context = p_ctrl->p_context; + p_ctrl->p_callback(&args); + } + else + { + /* Do Nothing */ + } + + /* Clear interrupt flag */ + R_LCDC->VI6_WPF0_IRQ_STA_b.FRE = 0; + R_LCDC->VI6_WPF0_IRQ_STA_b.UND = 0; + + /* Restore context if RTOS is used */ + FSP_CONTEXT_RESTORE +} + +#if (LCDC_CFG_PARAM_CHECKING_ENABLE) + +/*******************************************************************************************************************//** + * The parameter checking subroutine for R_LCDC_Open API. + * + * @param[in] p_cfg Pointer to the configuration structure for display interface + * @retval FSP_SUCCESS No parameter error found + * @retval FSP_ERR_ASSERTION Pointer to the control block is NULL. + * @retval FSP_ERR_INVALID_TIMING_SETTING Invalid timing parameter. + * @retval FSP_ERR_INVALID_LAYER_SETTING Invalid layer parameter + **********************************************************************************************************************/ +static fsp_err_t r_lcdc_open_param_check (display_cfg_t const * const p_cfg) +{ + fsp_err_t error; + + FSP_ASSERT(p_cfg); + FSP_ASSERT(p_cfg->p_extend); + + /* Sync signal parameter check */ + error = r_lcdc_open_param_check_sync_signal(p_cfg); + FSP_ERROR_RETURN(FSP_SUCCESS == error, error); + + error = r_lcdc_open_param_check_layer_setting(p_cfg); + FSP_ERROR_RETURN(FSP_SUCCESS == error, error); + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * The parameter checking subroutine for R_LCDC_Open API. + * + * @param[in] p_cfg Pointer to the configuration structure for display interface + * @retval FSP_SUCCESS No parameter error found + * @retval FSP_ERR_INVALID_TIMING_SETTING Invalid timing parameter. + * @retval FSP_ERR_INVALID_LAYER_SETTING Invalid layer parameter + **********************************************************************************************************************/ +static fsp_err_t r_lcdc_open_param_check_sync_signal (display_cfg_t const * const p_cfg) +{ + fsp_err_t error; + + error = r_lcdc_open_param_check_display_cycle(p_cfg); + FSP_ERROR_RETURN(FSP_SUCCESS == error, error); + + error = r_lcdc_open_param_check_layer_setting(p_cfg); + FSP_ERROR_RETURN(FSP_SUCCESS == error, error); + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * The parameter checking for display cycle. + * + * @param[in] p_cfg Pointer to the configuration structure for display interface + * @retval FSP_SUCCESS No parameter error found + * @retval FSP_ERR_INVALID_TIMING_SETTING Invalid timing parameter. + **********************************************************************************************************************/ +static fsp_err_t r_lcdc_open_param_check_display_cycle (display_cfg_t const * const p_cfg) +{ + static uint32_t h_active; + static uint32_t v_active; + + h_active = (p_cfg->output.htiming.display_cyc); + v_active = p_cfg->output.vtiming.display_cyc; + + FSP_ERROR_RETURN((h_active <= TIMING_MAX_H), FSP_ERR_INVALID_TIMING_SETTING); + FSP_ERROR_RETURN((v_active <= TIMING_MAX_V), FSP_ERR_INVALID_TIMING_SETTING); + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * The parameter checking for layer setting. + * + * @param[in] p_cfg Pointer to the configuration structure for display interface + * @retval FSP_SUCCESS No parameter error found + * @retval FSP_ERR_INVALID_LAYER_SETTING Invalid layer parameter + **********************************************************************************************************************/ +static fsp_err_t r_lcdc_open_param_check_layer_setting (display_cfg_t const * const p_cfg) +{ + uint32_t layer_num; + for (layer_num = 0; layer_num <= DISPLAY_FRAME_LAYER_2; layer_num++) + { + if (p_cfg->input[layer_num].p_base) + { + FSP_ERROR_RETURN((p_cfg->input[layer_num].hsize <= LAYER_MAX_HSIZE), FSP_ERR_INVALID_LAYER_SETTING); + FSP_ERROR_RETURN((p_cfg->input[layer_num].vsize <= LAYER_MAX_VSIZE), FSP_ERR_INVALID_LAYER_SETTING); + FSP_ERROR_RETURN((p_cfg->input[layer_num].coordinate_x <= LAYER_MAX_HCOOR), FSP_ERR_INVALID_LAYER_SETTING); + FSP_ERROR_RETURN((p_cfg->input[layer_num].coordinate_y <= LAYER_MAX_VCOOR), FSP_ERR_INVALID_LAYER_SETTING); + } + else + { + /* Do Nothing */ + } + } + + return FSP_SUCCESS; +} + +#endif diff --git a/drivers/rz/fsp/src/rza/r_mipi_dsi_b/r_mipi_dsi_b.c b/drivers/rz/fsp/src/rza/r_mipi_dsi_b/r_mipi_dsi_b.c new file mode 100644 index 00000000..5a3bcac3 --- /dev/null +++ b/drivers/rz/fsp/src/rza/r_mipi_dsi_b/r_mipi_dsi_b.c @@ -0,0 +1,1182 @@ +/* +* Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ +#include +#include "r_mipi_dsi_b.h" + +/*********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ +#define MIPI_DSI_OPEN (0x4D504944) +#define MIPI_MAX_CH0_CMD (128) +#define MIPI_MAX_CH1_CMD (1024) +#define MIPI_DSI_RSTSR_RESET_BITS (R_MIPI_DSI_RSTSR_SWRSTHS_Msk | \ + R_MIPI_DSI_RSTSR_SWRSTLP_Msk | \ + R_MIPI_DSI_RSTSR_SWRSTAPB_Msk | \ + R_MIPI_DSI_RSTSR_SWRSTIB_Msk | \ + R_MIPI_DSI_RSTSR_SWRSTV1_Msk) + +#define CAST_TO_UINT32 (0xFFFFFFFFU) + +#define DSI_TX_PACKET_PAYLOAD_DATA_WORD_COUNT (4) +#define DSI_TX_PACKET_PAYLOAD_DATA_WORD_BIT_SIZE (8) +#define DSI_TX_PACKET_PAYLOAD_DATA_WORD_COUNT_MAX (16) + +#define DSI_PACKET_FORMAT_IS_SHORT(cmd_id) ((cmd_id & 0x0F) <= 0x08) +#define DSI_PACKET_FORMAT_IS_LONG(cmd_id) ((cmd_id & 0x0F) > 0x08) + +/*********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ + +#if defined(__ARMCC_VERSION) || defined(__ICCARM__) +typedef void (BSP_CMSE_NONSECURE_CALL * mipi_dsi_prv_ns_callback)(mipi_dsi_callback_args_t * p_args); +#elif defined(__GNUC__) +typedef BSP_CMSE_NONSECURE_CALL void (*volatile mipi_dsi_prv_ns_callback)(mipi_dsi_callback_args_t * p_args); +#endif + +/*********************************************************************************************************************** + * Global variables + **********************************************************************************************************************/ + +const mipi_dsi_api_t g_mipi_dsi = +{ + .open = R_MIPI_DSI_B_Open, + .close = R_MIPI_DSI_B_Close, + .start = R_MIPI_DSI_B_Start, + .stop = R_MIPI_DSI_B_Stop, + .ulpsEnter = R_MIPI_DSI_B_UlpsEnter, + .ulpsExit = R_MIPI_DSI_B_UlpsExit, + .command = R_MIPI_DSI_B_Command, + .statusGet = R_MIPI_DSI_B_StatusGet, +}; + +/*********************************************************************************************************************** + * Private function prototypes + **********************************************************************************************************************/ +void mipi_dsi_seq0(IRQn_Type const irq); +void mipi_dsi_seq1(IRQn_Type const irq); +void mipi_dsi_vin1(IRQn_Type const irq); +void mipi_dsi_rcv(IRQn_Type const irq); +void mipi_dsi_ferr(IRQn_Type const irq); +void mipi_dsi_ppi(IRQn_Type const irq); + +static void dsi_isr_enable(mipi_dsi_b_irq_cfg_t const * irq_cfg, mipi_dsi_b_instance_ctrl_t * p_ctrl); +static void dsi_isr_disable(mipi_dsi_b_irq_cfg_t const * irq_cfg); + +static void dsi_enter_reset(void); +static uint8_t dsi_pow(uint8_t base, uint8_t expon); +static void dsi_init_timing(mipi_dsi_cfg_t const * const p_cfg); +static void dsi_exit_reset(mipi_dsi_cfg_t const * const p_cfg); +static void dsi_hs_clock_start(mipi_dsi_b_instance_ctrl_t * p_ctrl); +static void dsi_hs_clock_stop(mipi_dsi_b_instance_ctrl_t * p_ctrl); + +static void dsi_init_video(mipi_dsi_cfg_t const * p_cfg); + +static void dsi_call_callback(mipi_dsi_b_instance_ctrl_t * p_ctrl, mipi_dsi_callback_args_t * p_args); + +static fsp_err_t dsi_stop(mipi_dsi_b_instance_ctrl_t * p_ctrl); +static uint32_t dsi_cmd_sequence_register_a(mipi_dsi_cmd_t * p_cmd); +static uint32_t dsi_cmd_sequence_register_b(mipi_dsi_cmd_t * p_cmd); +static uint32_t dsi_cmd_sequence_register_c(mipi_dsi_cmd_t * p_cmd); +static uint32_t dsi_cmd_sequence_register_d(mipi_dsi_cmd_t * p_cmd); + +/*******************************************************************************************************************//** + * @addtogroup MIPI_DSI_B + * @{ + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Functions + **********************************************************************************************************************/ + +/******************************************************************************************************************//** + * Initialize the MIPI DSI peripheral. + * + * @retval FSP_SUCCESS The channel was successfully opened. + * @retval FSP_ERR_ASSERTION One or both of the parameters was NULL. + * @retval FSP_ERR_ALREADY_OPEN The instance is already opened. + * @retval FSP_ERR_INVALID_STATE Display module must be opened before DSI. + **********************************************************************************************************************/ +fsp_err_t R_MIPI_DSI_B_Open (mipi_dsi_ctrl_t * const p_api_ctrl, mipi_dsi_cfg_t const * const p_cfg) +{ + fsp_err_t err; + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) p_api_ctrl; + +#if MIPI_DSI_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_cfg); + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(MIPI_DSI_OPEN != p_ctrl->open, FSP_ERR_ALREADY_OPEN); +#endif + + FSP_ERROR_RETURN(R_LCDC->DU_MCR0_b.DI_EN, FSP_ERR_INVALID_STATE); + + /* Initialize internal state */ + p_ctrl->clock_state = MIPI_DSI_CLOCK_STATE_IDLE; + p_ctrl->video_started = false; + p_ctrl->p_cfg = p_cfg; + + /* Start clocks to the MIPI DSI peripheral */ + R_BSP_MODULE_START(FSP_IP_MIPI_DSI, 0); + + err = r_mipi_phy_b_open(p_cfg->p_mipi_phy_instance->p_ctrl, p_cfg->p_mipi_phy_instance->p_cfg); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + /* Set LINK registers */ + dsi_enter_reset(); + dsi_init_timing(p_cfg); + dsi_exit_reset(p_cfg); + + R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS); + + /* Configure interrupt sources */ + mipi_dsi_b_extended_cfg_t * p_extend = (mipi_dsi_b_extended_cfg_t *) p_cfg->p_extend; + R_MIPI_DSI->RXIER = p_extend->dsi_rxie; + R_MIPI_DSI->FERRIER = p_extend->dsi_ferrie; + R_MIPI_DSI->PLIER = p_extend->dsi_plie; + R_MIPI_DSI->VICH1IER = p_extend->dsi_vmie; + R_MIPI_DSI->SQCH0IER = p_extend->dsi_sqch0ie; + R_MIPI_DSI->SQCH1IER = p_extend->dsi_sqch1ie; + + /* Clear any active status bits */ + R_MIPI_DSI->SQCH0SCR = R_MIPI_DSI_SQCH0SCR_AACTFIN_Msk | + R_MIPI_DSI_SQCH0SCR_ADESFIN_Msk | + R_MIPI_DSI_SQCH0SCR_PKTBIGERR_Msk | + R_MIPI_DSI_SQCH0SCR_TXIBERR_Msk | + R_MIPI_DSI_SQCH0SCR_RXFATALERR_Msk | + R_MIPI_DSI_SQCH0SCR_RXFAIL_Msk | + R_MIPI_DSI_SQCH0SCR_RXPKTDFAIL_Msk | + R_MIPI_DSI_SQCH0SCR_RXCORERR_Msk | + R_MIPI_DSI_SQCH0SCR_RXAKE_Msk; + R_MIPI_DSI->SQCH1SCR = R_MIPI_DSI_SQCH1SCR_AACTFIN_Msk | + R_MIPI_DSI_SQCH1SCR_ADESFIN_Msk | + R_MIPI_DSI_SQCH1SCR_PKTBIGERR_Msk | + R_MIPI_DSI_SQCH1SCR_TXIBERR_Msk | + R_MIPI_DSI_SQCH1SCR_RXFATALERR_Msk | + R_MIPI_DSI_SQCH1SCR_RXFAIL_Msk | + R_MIPI_DSI_SQCH1SCR_RXPKTDFAIL_Msk | + R_MIPI_DSI_SQCH1SCR_RXCORERR_Msk | + R_MIPI_DSI_SQCH1SCR_RXAKE_Msk; + R_MIPI_DSI->VICH1SCR = R_MIPI_DSI_VICH1SCR_START_Msk | + R_MIPI_DSI_VICH1SCR_STOP_Msk | + R_MIPI_DSI_VICH1SCR_VIRDY_Msk | + R_MIPI_DSI_VICH1SCR_TIMERR_Msk | + R_MIPI_DSI_VICH1SCR_VBUFUDF_Msk | + R_MIPI_DSI_VICH1SCR_VBUFOVF_Msk; + R_MIPI_DSI->RXSCR = R_MIPI_DSI_RXSCR_BTAREQEND_Msk | + R_MIPI_DSI_RXSCR_LRXHTO_Msk | + R_MIPI_DSI_RXSCR_TATO_Msk | + R_MIPI_DSI_RXSCR_RXRESP_Msk | + R_MIPI_DSI_RXSCR_RXEOTP_Msk | + R_MIPI_DSI_RXSCR_RXUK5TRG_Msk | + R_MIPI_DSI_RXSCR_RXRTRG_Msk | + R_MIPI_DSI_RXSCR_RXTE_Msk | + R_MIPI_DSI_RXSCR_RXACK_Msk | + R_MIPI_DSI_RXSCR_EXTTEDET_Msk | + R_MIPI_DSI_RXSCR_MLFERR_Msk | + R_MIPI_DSI_RXSCR_ECCERR_Msk | + R_MIPI_DSI_RXSCR_UEXPKTERR_Msk | + R_MIPI_DSI_RXSCR_WCERR_Msk | + R_MIPI_DSI_RXSCR_CRCERR_Msk | + R_MIPI_DSI_RXSCR_IBERR_Msk | + R_MIPI_DSI_RXSCR_RXOVFERR_Msk | + R_MIPI_DSI_RXSCR_PRESPTOERR_Msk | + R_MIPI_DSI_RXSCR_NORETERR_Msk | + R_MIPI_DSI_RXSCR_MAXRPSZERR_Msk | + R_MIPI_DSI_RXSCR_ECCERR1B_Msk | + R_MIPI_DSI_RXSCR_RXAKE_Msk; + + p_ctrl->p_callback_memory = NULL; + p_ctrl->p_callback = p_cfg->p_callback; + + /* Enable interrupts */ + p_ctrl->p_context = p_cfg->p_context; + dsi_isr_enable(&p_extend->dsi_seq0, p_ctrl); + dsi_isr_enable(&p_extend->dsi_seq1, p_ctrl); + dsi_isr_enable(&p_extend->dsi_ferr, p_ctrl); + dsi_isr_enable(&p_extend->dsi_ppi, p_ctrl); + dsi_isr_enable(&p_extend->dsi_rcv, p_ctrl); + dsi_isr_enable(&p_extend->dsi_vin1, p_ctrl); + + /* Mark control block as opened */ + p_ctrl->open = MIPI_DSI_OPEN; + + /* Start high-speed clock */ + dsi_hs_clock_start(p_ctrl); + + /* Notify application that DSI is now open */ + mipi_dsi_callback_args_t callback_args; + callback_args.event = MIPI_DSI_EVENT_POST_OPEN; + callback_args.p_context = p_ctrl->p_context; + dsi_call_callback(p_ctrl, &callback_args); + + return FSP_SUCCESS; +} + +/******************************************************************************************************************//** + * Close MIPI DSI and display data instances, disable interrupts, and power-off the module. + * + * @retval FSP_SUCCESS The channel is successfully closed. + * @retval FSP_ERR_ASSERTION p_api_ctrl is NULL. + * @retval FSP_ERR_NOT_OPEN Instance is not open. + * @retval FSP_ERR_IN_USE Operation in progress and must be stopped before closing. + **********************************************************************************************************************/ +fsp_err_t R_MIPI_DSI_B_Close (mipi_dsi_ctrl_t * const p_api_ctrl) +{ + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) p_api_ctrl; + +#if MIPI_DSI_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(MIPI_DSI_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); +#endif + + /* Ensure video has stopped first */ + fsp_err_t err = dsi_stop(p_ctrl); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + dsi_hs_clock_stop(p_ctrl); + + mipi_dsi_cfg_t const * p_cfg = p_ctrl->p_cfg; + mipi_dsi_b_extended_cfg_t * p_extend = (mipi_dsi_b_extended_cfg_t *) p_cfg->p_extend; + dsi_isr_disable(&p_extend->dsi_seq0); + dsi_isr_disable(&p_extend->dsi_seq1); + dsi_isr_disable(&p_extend->dsi_ferr); + dsi_isr_disable(&p_extend->dsi_ppi); + dsi_isr_disable(&p_extend->dsi_rcv); + dsi_isr_disable(&p_extend->dsi_vin1); + + /* Close MIPI PHY */ + err = r_mipi_phy_b_close(p_cfg->p_mipi_phy_instance->p_ctrl); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + /* Set control block to closed */ + p_ctrl->open = 0U; + + /* Stop clocks to the MIPI DSI peripheral */ + R_BSP_MODULE_STOP(FSP_IP_MIPI_DSI, 0); + + return FSP_SUCCESS; +} + +/******************************************************************************************************************//** + * Start video output. + * Initialize Video Output Registers + * Perform sequence steps from section 34.4.2.4.(1) in RZ/A3M hardware manual. + * + * @retval FSP_SUCCESS Data is successfully written to the D/A Converter. + * @retval FSP_ERR_ASSERTION p_api_ctrl is NULL. + * @retval FSP_ERR_NOT_OPEN Instance is not open. + * @retval FSP_ERR_IN_USE The physical interface is currently in use. + * @retval FSP_ERR_INVALID_STATE DSI is already in video mode. + **********************************************************************************************************************/ +fsp_err_t R_MIPI_DSI_B_Start (mipi_dsi_ctrl_t * const p_api_ctrl) +{ + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) p_api_ctrl; + +#if MIPI_DSI_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(p_ctrl); + FSP_ERROR_RETURN(MIPI_DSI_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); + FSP_ERROR_RETURN(!p_ctrl->video_started, FSP_ERR_INVALID_STATE); +#endif + + /* Notify application that DSI is now open */ + mipi_dsi_callback_args_t callback_args; + callback_args.event = MIPI_DSI_EVENT_PRE_START; + callback_args.p_context = p_ctrl->p_context; + dsi_call_callback(p_ctrl, &callback_args); + + /* Do not start video if sequence operation is in progress */ + FSP_ERROR_RETURN(!(R_MIPI_DSI->LINKSR_b.SQCHRUN0) && !(R_MIPI_DSI->LINKSR_b.SQCHRUN1), FSP_ERR_IN_USE); + + mipi_dsi_cfg_t const * p_cfg = p_ctrl->p_cfg; + + /* Initialize Video Output Registers */ + dsi_init_video(p_cfg); + + while ((R_MIPI_DSI->VICH1SR_b.VIRDY != 1) && !p_ctrl->video_started) + { + /* Wait for video mode ready status + * NOTE: VICH1SR may be modified in isr */ + } + + p_ctrl->video_started = true; + + return FSP_SUCCESS; +} + +/******************************************************************************************************************//** + * Stop video output. + * + * @retval FSP_SUCCESS Data is successfully written to the D/A Converter. + * @retval FSP_ERR_ASSERTION p_api_ctrl is NULL. + * @retval FSP_ERR_NOT_OPEN Instance is not open. + * @retval FSP_ERR_IN_USE DSI cannot be closed while ULPS is active. + **********************************************************************************************************************/ +fsp_err_t R_MIPI_DSI_B_Stop (mipi_dsi_ctrl_t * const p_api_ctrl) +{ + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) p_api_ctrl; + +#if MIPI_DSI_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(p_ctrl); + FSP_ERROR_RETURN(MIPI_DSI_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); +#endif + + return dsi_stop(p_ctrl); +} + +/******************************************************************************************************************//** + * Enter Ultra-low Power State (ULPS). + * + * @retval FSP_SUCCESS Information read successfully. + * @retval FSP_ERR_ASSERTION p_api_ctrl is NULL. + * @retval FSP_ERR_NOT_OPEN Instance is not open. + * @retval FSP_ERR_INVALID_MODE Invalid mode for transition. + * @retval FSP_ERR_INVALID_ARGUMENT Invalid input parameter. + **********************************************************************************************************************/ +fsp_err_t R_MIPI_DSI_B_UlpsEnter (mipi_dsi_ctrl_t * const p_api_ctrl, mipi_dsi_lane_t lane) +{ + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) p_api_ctrl; + +#if MIPI_DSI_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(MIPI_DSI_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); + + /* Clock lane cannot enter ULPS when Continuous CLock mode is active */ + FSP_ERROR_RETURN(!((MIPI_DSI_LANE_CLOCK & lane) && R_MIPI_DSI->HSCLKSETR_b.HSCLKMODE), FSP_ERR_INVALID_MODE); + + FSP_ERROR_RETURN(MIPI_DSI_LANE_CLOCK == lane || MIPI_DSI_LANE_DATA_ALL == lane || + (MIPI_DSI_LANE_CLOCK | MIPI_DSI_LANE_DATA_ALL) == lane, + FSP_ERR_INVALID_ARGUMENT); +#endif + + /* Do not set 'enter ULPS' bit if lane is already in ULPS */ + uint32_t ulpscr = + ((MIPI_DSI_LANE_DATA_ALL & lane) && !p_ctrl->data_ulps_active) ? R_MIPI_DSI_ULPSCR_DLULPSENT_Msk : 0; + ulpscr |= + ((MIPI_DSI_LANE_CLOCK & lane) && !p_ctrl->clock_ulps_active) ? R_MIPI_DSI_ULPSCR_CLULPSENT_Msk : 0; + + p_ctrl->ulps_status |= lane; + + p_ctrl->clock_ulps_active = p_ctrl->clock_ulps_active || (MIPI_DSI_LANE_CLOCK & lane); + p_ctrl->data_ulps_active = p_ctrl->data_ulps_active || (MIPI_DSI_LANE_DATA_ALL & lane); + + R_MIPI_DSI->ULPSCR = ulpscr; + + return FSP_SUCCESS; +} + +/******************************************************************************************************************//** + * Exit Ultra-low Power State (ULPS). + * + * @retval FSP_SUCCESS Information read successfully. + * @retval FSP_ERR_ASSERTION p_api_ctrl is NULL. + * @retval FSP_ERR_NOT_OPEN Instance is not open. + * @retval FSP_ERR_INVALID_ARGUMENT Invalid input parameter. + **********************************************************************************************************************/ +fsp_err_t R_MIPI_DSI_B_UlpsExit (mipi_dsi_ctrl_t * const p_api_ctrl, mipi_dsi_lane_t lane) +{ + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) p_api_ctrl; +#if MIPI_DSI_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(MIPI_DSI_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); + FSP_ERROR_RETURN(MIPI_DSI_LANE_CLOCK == lane || MIPI_DSI_LANE_DATA_ALL == lane || + (MIPI_DSI_LANE_CLOCK | MIPI_DSI_LANE_DATA_ALL) == lane, + FSP_ERR_INVALID_ARGUMENT); +#endif + + /* Do not set 'exit ULPS' bit if lane is not in ULPS */ + uint32_t ulpscr = + ((MIPI_DSI_LANE_DATA_ALL & lane) && p_ctrl->data_ulps_active) ? R_MIPI_DSI_ULPSCR_DLULPSEXT_Msk : 0; + ulpscr |= + ((MIPI_DSI_LANE_CLOCK & lane) && p_ctrl->clock_ulps_active) ? R_MIPI_DSI_ULPSCR_CLULPSEXT_Msk : 0; + + p_ctrl->clock_ulps_active = p_ctrl->clock_ulps_active && !(MIPI_DSI_LANE_CLOCK & lane); + p_ctrl->data_ulps_active = p_ctrl->data_ulps_active && !(MIPI_DSI_LANE_DATA_ALL & lane); + + R_MIPI_DSI->ULPSCR = ulpscr; + p_ctrl->ulps_status &= ~lane; + + return FSP_SUCCESS; +} + +/******************************************************************************************************************//** + * Send a command to the peripheral device. + * + * @note p_data will be used as either write data or a read buffer depending on the data id. + * @note p_data memory must not be updated until sequence operation is complete if byte_count is greater than 16. + * + * @retval FSP_SUCCESS Command(s) queued successfully. + * @retval FSP_ERR_ASSERTION p_api_ctrl is NULL. + * cmd_id specifies a long packet but p_data is NULL. + * @retval FSP_ERR_NOT_OPEN Instance is not open. + * @retval FSP_ERR_IN_USE The physical interface is currently in use or video mode is in operation. + * @retval FSP_ERR_INVALID_POINTER Invalid pointer provided + * @retval FSP_ERR_INVALID_ARGUMENT Invalid message configuration + * @retval FSP_ERR_INVALID_CHANNEL Invalid channel for provided message configuration + **********************************************************************************************************************/ +fsp_err_t R_MIPI_DSI_B_Command (mipi_dsi_ctrl_t * const p_api_ctrl, mipi_dsi_cmd_t * p_cmd) +{ +#if MIPI_DSI_CFG_PARAM_CHECKING_ENABLE + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) p_api_ctrl; + + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(p_cmd, FSP_ERR_INVALID_POINTER); + FSP_ERROR_RETURN(MIPI_DSI_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); + FSP_ERROR_RETURN(p_cmd->p_tx_buffer || (p_cmd->tx_len == 0), FSP_ERR_INVALID_ARGUMENT); // Tx buffer must be supplied for non-zero Tx length + + FSP_ERROR_RETURN(!((p_cmd->channel == 0) && (p_cmd->tx_len > MIPI_MAX_CH0_CMD)), FSP_ERR_INVALID_ARGUMENT); // Max Tx size is 128 for channel 0 + FSP_ERROR_RETURN(!((p_cmd->channel == 1) && (p_cmd->tx_len > MIPI_MAX_CH1_CMD)), FSP_ERR_INVALID_ARGUMENT); // Max Tx size is 1k for channel 1 + + /* AUX Operation */ + bool aux = (p_cmd->flags & MIPI_DSI_CMD_FLAG_AUX_OPERATION); + if (aux) + { + bool bta = p_cmd->flags & + (MIPI_DSI_CMD_FLAG_BTA | MIPI_DSI_CMD_FLAG_BTA_READ | MIPI_DSI_CMD_FLAG_BTA_NO_WRITE); + bool initial_skew = (p_cmd->flags & MIPI_DSI_CMD_FLAG_ACT_CODE_INITIAL_SKEW_CAL); + bool periodic_skew = (p_cmd->flags & MIPI_DSI_CMD_FLAG_ACT_CODE_PERIODIC_SKEW_CAL); + FSP_ERROR_RETURN(!bta && !p_cmd->tx_len, FSP_ERR_INVALID_ARGUMENT); + FSP_ERROR_RETURN(!R_MIPI_DSI->LINKSR_b.VICHRUN1, FSP_ERR_INVALID_ARGUMENT); // Aux operation is prohibited when video mode is running + FSP_ERROR_RETURN(!(initial_skew || periodic_skew) || (p_cmd->channel != 0), FSP_ERR_INVALID_ARGUMENT); // Periodic and Initial skew must be HS + } + + uint8_t lp = (0 != (p_cmd->flags & MIPI_DSI_CMD_FLAG_LOW_POWER)); + + FSP_ERROR_RETURN(!(lp && R_MIPI_DSI->LINKSR_b.VICHRUN1), FSP_ERR_IN_USE); // LP not allowed during video mode operation. + FSP_ERROR_RETURN(!(lp && (p_cmd->channel != 0)), FSP_ERR_INVALID_CHANNEL); // LP only allowed on channel 0 +#else + FSP_PARAMETER_NOT_USED(p_api_ctrl); +#endif + + /* Do not modify registers if sequence operation is currently in progress */ + FSP_ERROR_RETURN(!(R_MIPI_DSI->LINKSR_b.SQCHRUN0) && !(R_MIPI_DSI->LINKSR_b.SQCHRUN1), FSP_ERR_IN_USE); + + R_MIPI_DSI->TXPPD0R = 0x00000000; // initialize TXPPD0R + R_MIPI_DSI->TXPPD1R = 0x00000000; // initialize TXPPD1R + R_MIPI_DSI->TXPPD2R = 0x00000000; // initialize TXPPD2R + R_MIPI_DSI->TXPPD3R = 0x00000000; // initialize TXPPD3R + + uint32_t * p_sequence_reg = (uint32_t *) (&R_MIPI_DSI->SQCH0DSC00AR); // Sequence Channel 0 + + if (p_cmd->channel == 1) + { + p_sequence_reg = (uint32_t *) (&R_MIPI_DSI->SQCH1DSC00AR); // Sequence Channel 1 + } + else + { + // do nothing + } + + *p_sequence_reg++ = dsi_cmd_sequence_register_a(p_cmd); + *p_sequence_reg++ = dsi_cmd_sequence_register_b(p_cmd); + *p_sequence_reg++ = dsi_cmd_sequence_register_c(p_cmd); + *p_sequence_reg++ = dsi_cmd_sequence_register_d(p_cmd); + + bool long_packet = DSI_PACKET_FORMAT_IS_LONG(p_cmd->cmd_id); + + if (long_packet && (p_cmd->tx_len <= DSI_TX_PACKET_PAYLOAD_DATA_WORD_COUNT_MAX)) + { + for (uint8_t i = 0; i < p_cmd->tx_len; i++) + { + if (3 >= i) + { + R_MIPI_DSI->TXPPD0R |= + (uint32_t) (*(p_cmd->p_tx_buffer + i) << + (DSI_TX_PACKET_PAYLOAD_DATA_WORD_BIT_SIZE * + (i % DSI_TX_PACKET_PAYLOAD_DATA_WORD_COUNT))); // Long packet payload data 0 - 3 + } + else if (7 >= i) + { + R_MIPI_DSI->TXPPD1R |= + (uint32_t) (*(p_cmd->p_tx_buffer + i) << + (DSI_TX_PACKET_PAYLOAD_DATA_WORD_BIT_SIZE * + (i % DSI_TX_PACKET_PAYLOAD_DATA_WORD_COUNT))); // Long packet payload data 4 - 7 + } + else if (11 >= i) + { + R_MIPI_DSI->TXPPD2R |= + (uint32_t) (*(p_cmd->p_tx_buffer + i) << + (DSI_TX_PACKET_PAYLOAD_DATA_WORD_BIT_SIZE * + (i % DSI_TX_PACKET_PAYLOAD_DATA_WORD_COUNT))); // Long packet payload data 8 - 11 + } + else if (15 >= i) + { + R_MIPI_DSI->TXPPD3R |= + (uint32_t) (*(p_cmd->p_tx_buffer + i) << + (DSI_TX_PACKET_PAYLOAD_DATA_WORD_BIT_SIZE * + (i % DSI_TX_PACKET_PAYLOAD_DATA_WORD_COUNT))); // Long packet payload data 12 - 15 + } + else + { + // do nothing + } + } + } + else + { + // do nothing + } + + /* Start sequence operation */ + R_MIPI_DSI->SQCH0SET0R = (bool) (0 == p_cmd->channel); + R_MIPI_DSI->SQCH1SET0R = (bool) (1 == p_cmd->channel); + + return FSP_SUCCESS; +} + +/******************************************************************************************************************//** + * Provide information about current MIPI DSI status. + * + * Note: Acknowledge and Error Status is only cleared when read by calling this function. + * + * @retval FSP_SUCCESS Information read successfully. + * @retval FSP_ERR_ASSERTION p_api_ctrl is NULL. + * @retval FSP_ERR_NOT_OPEN Instance is not open. + * + **********************************************************************************************************************/ +fsp_err_t R_MIPI_DSI_B_StatusGet (mipi_dsi_ctrl_t * const p_api_ctrl, mipi_dsi_status_t * p_status) +{ +#if MIPI_DSI_CFG_PARAM_CHECKING_ENABLE + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) p_api_ctrl; + FSP_ASSERT(NULL != p_ctrl); + FSP_ASSERT(NULL != p_status); + FSP_ERROR_RETURN(MIPI_DSI_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); +#else + FSP_PARAMETER_NOT_USED(p_api_ctrl); +#endif + + p_status->link_status = (mipi_dsi_link_status_t) R_MIPI_DSI->LINKSR; + p_status->ack_err_latest.bits = R_MIPI_DSI->AKEPLATIR; + p_status->ack_err_accumulated.bits = R_MIPI_DSI->AKEPACMSR; + + /* Clear accumulated error bits after reading */ + R_MIPI_DSI->AKEPSCR = p_status->ack_err_accumulated.bits; + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * @} (end addtogroup MIPI_DSI_B) + **********************************************************************************************************************/ + +/*******************************************************************************************************************//** + * Stop DSI operation. Basic parameter checking to be performed by caller. + * + * @param[in] p_ctrl Pointer to instance control structure + * + * @retval FSP_SUCCESS DSI stopped successfully. + * @retval FSP_ERR_IN_USE DSI cannot be stopped in ULPS. + **********************************************************************************************************************/ +static fsp_err_t dsi_stop (mipi_dsi_b_instance_ctrl_t * p_ctrl) +{ +#if MIPI_DSI_CFG_PARAM_CHECKING_ENABLE + FSP_ERROR_RETURN(!p_ctrl->ulps_status, FSP_ERR_IN_USE); +#else + FSP_PARAMETER_NOT_USED(p_ctrl); +#endif + + /* Check if running first else the stop operation may stall indefinitely */ + if (R_MIPI_DSI->VICH1SR_b.RUNNING) + { + /* Initiate stop video output and wait */ + R_MIPI_DSI->VICH1SET0R_b.VSTPAFT = 1U; + + while ((R_MIPI_DSI->VICH1SR_b.STOP != 1) && p_ctrl->video_started) + { + /* Wait for video mode stop + * - VICH1SR.STOP must be zero before proceeding to stop LCDC + * NOTE: VICH1SR may be modified in isr */ + } + + p_ctrl->video_started = false; + + /* Clear any stale VICH1SR status */ + R_MIPI_DSI->VICH1SCR = R_MIPI_DSI->VICH1SR; + + while (R_MIPI_DSI->LINKSR_b.HSBUSY != 0) + { + /* wait for LINKSR.HSBUSY to become 0 */ + } + } + + return FSP_SUCCESS; +} + +/*********************************************************************************************************************** + * Returns configuration values for Sequence Register A + * + * @param[in] p_cmd Pointer to formatted message structure + **********************************************************************************************************************/ +static uint32_t dsi_cmd_sequence_register_a (mipi_dsi_cmd_t * p_cmd) +{ + /* + * Long write packets contain the word count in header bytes 1 and 2. + * The payload follows the header and is word count bytes long. + * + * Short write packets encode up to two parameters in header bytes 1 + * and 2. + */ + uint8_t short_data[2]; + bool long_packet = DSI_PACKET_FORMAT_IS_LONG(p_cmd->cmd_id); + if (long_packet) + { + short_data[0] = + (uint8_t) ((p_cmd->tx_len & R_MIPI_DSI_SQCH0DSC00AR_DATA0_Msk) >> R_MIPI_DSI_SQCH0DSC00AR_DATA0_Pos); + short_data[1] = + (uint8_t) ((p_cmd->tx_len & R_MIPI_DSI_SQCH0DSC00AR_DATA1_Msk) >> R_MIPI_DSI_SQCH0DSC00AR_DATA1_Pos); + } + else + { + short_data[0] = (p_cmd->tx_len > 0) ? p_cmd->p_tx_buffer[0] : 0U; + short_data[1] = (p_cmd->tx_len > 1) ? p_cmd->p_tx_buffer[1] : 0U; + } + + uint8_t bta = + (p_cmd->flags & (MIPI_DSI_CMD_FLAG_BTA | MIPI_DSI_CMD_FLAG_BTA_READ | MIPI_DSI_CMD_FLAG_BTA_NO_WRITE)); + + uint8_t lp = (0 != (p_cmd->flags & MIPI_DSI_CMD_FLAG_LOW_POWER)); + uint32_t sequence_register_a = + (((uint32_t) short_data[0] << R_MIPI_DSI_SQCH0DSC00AR_DATA0_Pos) & R_MIPI_DSI_SQCH0DSC00AR_DATA0_Msk) | + (((uint32_t) short_data[1] << R_MIPI_DSI_SQCH0DSC00AR_DATA1_Pos) & R_MIPI_DSI_SQCH0DSC00AR_DATA1_Msk) | + (((uint32_t) p_cmd->cmd_id << R_MIPI_DSI_SQCH0DSC00AR_DT_Pos) & R_MIPI_DSI_SQCH0DSC00AR_DT_Msk) | + (((uint32_t) p_cmd->channel << R_MIPI_DSI_SQCH0DSC00AR_VC_Pos) & R_MIPI_DSI_SQCH0DSC00AR_VC_Msk) | + (((uint32_t) long_packet << R_MIPI_DSI_SQCH0DSC00AR_FMT_Pos) & R_MIPI_DSI_SQCH0DSC00AR_FMT_Msk) | + (((uint32_t) lp << R_MIPI_DSI_SQCH0DSC00AR_SPD_Pos) & R_MIPI_DSI_SQCH0DSC00AR_SPD_Msk) | + (((uint32_t) bta << R_MIPI_DSI_SQCH0DSC00AR_BTA_Pos) & R_MIPI_DSI_SQCH0DSC00AR_BTA_Msk) | + (((uint32_t) 0 << R_MIPI_DSI_SQCH0DSC00AR_NXACT_Pos) & R_MIPI_DSI_SQCH0DSC00AR_NXACT_Msk); + + return sequence_register_a; +} + +/*********************************************************************************************************************** + * Returns configuration values for Sequence Register B + * + * @param[in] p_cmd Pointer to formatted message structure + **********************************************************************************************************************/ +static uint32_t dsi_cmd_sequence_register_b (mipi_dsi_cmd_t * p_cmd) +{ + uint8_t dtsel = 0; + if (p_cmd->tx_len > DSI_TX_PACKET_PAYLOAD_DATA_WORD_COUNT_MAX) + { + /* Use sequence RAM */ + dtsel = 1; + } + else + { + /* Use packet payload data register */ + dtsel = 0; + } + + return (dtsel << R_MIPI_DSI_SQCH0DSC00BR_DTSEL_Pos) & R_MIPI_DSI_SQCH0DSC00BR_DTSEL_Msk; +} + +/*********************************************************************************************************************** + * Returns configuration values for Sequence Register C + * + * @param[in] p_cmd Pointer to formatted message structure + **********************************************************************************************************************/ +static uint32_t dsi_cmd_sequence_register_c (mipi_dsi_cmd_t * p_cmd) +{ + bool aux_operation = (p_cmd->flags & MIPI_DSI_CMD_FLAG_AUX_OPERATION); + bool actcode = aux_operation ? (p_cmd->flags & 0xF) : 0; // Always store Rx result in slot 0 + uint32_t sequence_register_c = + (((uint32_t) 0 << R_MIPI_DSI_SQCH0DSC00CR_FINACT_Pos) & R_MIPI_DSI_SQCH0DSC00CR_FINACT_Msk) | + (((uint32_t) aux_operation << R_MIPI_DSI_SQCH0DSC00CR_AUXOP_Pos) & R_MIPI_DSI_SQCH0DSC00CR_AUXOP_Msk) | + (((uint32_t) actcode << R_MIPI_DSI_SQCH0DSC00CR_ACTCODE_Pos) & R_MIPI_DSI_SQCH0DSC00CR_ACTCODE_Msk); + + return sequence_register_c; +} + +/*********************************************************************************************************************** + * Returns configuration values for Sequence Register D + * + * @param[in] p_cmd Pointer to formatted message structure + **********************************************************************************************************************/ +static uint32_t dsi_cmd_sequence_register_d (mipi_dsi_cmd_t * p_cmd) +{ + uint8_t bta = + (p_cmd->flags & (MIPI_DSI_CMD_FLAG_BTA | MIPI_DSI_CMD_FLAG_BTA_READ | MIPI_DSI_CMD_FLAG_BTA_NO_WRITE)); + + return (uint32_t) ((uintptr_t) (bta ? p_cmd->p_rx_buffer : p_cmd->p_tx_buffer) & CAST_TO_UINT32); // This buffer address is used for both Tx and Rx. +} + +/*******************************************************************************************************************//** + * Calls user callback + * + * @param[in] p_ctrl Pointer to MIPI DSI instance control block + * @param[in] p_args Pointer to arguments on stack + **********************************************************************************************************************/ +static void dsi_call_callback (mipi_dsi_b_instance_ctrl_t * p_ctrl, mipi_dsi_callback_args_t * p_args) +{ + mipi_dsi_callback_args_t args; + + /* Store callback arguments in memory provided by user if available. This allows callback arguments to be + * stored in non-secure memory so they can be accessed by a non-secure callback function. */ + mipi_dsi_callback_args_t * p_args_memory = p_ctrl->p_callback_memory; + + if (NULL == p_args_memory) + { + /* Use provided args struct on stack */ + p_args_memory = p_args; + } + else + { + /* Save current arguments on the stack in case this is a nested interrupt. */ + args = *p_args_memory; + + /* Copy the stacked args to callback memory */ + *p_args_memory = *p_args; + } + +#if BSP_TZ_SECURE_BUILD + + /* p_callback can point to a secure function or a non-secure function. */ + if (!cmse_is_nsfptr(p_ctrl->p_callback)) + { + /* If p_callback is secure, then the project does not need to change security state. */ + p_ctrl->p_callback(p_args_memory); + } + else + { + /* If p_callback is Non-secure, then the project must change to Non-secure state in order to call the callback. */ + mipi_dsi_prv_ns_callback p_callback = (mipi_dsi_prv_ns_callback) (p_ctrl->p_callback); + p_callback(p_args_memory); + } +#else + + /* If the project is not Trustzone Secure, then it will never need to change security state in order to call the callback. */ + p_ctrl->p_callback(p_args_memory); +#endif + + if (NULL != p_ctrl->p_callback_memory) + { + /* Restore callback memory in case this is a nested interrupt. */ + *p_ctrl->p_callback_memory = args; + } +} + +/*******************************************************************************************************************//** + * Private helper functions + **********************************************************************************************************************/ + +/*******************************************************************************************************************//** + * Enter Reset + * Perform sequence from section 34.4.2.1.(2) in RZ/A3M hardware manual. + **********************************************************************************************************************/ +static void dsi_enter_reset () +{ + /* Enable clock lane */ + R_MIPI_DSI->TXSETR_b.CLEN = 1U; + + /* Enter the DSI Host software reset state */ + R_MIPI_DSI->RSTCR_b.SWRST = 1; + + /* Wait for reset process to start - Polling RSTSR is okay since it's not updated in interrupt.*/ + FSP_HARDWARE_REGISTER_WAIT((R_MIPI_DSI->RSTSR & MIPI_DSI_RSTSR_RESET_BITS), MIPI_DSI_RSTSR_RESET_BITS); +} + +/*******************************************************************************************************************//** + * Initialize timing registers from configuration data + * - Perform sequence step (F) from section 34.4.2.1.(1) in RZ/A3M hardware manual. + * + * @param[in] p_cfg Pointer to MIPI DSI configuration structure + **********************************************************************************************************************/ +static void dsi_init_timing (mipi_dsi_cfg_t const * const p_cfg) +{ + /* Set common settings */ + /* Enable clock and data lanes and set number of lanes to use */ + R_MIPI_DSI->TXSETR = R_MIPI_DSI_TXSETR_DLEN_Msk | R_MIPI_DSI_TXSETR_CLEN_Msk | (uint32_t) (p_cfg->num_lanes - 1); + + /* Set ULPS wake-up period */ + R_MIPI_DSI->ULPSSETR_b.ULPSWKUP = p_cfg->ulps_wakeup_period; + + /* Set data scrambling and/or EoTp transmission */ + R_MIPI_DSI->DSISETR = + ((p_cfg->max_return_packet_size << R_MIPI_DSI_DSISETR_MRPSZ_Pos) & R_MIPI_DSI_DSISETR_MRPSZ_Msk) | + (((uint32_t) p_cfg->ecc_enable << R_MIPI_DSI_DSISETR_ECCEN_Pos) & R_MIPI_DSI_DSISETR_ECCEN_Msk) | + (((uint32_t) p_cfg->crc_check_mask << R_MIPI_DSI_DSISETR_CRCEN_Pos) & R_MIPI_DSI_DSISETR_CRCEN_Msk) | + (((uint32_t) p_cfg->scramble_enable << R_MIPI_DSI_DSISETR_SCREN_Pos) & R_MIPI_DSI_DSISETR_SCREN_Msk) | + (((uint32_t) p_cfg->tearing_detect << R_MIPI_DSI_DSISETR_TEIDIR_Pos) & R_MIPI_DSI_DSISETR_TEIDIR_Msk) | + (((uint32_t) p_cfg->eotp_enable << R_MIPI_DSI_DSISETR_EOTPEN_Pos) & R_MIPI_DSI_DSISETR_EOTPEN_Msk); + + /* Set LP lane transition timing */ + R_MIPI_DSI->CLSTPTSETR = + ((p_cfg->p_timing->clock_stop_time << R_MIPI_DSI_CLSTPTSETR_CLKSTPT_Pos) & + R_MIPI_DSI_CLSTPTSETR_CLKSTPT_Msk) | + ((p_cfg->p_timing->clock_beforehand_time << R_MIPI_DSI_CLSTPTSETR_CLKBFHT_Pos) & + R_MIPI_DSI_CLSTPTSETR_CLKBFHT_Msk) | + ((p_cfg->p_timing->clock_keep_time << R_MIPI_DSI_CLSTPTSETR_CLKKPT_Pos) & + R_MIPI_DSI_CLSTPTSETR_CLKKPT_Msk); + R_MIPI_DSI->LPTRNSTSETR = p_cfg->p_timing->go_lp_and_back & R_MIPI_DSI_LPTRNSTSETR_GOLPBKT_Msk; + + /* Set timeout values */ + R_MIPI_DSI->PRESPTOBTASETR = p_cfg->bta_timeout; + R_MIPI_DSI->PRESPTOLPSETR = p_cfg->lprw_timeout; + R_MIPI_DSI->PRESPTOHSSETR = p_cfg->hsrw_timeout; + R_MIPI_DSI->HSTXTOSETR = p_cfg->hs_tx_timeout; + R_MIPI_DSI->LRXHTOSETR = p_cfg->lp_rx_timeout; + R_MIPI_DSI->TATOSETR = p_cfg->turnaround_timeout; +} + +/*******************************************************************************************************************//** + * Returns base to the power of expon + * + * @param[in] base Base number + * @param[in] expon Exponent + **********************************************************************************************************************/ +static uint8_t dsi_pow (uint8_t base, uint8_t expon) +{ + uint8_t result = 1; + for (uint8_t i = 0; i < expon; i++) + { + result *= base; + } + + return result; +} + +/*******************************************************************************************************************//** + * Exit Reset + * Perform sequence steps 34.4.2.1.(2) in RZ/A3M hardware manual. + * + * NOTE: Calling this function is prohibited without first calling dsi_enter_reset(), which sets RSTCR.SWRST to 1 + * + * @param[in] p_cfg Pointer to MIPI DSI configuration structure + **********************************************************************************************************************/ +static void dsi_exit_reset (mipi_dsi_cfg_t const * const p_cfg) +{ + /* Transition data lanes to stop state */ + R_MIPI_DSI->RSTCR_b.FCETXSTP = 1U; + + /* Wait for data lanes transition to stop state */ + FSP_HARDWARE_REGISTER_WAIT((R_MIPI_DSI->RSTSR & + (R_MIPI_DSI_RSTSR_DL0DIR_Msk | R_MIPI_DSI_RSTSR_DLSTPST_Msk)), + (((uint32_t) (dsi_pow(2, p_cfg->num_lanes)) - 1) << R_MIPI_DSI_RSTSR_DLSTPST_Pos)); + + /* Clear the Force Tx Stop and Software Reset bits */ + R_MIPI_DSI->RSTCR_b.FCETXSTP = 0U; + R_MIPI_DSI->RSTCR_b.SWRST = 0U; + + /* Wait for software reset to complete */ + FSP_HARDWARE_REGISTER_WAIT((R_MIPI_DSI->RSTSR & MIPI_DSI_RSTSR_RESET_BITS), 0); +} + +/*******************************************************************************************************************//** + * Initialize High Speed Clock + * Perform sequence steps from section 34.4.2.2 in RZ/A3M hardware manual. + * + * @param[in] p_ctrl Pointer to MIPI DSI instance control block + **********************************************************************************************************************/ +static void dsi_hs_clock_start (mipi_dsi_b_instance_ctrl_t * p_ctrl) +{ + mipi_dsi_cfg_t const * p_cfg = p_ctrl->p_cfg; + + /* Enable clock lane */ + R_MIPI_DSI->TXSETR_b.CLEN = 1U; + p_ctrl->clock_state = MIPI_DSI_CLOCK_STATE_STARTING; + + R_MIPI_DSI->HSCLKSETR = R_MIPI_DSI_HSCLKSETR_HSCLKRUN_Msk | + (p_cfg->continuous_clock ? R_MIPI_DSI_HSCLKSETR_HSCLKMODE_Msk : 0U); + + while ((R_MIPI_DSI->PLSR_b.CLLP2HS != p_cfg->continuous_clock) && + (p_ctrl->clock_state != MIPI_DSI_CLOCK_STATE_STARTED)) + { + /* Wait for HS clock notification bit set to 1. (only in the continuous clock mode) + * NOTE: PLSR may be modified in ISR */ + } + + p_ctrl->clock_state = MIPI_DSI_CLOCK_STATE_STARTED; +} + +/*********************************************************************************************************************** + * De-initialize High Speed Clock + * Perform sequence steps from section 34.4.2.2 in RZ/A3M hardware manual. + * + * @param[in] p_ctrl Pointer to MIPI DSI instance control block + **********************************************************************************************************************/ +static void dsi_hs_clock_stop (mipi_dsi_b_instance_ctrl_t * p_ctrl) +{ + mipi_dsi_cfg_t const * p_cfg = p_ctrl->p_cfg; + + R_MIPI_DSI->HSCLKSETR_b.HSCLKRUN = 0; + p_ctrl->clock_state = MIPI_DSI_CLOCK_STATE_STOPPING; + + while ((R_MIPI_DSI->PLSR_b.CLHS2LP != p_cfg->continuous_clock) && + (p_ctrl->clock_state != MIPI_DSI_CLOCK_STATE_IDLE)) + { + /* Wait for clock lane transition LP state. + * NOTE: PLSR may be modified in ISR */ + } + + p_ctrl->clock_state = MIPI_DSI_CLOCK_STATE_IDLE; +} + +/*********************************************************************************************************************** + * Initialize Video Output Registers + * Perform sequence steps 4 and 6 from section 34.4.2.4.(1) in RZ/A3M hardware manual. + * + * @param[in] p_cfg Pointer to MIPI DSI configuration structure + **********************************************************************************************************************/ +static void dsi_init_video (mipi_dsi_cfg_t const * p_cfg) +{ + R_MIPI_DSI->VICH1PPSETR = + (((uint32_t) p_cfg->sync_pulse << R_MIPI_DSI_VICH1PPSETR_TXESYNC_Pos) & R_MIPI_DSI_VICH1PPSETR_TXESYNC_Msk) | + (((uint32_t) p_cfg->data_type << R_MIPI_DSI_VICH1PPSETR_DT_Pos) & R_MIPI_DSI_VICH1PPSETR_DT_Msk) | + (((uint32_t) p_cfg->virtual_channel_id << R_MIPI_DSI_VICH1PPSETR_VC_Pos) & + R_MIPI_DSI_VICH1PPSETR_VC_Msk); + R_MIPI_DSI->VICH1VSSETR = + ((p_cfg->vertical_sync_lines << R_MIPI_DSI_VICH1VSSETR_VSA_Pos) & R_MIPI_DSI_VICH1VSSETR_VSA_Msk) | + (((uint32_t) p_cfg->vertical_sync_polarity << R_MIPI_DSI_VICH1VSSETR_VSPOL_Pos) & + R_MIPI_DSI_VICH1VSSETR_VSPOL_Msk) | + ((p_cfg->vertical_active_lines << R_MIPI_DSI_VICH1VSSETR_VACTIVE_Pos) & + R_MIPI_DSI_VICH1VSSETR_VACTIVE_Msk); + R_MIPI_DSI->VICH1VPSETR = + ((p_cfg->vertical_back_porch << R_MIPI_DSI_VICH1VPSETR_VBP_Pos) & R_MIPI_DSI_VICH1VPSETR_VBP_Msk) | + ((p_cfg->vertical_front_porch << R_MIPI_DSI_VICH1VPSETR_VFP_Pos) & + R_MIPI_DSI_VICH1VPSETR_VFP_Msk); + R_MIPI_DSI->VICH1HSSETR = + ((p_cfg->horizontal_sync_lines << R_MIPI_DSI_VICH1HSSETR_HSA_Pos) & R_MIPI_DSI_VICH1HSSETR_HSA_Msk) | + (((uint32_t) p_cfg->horizontal_sync_polarity << R_MIPI_DSI_VICH1HSSETR_HSPOL_Pos) & + R_MIPI_DSI_VICH1HSSETR_HSPOL_Msk) | + ((p_cfg->horizontal_active_lines << R_MIPI_DSI_VICH1HSSETR_HACTIVE_Pos) & + R_MIPI_DSI_VICH1HSSETR_HACTIVE_Msk); + R_MIPI_DSI->VICH1HPSETR = + ((p_cfg->horizontal_back_porch << R_MIPI_DSI_VICH1HPSETR_HBP_Pos) & R_MIPI_DSI_VICH1HPSETR_HBP_Msk) | + ((p_cfg->horizontal_front_porch << R_MIPI_DSI_VICH1HPSETR_HFP_Pos) & + R_MIPI_DSI_VICH1HPSETR_HFP_Msk); + R_MIPI_DSI->VICH1SET1R = + ((p_cfg->video_mode_delay << R_MIPI_DSI_VICH1SET1R_DLY_Pos) & R_MIPI_DSI_VICH1SET1R_DLY_Msk); + + R_MIPI_DSI->VICH1SET0R = p_cfg->hsa_no_lp | p_cfg->hbp_no_lp | p_cfg->hfp_no_lp; + R_MIPI_DSI->VICH1SET0R_b.VSTART = (1U << R_MIPI_DSI_VICH1SET0R_VSTART_Pos) & R_MIPI_DSI_VICH1SET0R_VSTART_Msk; +} + +/*********************************************************************************************************************** + * Enable the specified ISR and add the control structure to the ISR context lookup table. + * + * @param[in] irq_cfg Pointer to interrupt configuration structure + * @param[in] p_ctrl Pointer to MIPI DSI instance control block + **********************************************************************************************************************/ +static void dsi_isr_enable (mipi_dsi_b_irq_cfg_t const * irq_cfg, mipi_dsi_b_instance_ctrl_t * p_ctrl) +{ + R_BSP_IrqCfgEnable(irq_cfg->irq, irq_cfg->ipl, p_ctrl); +} + +/*********************************************************************************************************************** + * Disable the specified ISR + * + * @param[in] irq_cfg Pointer to interrupt configuration structure + **********************************************************************************************************************/ +static void dsi_isr_disable (mipi_dsi_b_irq_cfg_t const * irq_cfg) +{ + R_BSP_IrqDisable(irq_cfg->irq); + R_FSP_IsrContextSet(irq_cfg->irq, NULL); +} + +/*********************************************************************************************************************** + * Interrupt Service Routines + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Sequence 0 ISR + * - Process LP sequence command events and forward them to the user callback + **********************************************************************************************************************/ +void mipi_dsi_seq0 (IRQn_Type const irq) { + /* Save context if RTOS is used */ + FSP_CONTEXT_SAVE; + + /* Clear sequence channel 0 status register bits */ + uint32_t sqch0sr_bits = R_MIPI_DSI->SQCH0SR; + R_MIPI_DSI->SQCH0SCR = sqch0sr_bits; + + /* Clear the IR flag */ + R_BSP_IrqStatusClear(irq); + + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) R_FSP_IsrContextGet(irq); + mipi_dsi_callback_args_t args; + args.event = MIPI_DSI_EVENT_SEQUENCE_0; + args.tx_status = (mipi_dsi_sequence_status_t) sqch0sr_bits; + args.p_context = p_ctrl->p_context; + dsi_call_callback(p_ctrl, &args); + + /* Restore context if RTOS is used */ + FSP_CONTEXT_RESTORE; +} + +/*********************************************************************************************************************** + * Sequence 1 ISR + * - Process HS sequence command events and forward them to the user callback + **********************************************************************************************************************/ +void mipi_dsi_seq1 (IRQn_Type const irq) { + /* Save context if RTOS is used */ + FSP_CONTEXT_SAVE; + + /* Clear sequence channel 1 status register bits */ + uint32_t sqch1sr_bits = R_MIPI_DSI->SQCH1SR; + R_MIPI_DSI->SQCH1SCR = sqch1sr_bits; + + /* Clear the IR flag */ + R_BSP_IrqStatusClear(irq); + + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) R_FSP_IsrContextGet(irq); + mipi_dsi_callback_args_t args; + args.event = MIPI_DSI_EVENT_SEQUENCE_1; + args.tx_status = (mipi_dsi_sequence_status_t) sqch1sr_bits; + args.p_context = p_ctrl->p_context; + dsi_call_callback(p_ctrl, &args); + + /* Restore context if RTOS is used */ + FSP_CONTEXT_RESTORE; +} + +/*********************************************************************************************************************** + * Video Input ISR + * - Process DSI Video Input Events and forward them to the user callback + **********************************************************************************************************************/ +void mipi_dsi_vin1 (IRQn_Type const irq) { + /* Save context if RTOS is used */ + FSP_CONTEXT_SAVE; + + /* Clear video mode status register bits */ + uint32_t vmsr_bits = R_MIPI_DSI->VICH1SR; + R_MIPI_DSI->VICH1SCR = vmsr_bits; + + /* Clear the IR flag */ + R_BSP_IrqStatusClear(irq); + + /* Update internal state */ + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) R_FSP_IsrContextGet(irq); + if (vmsr_bits & R_MIPI_DSI_VICH1SR_VIRDY_Msk) + { + p_ctrl->video_started = true; + } + else if (vmsr_bits & R_MIPI_DSI_VICH1SR_STOP_Msk) + { + p_ctrl->video_started = false; + } + else + { + // do nothing + } + + /* Pass data to user */ + mipi_dsi_callback_args_t args; + args.event = MIPI_DSI_EVENT_VIDEO; + args.video_status = (mipi_dsi_video_status_t) vmsr_bits; + args.p_context = p_ctrl->p_context; + dsi_call_callback(p_ctrl, &args); + + /* Perform reset according to RZA3M UM 34.4.2.6.(6) */ + if (vmsr_bits & (R_MIPI_DSI_VICH1SR_VBUFUDF_Msk | R_MIPI_DSI_VICH1SR_VBUFOVF_Msk | R_MIPI_DSI_VICH1SR_TIMERR_Msk)) + { + dsi_enter_reset(); + dsi_exit_reset(p_ctrl->p_cfg); + } + + /* Restore context if RTOS is used */ + FSP_CONTEXT_RESTORE; +} + +/*********************************************************************************************************************** + * Receive ISR + * - Process Receive Events and forward them to the user callback + **********************************************************************************************************************/ +void mipi_dsi_rcv (IRQn_Type const irq) { + /* Save context if RTOS is used */ + FSP_CONTEXT_SAVE; + + /* Clear receive status register bits */ + uint32_t rxsr_bits = R_MIPI_DSI->RXSR; + R_MIPI_DSI->RXSCR = rxsr_bits; + + /* Clear the IR flag */ + R_BSP_IrqStatusClear(irq); + + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) R_FSP_IsrContextGet(irq); + mipi_dsi_callback_args_t args; + args.event = MIPI_DSI_EVENT_RECEIVE; + args.rx_status = (mipi_dsi_receive_status_t) rxsr_bits; + args.p_result = (mipi_dsi_receive_result_t *) &R_MIPI_DSI->RXRSS0R; + args.p_context = p_ctrl->p_context; + dsi_call_callback(p_ctrl, &args); + + R_MIPI_DSI->RXRINFOOWSCR = R_MIPI_DSI_RXRINFOOWSCR_SLT0INFOOWC_Msk; // Clear slot 0 after reading + + /* Restore context if RTOS is used */ + FSP_CONTEXT_RESTORE; +} + +/*********************************************************************************************************************** + * Fatal Error ISR + * - Process Fatal Error Events and forward them to the user callback + **********************************************************************************************************************/ +void mipi_dsi_ferr (IRQn_Type const irq) { + /* Save context if RTOS is used */ + FSP_CONTEXT_SAVE; + + /* Clear receive status register bits */ + uint32_t ferrsr_bits = R_MIPI_DSI->FERRSR; + R_MIPI_DSI->FERRSCR = ferrsr_bits; + + /* Clear the IR flag */ + R_BSP_IrqStatusClear(irq); + + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) R_FSP_IsrContextGet(irq); + mipi_dsi_callback_args_t args; + args.event = MIPI_DSI_EVENT_FATAL; + args.fatal_status = (mipi_dsi_fatal_status_t) ferrsr_bits; + args.p_context = p_ctrl->p_context; + dsi_call_callback(p_ctrl, &args); + + /* Restore context if RTOS is used */ + FSP_CONTEXT_RESTORE; +} + +/*********************************************************************************************************************** + * PHY-Protocol Interface ISR + * - Process Phy-Protocol Events and forward them to the user callback + **********************************************************************************************************************/ +void mipi_dsi_ppi (IRQn_Type const irq) { + /* Save context if RTOS is used */ + FSP_CONTEXT_SAVE; + + /* Clear PLSR */ + uint32_t plsr_bits = R_MIPI_DSI->PLSR; + R_MIPI_DSI->PLSCR = plsr_bits; + + /* Clear the IR flag */ + R_BSP_IrqStatusClear(irq); + + /* Update internal state */ + mipi_dsi_b_instance_ctrl_t * p_ctrl = (mipi_dsi_b_instance_ctrl_t *) R_FSP_IsrContextGet(irq); + if ((p_ctrl->clock_state == MIPI_DSI_CLOCK_STATE_STARTING) && + (plsr_bits & R_MIPI_DSI_PLSR_CLLP2HS_Msk)) + { + p_ctrl->clock_state = MIPI_DSI_CLOCK_STATE_STARTED; + } + else if ((p_ctrl->clock_state == MIPI_DSI_CLOCK_STATE_STOPPING) && + (plsr_bits & R_MIPI_DSI_PLSR_CLHS2LP_Msk)) + { + p_ctrl->clock_state = MIPI_DSI_CLOCK_STATE_IDLE; + } + else + { + // do nothing + } + + /* Pass data to user */ + mipi_dsi_callback_args_t args; + args.event = MIPI_DSI_EVENT_PHY; + args.phy_status = (mipi_dsi_phy_status_t) plsr_bits; + args.p_context = p_ctrl->p_context; + dsi_call_callback(p_ctrl, &args); + + /* Restore context if RTOS is used */ + FSP_CONTEXT_RESTORE; +} diff --git a/drivers/rz/fsp/src/rza/r_mipi_phy_b/r_mipi_phy_b.c b/drivers/rz/fsp/src/rza/r_mipi_phy_b/r_mipi_phy_b.c new file mode 100644 index 00000000..ce115102 --- /dev/null +++ b/drivers/rz/fsp/src/rza/r_mipi_phy_b/r_mipi_phy_b.c @@ -0,0 +1,123 @@ +/* +* Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ +#include + +/*********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ +#define MIPI_PHY_OPEN (0x4D504950) + +/*********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Global variables + **********************************************************************************************************************/ + +const mipi_phy_b_api_t g_mipi_phy = +{ + .open = r_mipi_phy_b_open, + .close = r_mipi_phy_b_close, +}; + +/*********************************************************************************************************************** + * Private function prototypes + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Functions + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Initialize the MIPI PHY peripheral. + * + * @retval FSP_SUCCESS The channel was successfully opened. + * @retval FSP_ERR_ASSERTION One or both of the parameters was NULL. + * @retval FSP_ERR_ALREADY_OPEN The instance is already opened. + **********************************************************************************************************************/ +fsp_err_t r_mipi_phy_b_open (mipi_phy_b_ctrl_t * const p_api_ctrl, mipi_phy_b_cfg_t const * const p_cfg) +{ + mipi_phy_b_ctrl_t * p_ctrl = p_api_ctrl; + +#if MIPI_DSI_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + FSP_ASSERT(NULL != p_cfg); + FSP_ERROR_RETURN(MIPI_PHY_OPEN != p_ctrl->open, FSP_ERR_ALREADY_OPEN); +#endif + + R_MIPI_DSI->DSIDPHYCTRL0_b.EN_BGR = 0b1; + + R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MICROSECONDS); + R_MIPI_DSI->DSIDPHYCTRL0_b.EN_LDO1200 = 0b1; + + R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MICROSECONDS); + + /* Set D-PHY timing parameters */ + mipi_phy_b_timing_t const * p_timing = p_cfg->p_timing; + R_MIPI_DSI->DSIDPHYTIM0 = (p_timing->t_init << R_MIPI_DSI_DSIDPHYTIM0_T_INIT_Pos) & + R_MIPI_DSI_DSIDPHYTIM0_T_INIT_Msk; + R_MIPI_DSI->DSIDPHYTIM1 = + (uint32_t) (((p_timing->t_hs_prep << R_MIPI_DSI_DSIDPHYTIM1_THS_PREPARE_Pos) & + R_MIPI_DSI_DSIDPHYTIM1_THS_PREPARE_Msk) | + ((p_timing->t_clk_prep << R_MIPI_DSI_DSIDPHYTIM1_TCLK_PREPARE_Pos) & + R_MIPI_DSI_DSIDPHYTIM1_TCLK_PREPARE_Msk)); + R_MIPI_DSI->DSIDPHYTIM2 = + (uint32_t) (((p_timing->t_clk_trail << R_MIPI_DSI_DSIDPHYTIM2_TCLK_TRAIL_Pos) & + R_MIPI_DSI_DSIDPHYTIM2_TCLK_TRAIL_Msk) | + ((p_timing->t_clk_post << R_MIPI_DSI_DSIDPHYTIM2_TCLK_POST_Pos) & + R_MIPI_DSI_DSIDPHYTIM2_TCLK_POST_Msk) | + ((p_timing->t_clk_pre << R_MIPI_DSI_DSIDPHYTIM2_TCLK_PRE_Pos) & + R_MIPI_DSI_DSIDPHYTIM2_TCLK_POST_Msk) | + ((p_timing->t_clk_zero << R_MIPI_DSI_DSIDPHYTIM2_TCLK_ZERO_Pos) & + R_MIPI_DSI_DSIDPHYTIM2_TCLK_ZERO_Msk)); + R_MIPI_DSI->DSIDPHYTIM3 = + (uint32_t) (((p_timing->t_lp_exit << R_MIPI_DSI_DSIDPHYTIM3_TLPX_Pos) & R_MIPI_DSI_DSIDPHYTIM3_TLPX_Msk) | + ((p_timing->t_hs_exit << R_MIPI_DSI_DSIDPHYTIM3_THS_EXIT_Pos) & + R_MIPI_DSI_DSIDPHYTIM3_THS_EXIT_Msk) | + ((p_timing->t_hs_trail << R_MIPI_DSI_DSIDPHYTIM3_THS_TRAIL_Pos) & + R_MIPI_DSI_DSIDPHYTIM3_THS_TRAIL_Msk) | + ((p_timing->t_hs_zero << R_MIPI_DSI_DSIDPHYTIM3_THS_ZERO_Pos) & + R_MIPI_DSI_DSIDPHYTIM3_THS_ZERO_Msk)); + + /* Keep track of p_cfg struct */ + p_ctrl->p_cfg = p_cfg; + + /* Mark control block as opened */ + p_ctrl->open = MIPI_PHY_OPEN; + + return FSP_SUCCESS; +} + +/*********************************************************************************************************************** + * Stop filter operations and close the channel instance. + * + * @retval FSP_SUCCESS The channel is successfully closed. + * @retval FSP_ERR_ASSERTION p_api_ctrl is NULL. + * @retval FSP_ERR_NOT_OPEN Instance is not open. + **********************************************************************************************************************/ +fsp_err_t r_mipi_phy_b_close (mipi_phy_b_ctrl_t * const p_api_ctrl) +{ + mipi_phy_b_ctrl_t * p_ctrl = p_api_ctrl; + +#if MIPI_DSI_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(MIPI_PHY_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); +#endif + + R_MIPI_DSI->DSIDPHYCTRL0_b.EN_BGR = 0U; + + R_MIPI_DSI->DSIDPHYCTRL0_b.EN_LDO1200 = 0U; + + /* Set control block to closed */ + p_ctrl->open = 0U; + + return FSP_SUCCESS; +} diff --git a/zephyr/rz/rz_cfg/fsp_cfg/rza/r_lcdc_cfg.h b/zephyr/rz/rz_cfg/fsp_cfg/rza/r_lcdc_cfg.h new file mode 100644 index 00000000..97375467 --- /dev/null +++ b/zephyr/rz/rz_cfg/fsp_cfg/rza/r_lcdc_cfg.h @@ -0,0 +1,10 @@ +/* +* Copyright (c) 2020 - 2025 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef R_LCDC_CFG_H_ +#define R_LCDC_CFG_H_ +#define LCDC_CFG_PARAM_CHECKING_ENABLE (BSP_CFG_PARAM_CHECKING_ENABLE) +#endif /* R_LCDC_CFG_H_ */ diff --git a/zephyr/rz/rz_cfg/fsp_cfg/rza/r_mipi_dsi_cfg.h b/zephyr/rz/rz_cfg/fsp_cfg/rza/r_mipi_dsi_cfg.h new file mode 100644 index 00000000..ae16dac5 --- /dev/null +++ b/zephyr/rz/rz_cfg/fsp_cfg/rza/r_mipi_dsi_cfg.h @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2020 - 2025 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef R_MIPI_DSI_CFG_H_ +#define R_MIPI_DSI_CFG_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#define MIPI_DSI_CFG_PARAM_CHECKING_ENABLE ((BSP_CFG_PARAM_CHECKING_ENABLE)) + +#ifdef __cplusplus +} +#endif +#endif /* R_MIPI_DSI_CFG_H_ */