@@ -38,6 +38,7 @@ struct mipi_dsi_stm32_config {
3838 const struct device * rcc ;
3939 const struct reset_dt_spec reset ;
4040 struct stm32_pclken dsi_clk ;
41+ struct stm32_pclken dsisrc_clk ;
4142 struct stm32_pclken ref_clk ;
4243 struct stm32_pclken pix_clk ;
4344 uint32_t data_lanes ;
@@ -56,6 +57,27 @@ struct mipi_dsi_stm32_data {
5657 uint32_t pixel_clk_khz ;
5758};
5859
60+ #if DT_HAS_COMPAT_STATUS_OKAY (st_stm32u5_mipi_dsi )
61+ /* Configures DSI PHY as DSI clock source (STM32U5 specific) */
62+ static int stm32_dsi_clock_source_config (const struct device * dev )
63+ {
64+ const struct mipi_dsi_stm32_config * config = dev -> config ;
65+ int ret ;
66+
67+ ret = clock_control_configure (config -> rcc , (clock_control_subsys_t )& config -> dsisrc_clk ,
68+ NULL );
69+ if (ret < 0 ) {
70+ LOG_ERR ("Failed to configure DSI clock source (%d)" , ret );
71+ return ret ;
72+ }
73+
74+ LOG_DBG ("DSI kernel clock source selection, RCC_CCIPR2_DSIHOSTSEL: %u" ,
75+ __HAL_RCC_GET_DSI_SOURCE () == RCC_DSICLKSOURCE_DSIPHY );
76+
77+ return 0 ;
78+ }
79+ #endif
80+
5981static void mipi_dsi_stm32_log_config (const struct device * dev )
6082{
6183 const struct mipi_dsi_stm32_config * config = dev -> config ;
@@ -66,9 +88,20 @@ static void mipi_dsi_stm32_log_config(const struct device *dev)
6688 LOG_DBG (" AutomaticClockLaneControl 0x%x" , data -> hdsi .Init .AutomaticClockLaneControl );
6789 LOG_DBG (" TXEscapeCkdiv %u" , data -> hdsi .Init .TXEscapeCkdiv );
6890 LOG_DBG (" NumberOfLanes %u" , data -> hdsi .Init .NumberOfLanes );
91+ #if DT_HAS_COMPAT_STATUS_OKAY (st_stm32u5_mipi_dsi )
92+ LOG_DBG (" PHYFrequencyRange 0x%x" , data -> hdsi .Init .PHYFrequencyRange );
93+ LOG_DBG (" PHYLowPowerOffset 0x%x" , data -> hdsi .Init .PHYLowPowerOffset );
94+ #endif
95+
96+ LOG_DBG ("PLLInit configuration:" );
6997 LOG_DBG (" PLLNDIV %u" , data -> pll_init .PLLNDIV );
7098 LOG_DBG (" PLLIDF %u" , data -> pll_init .PLLIDF );
7199 LOG_DBG (" PLLODF %u" , data -> pll_init .PLLODF );
100+ #if DT_HAS_COMPAT_STATUS_OKAY (st_stm32u5_mipi_dsi )
101+ LOG_DBG (" PLLVCORange 0x%x" , data -> pll_init .PLLVCORange );
102+ LOG_DBG (" PLLChargePump 0x%x" , data -> pll_init .PLLChargePump );
103+ LOG_DBG (" PLLTuning 0x%x" , data -> pll_init .PLLTuning );
104+ #endif
72105
73106 LOG_DBG ("HAL_DSI_ConfigVideoMode setup:" );
74107 LOG_DBG (" VirtualChannelID %u" , data -> vid_cfg .VirtualChannelID );
@@ -168,9 +201,15 @@ static int mipi_dsi_stm32_host_init(const struct device *dev)
168201 return ret ;
169202 }
170203
204+ #if DT_HAS_COMPAT_STATUS_OKAY (st_stm32u5_mipi_dsi )
205+ /* LANE_BYTE_CLOCK = CLK_IN / PLLIDF * 2 * PLLNDIV / PLLODF / 8 */
206+ data -> lane_clk_khz = hse_clock / data -> pll_init .PLLIDF * 2 * data -> pll_init .PLLNDIV /
207+ data -> pll_init .PLLODF / 8 / 1000 ;
208+ #else
171209 /* LANE_BYTE_CLOCK = CLK_IN / PLLIDF * 2 * PLLNDIV / 2 / PLLODF / 8 */
172210 data -> lane_clk_khz = hse_clock / data -> pll_init .PLLIDF * 2 * data -> pll_init .PLLNDIV / 2 /
173211 (1UL << data -> pll_init .PLLODF ) / 8 / 1000 ;
212+ #endif
174213
175214 /* stm32x_hal_dsi: The values 0 and 1 stop the TX_ESC clock generation */
176215 data -> hdsi .Init .TXEscapeCkdiv = 0 ;
@@ -213,13 +252,16 @@ static int mipi_dsi_stm32_host_init(const struct device *dev)
213252 return - EIO ;
214253 }
215254
255+ #ifndef CONFIG_SOC_SERIES_STM32U5X
256+
216257 if (config -> lp_rx_filter_freq ) {
217258 hal_ret = HAL_DSI_SetLowPowerRXFilter (& data -> hdsi , config -> lp_rx_filter_freq );
218259 if (hal_ret != HAL_OK ) {
219260 LOG_ERR ("Setup DSI LP RX filter failed! (%d)" , hal_ret );
220261 return - EIO ;
221262 }
222263 }
264+ #endif
223265
224266 hal_ret = HAL_DSI_ConfigErrorMonitor (& data -> hdsi , config -> active_errors );
225267 if (hal_ret != HAL_OK ) {
@@ -290,6 +332,14 @@ static int mipi_dsi_stm32_attach(const struct device *dev, uint8_t channel,
290332 return - EIO ;
291333 }
292334
335+ #if DT_HAS_COMPAT_STATUS_OKAY (st_stm32u5_mipi_dsi )
336+ ret = stm32_dsi_clock_source_config (dev );
337+ if (ret < 0 ) {
338+ LOG_ERR ("Failed to configure DSI clock source" );
339+ return ret ;
340+ }
341+ #endif
342+
293343 if (IS_ENABLED (CONFIG_MIPI_DSI_LOG_LEVEL_DBG )) {
294344 mipi_dsi_stm32_log_config (dev );
295345 }
@@ -458,6 +508,12 @@ static int mipi_dsi_stm32_init(const struct device *dev)
458508 .enr = DT_INST_CLOCKS_CELL_BY_NAME(inst, dsiclk, bits), \
459509 .bus = DT_INST_CLOCKS_CELL_BY_NAME(inst, dsiclk, bus), \
460510 }, \
511+ COND_CODE_1(DT_INST_CLOCKS_HAS_NAME(inst, dsisrc), \
512+ (.dsisrc_clk = { \
513+ .enr = DT_INST_CLOCKS_CELL_BY_NAME(inst, dsisrc, bits), \
514+ .bus = DT_INST_CLOCKS_CELL_BY_NAME(inst, dsisrc, bus), \
515+ },), \
516+ (.dsisrc_clk = {0},)) \
461517 .ref_clk = { \
462518 .enr = DT_INST_CLOCKS_CELL_BY_NAME(inst, refclk, bits), \
463519 .bus = DT_INST_CLOCKS_CELL_BY_NAME(inst, refclk, bus), \
@@ -480,6 +536,13 @@ static int mipi_dsi_stm32_init(const struct device *dev)
480536 DT_INST_PROP(inst, non_continuous) ? \
481537 DSI_AUTO_CLK_LANE_CTRL_ENABLE : \
482538 DSI_AUTO_CLK_LANE_CTRL_DISABLE, \
539+ COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, phy_freq_range), \
540+ (.PHYFrequencyRange = DT_INST_PROP(inst, phy_freq_range),),\
541+ ()) \
542+ COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, phy_low_power_offset), \
543+ (.PHYLowPowerOffset = \
544+ DT_INST_PROP(inst, phy_low_power_offset),), \
545+ ()) \
483546 }, \
484547 }, \
485548 .host_timeouts = COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, host_timeouts), \
@@ -495,15 +558,25 @@ static int mipi_dsi_stm32_init(const struct device *dev)
495558 DSI_DATA_ENABLE_ACTIVE_HIGH : DSI_DATA_ENABLE_ACTIVE_LOW, \
496559 .LooselyPacked = DT_INST_PROP(inst, loosely_packed) ? \
497560 DSI_LOOSELY_PACKED_ENABLE : DSI_LOOSELY_PACKED_DISABLE, \
498- .LPLargestPacketSize = DT_INST_PROP_OR(inst, largest_packet_size, 4), \
561+ .LPLargestPacketSize = DT_INST_PROP_OR(inst, largest_packet_size, 4), \
499562 .LPVACTLargestPacketSize = DT_INST_PROP_OR(inst, largest_packet_size, 4), \
500563 .FrameBTAAcknowledgeEnable = DT_INST_PROP(inst, bta_ack_disable) ? \
501- DSI_FBTAA_DISABLE : DSI_FBTAA_ENABLE, \
564+ DSI_FBTAA_DISABLE : DSI_FBTAA_ENABLE, \
502565 }, \
503566 .pll_init = { \
504567 .PLLNDIV = DT_INST_PROP(inst, pll_ndiv), \
505568 .PLLIDF = DT_INST_PROP(inst, pll_idf), \
506569 .PLLODF = DT_INST_PROP(inst, pll_odf), \
570+ COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, pll_vco_range), \
571+ (.PLLVCORange = DT_INST_PROP(inst, pll_vco_range),), \
572+ ()) \
573+ COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, pll_charge_pump), \
574+ (.PLLChargePump = \
575+ DT_INST_PROP(inst, pll_charge_pump),), \
576+ ()) \
577+ COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, pll_tuning), \
578+ (.PLLTuning = DT_INST_PROP(inst, pll_tuning),), \
579+ ()) \
507580 }, \
508581 }; \
509582 DEVICE_DT_INST_DEFINE(inst, &mipi_dsi_stm32_init, NULL, \
0 commit comments