feat(dsi): split the dphy config clock and pll reference clock

this is a breaking change in the esp32p4 ver3.0 silicon.
This commit is contained in:
morris
2025-09-08 18:57:46 +08:00
parent b7fc7acb23
commit eedbd9f8e3
24 changed files with 469 additions and 235 deletions

View File

@@ -300,6 +300,7 @@ static inline void dw_gdma_ll_channel_clear_intr(dw_gdma_dev_t *dev, uint8_t cha
* @param channel Channel number
* @param en True to enable, false to disable
*/
__attribute__((always_inline))
static inline void dw_gdma_ll_channel_enable(dw_gdma_dev_t *dev, uint8_t channel, bool en)
{
if (en) {
@@ -818,6 +819,7 @@ static inline void dw_gdma_ll_channel_set_dst_outstanding_limit(dw_gdma_dev_t *d
* @param channel Channel number
* @param addr Address of the first link list item, it must be aligned 64 bytes
*/
__attribute__((always_inline))
static inline void dw_gdma_ll_channel_set_link_list_head_addr(dw_gdma_dev_t *dev, uint8_t channel, uint32_t addr)
{
dev->ch[channel].llp0.loc0 = addr >> 6;
@@ -846,6 +848,7 @@ static inline intptr_t dw_gdma_ll_channel_get_current_link_list_item_addr(dw_gdm
* @param channel Channel number
* @param port Master port
*/
__attribute__((always_inline))
static inline void dw_gdma_ll_channel_set_link_list_master_port(dw_gdma_dev_t *dev, uint8_t channel, uint32_t port)
{
dev->ch[channel].llp0.lms = port;

View File

@@ -16,6 +16,7 @@
#define MIPI_DSI_LL_GET_BRG(bus_id) (bus_id == 0 ? &MIPI_DSI_BRIDGE : NULL)
#define MIPI_DSI_LL_EVENT_UNDERRUN (1 << 0)
#define MIPI_DSI_LL_EVENT_VSYNC (1 << 1)
#ifdef __cplusplus
extern "C" {
@@ -167,78 +168,6 @@ static inline void mipi_dsi_brg_ll_credit_reset(dsi_brg_dev_t *dev)
dev->raw_buf_credit_ctl.credit_reset = 1;
}
/**
* @brief Set the color coding for the bridge controller
*
* @param dev Pointer to the DSI bridge controller register base address
* @param color_coding Color coding value
* @param sub_config Sub configuration
*/
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
static inline void mipi_dsi_brg_ll_set_pixel_format(dsi_brg_dev_t *dev, lcd_color_format_t color_coding, uint32_t sub_config)
{
switch (color_coding) {
case LCD_COLOR_FMT_RGB565:
dev->pixel_type.raw_type = 2;
dev->pixel_type.dpi_type = 2;
break;
case LCD_COLOR_FMT_RGB666:
dev->pixel_type.raw_type = 1;
dev->pixel_type.dpi_type = 1;
break;
case LCD_COLOR_FMT_RGB888:
dev->pixel_type.raw_type = 0;
dev->pixel_type.dpi_type = 0;
break;
default:
// MIPI DSI host can only accept RGB data, no YUV data
HAL_ASSERT(false);
break;
}
dev->pixel_type.dpi_config = sub_config;
}
#else
static inline void mipi_dsi_brg_ll_set_pixel_format(dsi_brg_dev_t *dev, lcd_color_format_t color_coding, uint32_t sub_config)
{
switch (color_coding) {
case LCD_COLOR_FMT_RGB565:
dev->pixel_type.raw_type = 2;
break;
case LCD_COLOR_FMT_RGB666:
dev->pixel_type.raw_type = 1;
break;
case LCD_COLOR_FMT_RGB888:
dev->pixel_type.raw_type = 0;
break;
default:
// MIPI DSI host can only accept RGB data, no YUV data
HAL_ASSERT(false);
break;
}
dev->pixel_type.dpi_config = sub_config;
}
#endif
/**
* @brief Set the color space for input color data
*
* @param dev Pointer to the DSI bridge controller register base address
* @param color_space Color space type
*/
static inline void mipi_dsi_brg_ll_set_input_color_space(dsi_brg_dev_t *dev, lcd_color_space_t color_space)
{
switch (color_space) {
case LCD_COLOR_SPACE_RGB:
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_SPACE_YUV:
dev->pixel_type.data_in_type = 1;
break;
default:
abort();
}
}
/**
* @brief Set the vertical timing parameters for the bridge controller
*
@@ -402,6 +331,157 @@ static inline void mipi_dsi_brg_ll_set_yuv422_pack_order(dsi_brg_dev_t *dev, lcd
}
}
/**********************************************************************************************************************/
/************************ The following functions behave differently based on the chip revision ***********************/
/**********************************************************************************************************************/
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
/**
* @brief Set the color format for the input color data
*
* @param dev Pointer to the DSI bridge controller register base address
* @param color_format Color format
*/
static inline void mipi_dsi_brg_ll_set_input_color_format(dsi_brg_dev_t *dev, lcd_color_format_t color_format)
{
switch (color_format) {
case LCD_COLOR_FMT_RGB888:
dev->pixel_type.raw_type = 0;
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_FMT_RGB666:
dev->pixel_type.raw_type = 1;
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_FMT_RGB565:
dev->pixel_type.raw_type = 2;
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_FMT_YUV422:
dev->pixel_type.raw_type = 9;
dev->pixel_type.data_in_type = 1;
break;
default:
abort();
}
}
/**
* @brief Set the color space for output color data
*
* @param dev Pointer to the DSI bridge controller register base address
* @param color_format Color format
*/
static inline void mipi_dsi_brg_ll_set_output_color_format(dsi_brg_dev_t *dev, lcd_color_format_t color_format, uint32_t sub_config)
{
switch (color_format) {
case LCD_COLOR_FMT_RGB888:
dev->pixel_type.dpi_type = 0;
break;
case LCD_COLOR_FMT_RGB666:
dev->pixel_type.dpi_type = 1;
break;
case LCD_COLOR_FMT_RGB565:
dev->pixel_type.dpi_type = 2;
break;
default:
abort();
}
dev->pixel_type.dpi_config = sub_config;
}
/**
* @brief Reset the DSI bridge module
*
* @param dev Pointer to the DSI bridge controller register base address
*/
static inline void mipi_dsi_brg_ll_reset(dsi_brg_dev_t *dev)
{
dev->en.dsi_brig_rst = 1;
dev->en.dsi_brig_rst = 0;
}
/**
* @brief Set the color range of input data
*
* @param dev LCD register base address
* @param range Color range
*/
static inline void mipi_dsi_brg_ll_set_input_color_range(dsi_brg_dev_t *dev, lcd_color_range_t range)
{
if (range == LCD_COLOR_RANGE_LIMIT) {
dev->yuv_cfg.yuv_range = 0;
} else if (range == LCD_COLOR_RANGE_FULL) {
dev->yuv_cfg.yuv_range = 1;
}
}
#else
/**
* @brief Set the color format for the input color data
*
* @param dev Pointer to the DSI bridge controller register base address
* @param color_format Color format
*/
static inline void mipi_dsi_brg_ll_set_input_color_format(dsi_brg_dev_t *dev, lcd_color_format_t color_format)
{
switch (color_format) {
case LCD_COLOR_FMT_RGB888:
dev->pixel_type.raw_type = 0;
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_FMT_RGB666:
dev->pixel_type.raw_type = 1;
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_FMT_RGB565:
dev->pixel_type.raw_type = 2;
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_FMT_YUV422:
dev->pixel_type.data_in_type = 1;
break;
default:
abort();
}
}
/**
* @brief Set the color space for output color data
*
* @param dev Pointer to the DSI bridge controller register base address
* @param color_format Color format
*/
static inline void mipi_dsi_brg_ll_set_output_color_format(dsi_brg_dev_t *dev, lcd_color_format_t color_format, uint32_t sub_config)
{
switch (color_format) {
case LCD_COLOR_FMT_RGB565:
dev->pixel_type.raw_type = 2;
break;
case LCD_COLOR_FMT_RGB666:
dev->pixel_type.raw_type = 1;
break;
case LCD_COLOR_FMT_RGB888:
dev->pixel_type.raw_type = 0;
break;
default:
abort();
}
dev->pixel_type.dpi_config = sub_config;
}
static inline void mipi_dsi_brg_ll_reset(dsi_brg_dev_t *dev)
{
// Not supported
}
static inline void mipi_dsi_brg_ll_set_input_color_range(dsi_brg_dev_t *dev, lcd_color_range_t range)
{
// Not supported
}
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -10,6 +10,7 @@
#include <stdint.h>
#include "soc/hp_sys_clkrst_struct.h"
#include "hal/misc.h"
#include "hal/config.h"
#include "hal/mipi_dsi_host_ll.h"
#include "hal/mipi_dsi_brg_ll.h"
#include "hal/mipi_dsi_phy_ll.h"
@@ -91,11 +92,14 @@ static inline void mipi_dsi_ll_set_dpi_clock_source(int group_id, mipi_dsi_dpi_c
case MIPI_DSI_DPI_CLK_SRC_XTAL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 0;
break;
case MIPI_DSI_DPI_CLK_SRC_PLL_F240M:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 1;
break;
case MIPI_DSI_DPI_CLK_SRC_PLL_F160M:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 2;
break;
case MIPI_DSI_DPI_CLK_SRC_PLL_F240M:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 1;
case MIPI_DSI_DPI_CLK_SRC_APLL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 3;
break;
default:
abort();
@@ -148,41 +152,22 @@ static inline void mipi_dsi_ll_enable_phy_config_clock(int group_id, bool enable
} while(0)
/**
* @brief Enable MIPI DSI PHY PLL reference clock
*
* @param group_id Group ID
* @param enable true to enable, false to disable
*/
static inline void mipi_dsi_ll_enable_phy_reference_clock(int group_id, bool enable)
{
(void)group_id;
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define mipi_dsi_ll_enable_phy_reference_clock(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
mipi_dsi_ll_enable_phy_reference_clock(__VA_ARGS__); \
} while(0)
/**
* @brief Set the clock source for the DSI PHY interface
* @brief Set the clock source for the DSI PHY configuration interface
*
* @param group_id Group ID
* @param source Clock source
*/
static inline void mipi_dsi_ll_set_phy_clock_source(int group_id, mipi_dsi_phy_clock_source_t source)
static inline void _mipi_dsi_ll_set_phy_config_clock_source(int group_id, soc_periph_mipi_dsi_phy_cfg_clk_src_t source)
{
(void)group_id;
switch (source) {
case MIPI_DSI_PHY_CLK_SRC_PLL_F20M:
case MIPI_DSI_PHY_CFG_CLK_SRC_PLL_F20M:
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 0;
break;
case MIPI_DSI_PHY_CLK_SRC_RC_FAST:
case MIPI_DSI_PHY_CFG_CLK_SRC_RC_FAST:
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 1;
break;
case MIPI_DSI_PHY_CLK_SRC_PLL_F25M:
case MIPI_DSI_PHY_CFG_CLK_SRC_PLL_F25M:
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 2;
break;
default:
@@ -192,11 +177,136 @@ static inline void mipi_dsi_ll_set_phy_clock_source(int group_id, mipi_dsi_phy_c
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define mipi_dsi_ll_set_phy_clock_source(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
mipi_dsi_ll_set_phy_clock_source(__VA_ARGS__); \
#define mipi_dsi_ll_set_phy_config_clock_source(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_mipi_dsi_ll_set_phy_config_clock_source(__VA_ARGS__); \
} while(0)
/**
* @brief Enable MIPI DSI PHY PLL reference clock
*
* @param group_id Group ID
* @param enable true to enable, false to disable
*/
static inline void mipi_dsi_ll_enable_phy_pllref_clock(int group_id, bool enable)
{
(void)group_id;
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define mipi_dsi_ll_enable_phy_pllref_clock(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
mipi_dsi_ll_enable_phy_pllref_clock(__VA_ARGS__); \
} while(0)
/**********************************************************************************************************************/
/************************ The following functions behave differently based on the chip revision ***********************/
/**********************************************************************************************************************/
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
/**
* @brief Set the clock source for the DSI PHY PLL reference clock
*
* @param group_id Group ID
* @param source Clock source
*/
static inline void _mipi_dsi_ll_set_phy_pllref_clock_source(int group_id, mipi_dsi_phy_pllref_clock_source_t source)
{
(void)group_id;
switch (source) {
case MIPI_DSI_PHY_PLLREF_CLK_SRC_XTAL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_src_sel = 0;
break;
case MIPI_DSI_PHY_PLLREF_CLK_SRC_APLL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_src_sel = 1;
break;
case MIPI_DSI_PHY_PLLREF_CLK_SRC_CPLL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_src_sel = 2;
break;
case MIPI_DSI_PHY_PLLREF_CLK_SRC_SPLL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_src_sel = 3;
break;
case MIPI_DSI_PHY_PLLREF_CLK_SRC_MPLL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_src_sel = 4;
break;
default:
abort();
}
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define mipi_dsi_ll_set_phy_pllref_clock_source(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_mipi_dsi_ll_set_phy_pllref_clock_source(__VA_ARGS__); \
} while(0)
/**
* @brief Set the clock division factor for the DSI PHY clock source
*
* @param group_id Group ID
* @param div Division factor
*/
static inline void _mipi_dsi_ll_set_phy_pll_ref_clock_div(int group_id, uint32_t div)
{
(void) group_id;
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl03, reg_mipi_dsi_dphy_pll_refclk_div_num, div - 1);
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define mipi_dsi_ll_set_phy_pll_ref_clock_div(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_mipi_dsi_ll_set_phy_pll_ref_clock_div(__VA_ARGS__);\
} while (0)
#else
/**
* @brief Set the clock source for the DSI PHY PLL reference clock
*
* @note The PHY PLL reference clock source is same as PHY configuration clock source
*
* @param group_id Group ID
* @param source Clock source
*/
static inline void _mipi_dsi_ll_set_phy_pllref_clock_source(int group_id, mipi_dsi_phy_pllref_clock_source_t source)
{
(void)group_id;
switch (source) {
case MIPI_DSI_PHY_PLLREF_CLK_SRC_PLL_F20M:
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 0;
break;
case MIPI_DSI_PHY_PLLREF_CLK_SRC_RC_FAST:
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 1;
break;
case MIPI_DSI_PHY_PLLREF_CLK_SRC_PLL_F25M:
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 2;
break;
default:
abort();
}
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define mipi_dsi_ll_set_phy_pllref_clock_source(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_mipi_dsi_ll_set_phy_pllref_clock_source(__VA_ARGS__); \
} while(0)
static inline void mipi_dsi_ll_set_phy_pll_ref_clock_div(int group_id, uint32_t div)
{
// not supported
(void)group_id;
(void)div;
}
#endif
#ifdef __cplusplus
}
#endif