Skip to content

Commit 5bad29f

Browse files
CharlesDiasjhedberg
authored andcommitted
drivers: mipi_dsi: Add STM32U5 support to DSI driver
These changes enhance the driver's compatibility with the STM32U5 series, enabling its use in applications requiring MIPI. Signed-off-by: Charles Dias <[email protected]>
1 parent a2d7d64 commit 5bad29f

File tree

1 file changed

+75
-2
lines changed

1 file changed

+75
-2
lines changed

drivers/mipi_dsi/dsi_stm32.c

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
5981
static 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

Comments
 (0)