Commit be55b2c2 authored by Francois Ramu's avatar Francois Ramu Committed by Anas Nashif
Browse files

drivers: flash: stm32 xspi flash driver with clock domain



Configure the xspi clocks domain by the clock domain
as defined by the DTS
Up to 3 possible clock confg : xspix, xspi_ker, xspi_mgr

Signed-off-by: default avatarFrancois Ramu <francois.ramu@st.com>
parent 1662c0ac
Loading
Loading
Loading
Loading
+45 −39
Original line number Diff line number Diff line
@@ -1735,41 +1735,53 @@ static int flash_stm32_xspi_init(const struct device *dev)
		return -ENODEV;
	}

	if (dev_cfg->pclk_len > 3) {
		/* Max 3 domain clock are expected */
		LOG_ERR("Could not select %d XSPI domain clock", dev_cfg->pclk_len);
		return -EIO;
	}

	/* Clock configuration */
	if (clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
			     (clock_control_subsys_t) &dev_cfg->pclken) != 0) {
			     (clock_control_subsys_t) &dev_cfg->pclken[0]) != 0) {
		LOG_ERR("Could not enable XSPI clock");
		return -EIO;
	}
	if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
					(clock_control_subsys_t) &dev_cfg->pclken[0],
					&ahb_clock_freq) < 0) {
		LOG_ERR("Failed call clock_control_get_rate(pclken)");
		return -EIO;
	}
	/* Alternate clock config for peripheral if any */
#if DT_CLOCKS_HAS_NAME(STM32_XSPI_NODE, xspi_ker)
	if (IS_ENABLED(STM32_XSPI_DOMAIN_CLOCK_SUPPORT) && (dev_cfg->pclk_len > 1)) {
		if (clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
				(clock_control_subsys_t) &dev_cfg->pclken_ker,
				(clock_control_subsys_t) &dev_cfg->pclken[1],
				NULL) != 0) {
			LOG_ERR("Could not select XSPI domain clock");
			return -EIO;
		}
		/*
		 * Get the clock rate from this one (update ahb_clock_freq)
		 * TODO: retrieve index in the clocks property where clocks has "xspi-ker"
		 * Assuming index is 1
		 */
		if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
					(clock_control_subsys_t) &dev_cfg->pclken_ker,
					&ahb_clock_freq) < 0) {
		LOG_ERR("Failed call clock_control_get_rate(pclken_ker)");
		return -EIO;
	}
#else
	if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
					(clock_control_subsys_t) &dev_cfg->pclken,
				(clock_control_subsys_t) &dev_cfg->pclken[1],
				&ahb_clock_freq) < 0) {
			LOG_ERR("Failed call clock_control_get_rate(pclken)");
			return -EIO;
		}
#endif
#if DT_CLOCKS_HAS_NAME(STM32_XSPI_NODE, xspi_mgr)
	}
	/* Clock domain corresponding to the IO-Mgr (XSPIM) */
	if (IS_ENABLED(STM32_XSPI_DOMAIN_CLOCK_SUPPORT) && (dev_cfg->pclk_len > 2)) {
		if (clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
			     (clock_control_subsys_t) &dev_cfg->pclken_mgr) != 0) {
				(clock_control_subsys_t) &dev_cfg->pclken[2]) != 0) {
			LOG_ERR("Could not enable XSPI Manager clock");
			return -EIO;
		}
#endif
		/* Do NOT Get the clock rate from this one */
	}

	for (; prescaler <= STM32_XSPI_CLOCK_PRESCALER_MAX; prescaler++) {
		uint32_t clk = STM32_XSPI_CLOCK_COMPUTE(ahb_clock_freq, prescaler);
@@ -2008,19 +2020,13 @@ static int flash_stm32_xspi_init(const struct device *dev)

static void flash_stm32_xspi_irq_config_func(const struct device *dev);

static const struct stm32_pclken pclken[] = STM32_DT_CLOCKS(STM32_XSPI_NODE);

PINCTRL_DT_DEFINE(STM32_XSPI_NODE);

static const struct flash_stm32_xspi_config flash_stm32_xspi_cfg = {
	.pclken = {.bus = DT_CLOCKS_CELL_BY_NAME(STM32_XSPI_NODE, xspix, bus),
		   .enr = DT_CLOCKS_CELL_BY_NAME(STM32_XSPI_NODE, xspix, bits)},
#if DT_CLOCKS_HAS_NAME(STM32_XSPI_NODE, xspi_ker)
	.pclken_ker = {.bus = DT_CLOCKS_CELL_BY_NAME(STM32_XSPI_NODE, xspi_ker, bus),
		       .enr = DT_CLOCKS_CELL_BY_NAME(STM32_XSPI_NODE, xspi_ker, bits)},
#endif
#if DT_CLOCKS_HAS_NAME(STM32_XSPI_NODE, xspi_mgr)
	.pclken_mgr = {.bus = DT_CLOCKS_CELL_BY_NAME(STM32_XSPI_NODE, xspi_mgr, bus),
		       .enr = DT_CLOCKS_CELL_BY_NAME(STM32_XSPI_NODE, xspi_mgr, bits)},
#endif
	.pclken = pclken,
	.pclk_len = DT_NUM_CLOCKS(STM32_XSPI_NODE),
	.irq_config = flash_stm32_xspi_irq_config_func,
	.flash_size = DT_INST_REG_ADDR_BY_IDX(0, 1),
	.max_frequency = DT_INST_PROP(0, ospi_max_frequency),
@@ -2061,14 +2067,14 @@ static struct flash_stm32_xspi_data flash_stm32_xspi_dev_data = {
#endif /* jedec_id */
};

DEVICE_DT_INST_DEFINE(0, &flash_stm32_xspi_init, NULL,
		      &flash_stm32_xspi_dev_data, &flash_stm32_xspi_cfg,
		      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		      &flash_stm32_xspi_driver_api);

static void flash_stm32_xspi_irq_config_func(const struct device *dev)
{
	IRQ_CONNECT(DT_IRQN(STM32_XSPI_NODE), DT_IRQ(STM32_XSPI_NODE, priority),
		    flash_stm32_xspi_isr, DEVICE_DT_INST_GET(0), 0);
	irq_enable(DT_IRQN(STM32_XSPI_NODE));
}

DEVICE_DT_INST_DEFINE(0, &flash_stm32_xspi_init, NULL,
		      &flash_stm32_xspi_dev_data, &flash_stm32_xspi_cfg,
		      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		      &flash_stm32_xspi_driver_api);
+15 −3
Original line number Diff line number Diff line
@@ -7,6 +7,19 @@
#ifndef ZEPHYR_DRIVERS_FLASH_XSPI_STM32_H_
#define ZEPHYR_DRIVERS_FLASH_XSPI_STM32_H_

/* Macro to check if any xspi device has a domain clock or more */
#define STM32_XSPI_DOMAIN_CLOCK_INST_SUPPORT(inst) \
	DT_CLOCKS_HAS_IDX(DT_INST_PARENT(inst), 1) ||
#define STM32_XSPI_INST_DEV_DOMAIN_CLOCK_SUPPORT				\
	(DT_INST_FOREACH_STATUS_OKAY(STM32_XSPI_DOMAIN_CLOCK_INST_SUPPORT) 0)

/* This symbol takes the value 1 if device instance has a domain clock in its dts */
#if STM32_XSPI_INST_DEV_DOMAIN_CLOCK_SUPPORT
#define STM32_XSPI_DOMAIN_CLOCK_SUPPORT 1
#else
#define STM32_XSPI_DOMAIN_CLOCK_SUPPORT 0
#endif

#define STM32_XSPI_FIFO_THRESHOLD       4U

/* Valid range is [0, 255] */
@@ -27,9 +40,8 @@
typedef void (*irq_config_func_t)(const struct device *dev);

struct flash_stm32_xspi_config {
	const struct stm32_pclken pclken; /* clock subsystem */
	const struct stm32_pclken pclken_ker; /* clock subsystem */
	const struct stm32_pclken pclken_mgr; /* clock subsystem */
	const struct stm32_pclken *pclken;
	size_t pclk_len;
	irq_config_func_t irq_config;
	size_t flash_size;
	uint32_t max_frequency;