|
| 1 | +/* |
| 2 | + * Copyright (c) 2025 EXALT Technologies. |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: Apache-2.0 |
| 5 | + */ |
| 6 | + |
| 7 | +#ifndef ZEPHYR_DRIVERS_MSPI_STM32_H_ |
| 8 | +#define ZEPHYR_DRIVERS_MSPI_STM32_H_ |
| 9 | +/* Macro to check if any xspi device has a domain clock or more */ |
| 10 | +#define MSPI_STM32_DOMAIN_CLOCK_INST_SUPPORT(inst) DT_CLOCKS_HAS_IDX(DT_INST_PARENT(inst), 1) || |
| 11 | +#define MSPI_STM32_INST_DEV_DOMAIN_CLOCK_SUPPORT \ |
| 12 | + (DT_INST_FOREACH_STATUS_OKAY(MSPI_STM32_DOMAIN_CLOCK_INST_SUPPORT) 0) |
| 13 | + |
| 14 | +/* This symbol takes the value 1 if device instance has a domain clock in its dts */ |
| 15 | +#if MSPI_STM32_INST_DEV_DOMAIN_CLOCK_SUPPORT |
| 16 | +#define MSPI_STM32_DOMAIN_CLOCK_SUPPORT 1 |
| 17 | +#else |
| 18 | +#define MSPI_STM32_DOMAIN_CLOCK_SUPPORT 0 |
| 19 | +#endif |
| 20 | + |
| 21 | +#define MSPI_STM32_FIFO_THRESHOLD 4U |
| 22 | +#define MSPI_MAX_FREQ 250000000 |
| 23 | +#define MSPI_MAX_DEVICE 2 |
| 24 | + |
| 25 | +#if defined(CONFIG_SOC_SERIES_STM32U5X) |
| 26 | +/* Valid range is [1, 256] */ |
| 27 | +#define MSPI_STM32_CLOCK_PRESCALER_MIN 1U |
| 28 | +#define MSPI_STM32_CLOCK_PRESCALER_MAX 256U |
| 29 | +#define MSPI_STM32_CLOCK_COMPUTE(bus_freq, prescaler) ((bus_freq) / (prescaler)) |
| 30 | +#else |
| 31 | +/* Valid range is [0, 255] */ |
| 32 | +#define MSPI_STM32_CLOCK_PRESCALER_MIN 0U |
| 33 | +#define MSPI_STM32_CLOCK_PRESCALER_MAX 255U |
| 34 | +#define MSPI_STM32_CLOCK_COMPUTE(bus_freq, prescaler) ((bus_freq) / ((prescaler) + 1U)) |
| 35 | +#endif |
| 36 | + |
| 37 | +#define MSPI_STM32_WRITE_REG_MAX_TIME 40U |
| 38 | +#define MSPI_STM32_MAX_FREQ 48000000 |
| 39 | + |
| 40 | +#define MSPI_STM32_CMD_WRSR 0x01 /* Write status register */ |
| 41 | +#define MSPI_STM32_CMD_RDSR 0x05 /* Read status register */ |
| 42 | +#define MSPI_STM32_CMD_READ 0x03 /* Read data */ |
| 43 | +#define MSPI_STM32_CMD_READ_FAST 0x0B /* Read data */ |
| 44 | +#define MSPI_STM32_CMD_PP 0x02 /* Page program */ |
| 45 | +#define MSPI_STM32_CMD_READ_4B 0x13 /* Read data 4 Byte Address */ |
| 46 | +#define MSPI_STM32_CMD_READ_FAST_4B 0x0C /* Fast Read 4 Byte Address */ |
| 47 | +#define MSPI_STM32_CMD_PP_4B 0x12 /* Page Program 4 Byte Address */ |
| 48 | +#define MSPI_STM32_CMD_WREN 0x06 /* Write enable */ |
| 49 | +#define MSPI_STM32_CMD_RDPD 0xAB /* Release from Deep Power Down */ |
| 50 | +#define MSPI_STM32_CMD_RD_CFGREG2 0x71 /* Read config register 2 */ |
| 51 | +#define MSPI_STM32_CMD_WR_CFGREG2 0x72 /* Write config register 2 */ |
| 52 | +#define MSPI_STM32_CMD_SE 0x20 /* Sector erase */ |
| 53 | +#define MSPI_STM32_CMD_SE_4B 0x21 /* Sector erase 4 byte address*/ |
| 54 | + |
| 55 | +#define MSPI_STM32_OCMD_RDSR 0x05FA /* Octal Read status register */ |
| 56 | +#define MSPI_STM32_OCMD_RD 0xEC13 /* Octal IO read command */ |
| 57 | +#define MSPI_STM32_OCMD_PAGE_PRG 0x12ED /* Octal Page Prog */ |
| 58 | +#define MSPI_STM32_OCMD_WREN 0x06F9 /* Octal Write enable */ |
| 59 | +#define MSPI_STM32_OCMD_DTR_RD 0xEE11 /* Octal IO DTR read command */ |
| 60 | +#define MSPI_STM32_OCMD_WR_CFGREG2 0x728D /* Octal Write configuration Register2 */ |
| 61 | +#define MSPI_STM32_OCMD_RD_CFGREG2 0x718E /* Octal Read configuration Register2 */ |
| 62 | +#define MSPI_STM32_OCMD_SE 0x21DE /* Octal Sector erase */ |
| 63 | + |
| 64 | +/* Flash Auto-polling values */ |
| 65 | +#define MSPI_STM32_WREN_MATCH 0x02 |
| 66 | +#define MSPI_STM32_WREN_MASK 0x02 |
| 67 | +#define MSPI_STM32_WEL_MATCH 0x00 |
| 68 | +#define MSPI_STM32_WEL_MASK 0x02 |
| 69 | +#define MSPI_STM32_MEM_RDY_MATCH 0x00 |
| 70 | +#define MSPI_STM32_MEM_RDY_MASK 0x01 |
| 71 | +#define MSPI_STM32_AUTO_POLLING_INTERVAL 0x10 |
| 72 | + |
| 73 | +/* Flash Dummy Cycles values */ |
| 74 | +#define MSPI_STM32_DUMMY_REG_OCTAL 4U |
| 75 | +#define MSPI_STM32_DUMMY_REG_OCTAL_DTR 5U |
| 76 | + |
| 77 | +/* Memory registers address */ |
| 78 | +#define MSPI_STM32_REG2_ADDR1 0x0000000 |
| 79 | +#define MSPI_STM32_CR2_STR_OPI_EN 0x01 |
| 80 | +#define MSPI_STM32_CR2_DTR_OPI_EN 0x02 |
| 81 | +#define MSPI_STM32_REG2_ADDR3 0x00000300 |
| 82 | +#define MSPI_STM32_CR2_DUMMY_CYCLES_66MHZ 0x07 |
| 83 | + |
| 84 | +typedef void (*irq_config_func_t)(void); |
| 85 | + |
| 86 | +#ifndef DMA_LOW_PRIORITY_LOW_WEIGHT |
| 87 | +#define DMA_LOW_PRIORITY_LOW_WEIGHT DMA_PRIORITY_LOW |
| 88 | +#endif |
| 89 | + |
| 90 | +#ifndef DMA_LOW_PRIORITY_MID_WEIGHT |
| 91 | +#define DMA_LOW_PRIORITY_MID_WEIGHT DMA_PRIORITY_MEDIUM |
| 92 | +#endif |
| 93 | + |
| 94 | +#ifndef DMA_LOW_PRIORITY_HIGH_WEIGHT |
| 95 | +#define DMA_LOW_PRIORITY_HIGH_WEIGHT DMA_PRIORITY_HIGH |
| 96 | +#endif |
| 97 | + |
| 98 | +#ifndef DMA_HIGH_PRIORITY |
| 99 | +#define DMA_HIGH_PRIORITY DMA_PRIORITY_VERY_HIGH |
| 100 | +#endif |
| 101 | + |
| 102 | +enum mspi_access_mode { |
| 103 | + MSPI_ACCESS_ASYNC = 1, |
| 104 | + MSPI_ACCESS_SYNC = 2, |
| 105 | + MSPI_ACCESS_DMA = 3 |
| 106 | +}; |
| 107 | + |
| 108 | +struct mspi_context { |
| 109 | + struct mspi_xfer xfer; |
| 110 | + int packets_left; |
| 111 | + struct k_sem lock; |
| 112 | +}; |
| 113 | + |
| 114 | +struct mspi_stm32_conf { |
| 115 | + bool use_dma; |
| 116 | + size_t pclk_len; |
| 117 | + irq_config_func_t irq_config; |
| 118 | + struct mspi_cfg mspicfg; |
| 119 | + const struct stm32_pclken *pclken; |
| 120 | + const struct pinctrl_dev_config *pcfg; |
| 121 | +}; |
| 122 | + |
| 123 | +/* Lookup table to set dma priority from the DTS */ |
| 124 | +static const uint32_t table_priority[] = { |
| 125 | + DMA_LOW_PRIORITY_LOW_WEIGHT, |
| 126 | + DMA_LOW_PRIORITY_MID_WEIGHT, |
| 127 | + DMA_LOW_PRIORITY_HIGH_WEIGHT, |
| 128 | + DMA_HIGH_PRIORITY, |
| 129 | +}; |
| 130 | + |
| 131 | +/* Lookup table to set dma channel direction from the DTS */ |
| 132 | +static const uint32_t table_direction[] = { |
| 133 | + DMA_MEMORY_TO_MEMORY, |
| 134 | + DMA_MEMORY_TO_PERIPH, |
| 135 | + DMA_PERIPH_TO_MEMORY, |
| 136 | +}; |
| 137 | + |
| 138 | +#if CONFIG_DMA_STM32U5 |
| 139 | +static const uint32_t table_src_size[] = { |
| 140 | + LL_DMA_SRC_DATAWIDTH_BYTE, |
| 141 | + LL_DMA_SRC_DATAWIDTH_HALFWORD, |
| 142 | + LL_DMA_SRC_DATAWIDTH_WORD, |
| 143 | +}; |
| 144 | + |
| 145 | +static const uint32_t table_dest_size[] = { |
| 146 | + LL_DMA_DEST_DATAWIDTH_BYTE, |
| 147 | + LL_DMA_DEST_DATAWIDTH_HALFWORD, |
| 148 | + LL_DMA_DEST_DATAWIDTH_WORD, |
| 149 | +}; |
| 150 | +#else |
| 151 | +static const uint32_t table_m_size[] = { |
| 152 | + LL_DMA_MDATAALIGN_BYTE, |
| 153 | + LL_DMA_MDATAALIGN_HALFWORD, |
| 154 | + LL_DMA_MDATAALIGN_WORD, |
| 155 | +}; |
| 156 | + |
| 157 | +static const uint32_t table_p_size[] = { |
| 158 | + LL_DMA_PDATAALIGN_BYTE, |
| 159 | + LL_DMA_PDATAALIGN_HALFWORD, |
| 160 | + LL_DMA_PDATAALIGN_WORD, |
| 161 | +}; |
| 162 | +#endif /* CONFIG_DMA_STM32U5 */ |
| 163 | + |
| 164 | +struct stream { |
| 165 | + DMA_TypeDef *reg; |
| 166 | + const struct device *dev; |
| 167 | + uint32_t channel; |
| 168 | + struct dma_config cfg; |
| 169 | + uint8_t priority; |
| 170 | + bool src_addr_increment; |
| 171 | + bool dst_addr_increment; |
| 172 | +}; |
| 173 | + |
| 174 | +union hmspi_handle { |
| 175 | +#ifdef HAL_XSPI_MODULE_ENABLED |
| 176 | + XSPI_HandleTypeDef xspi; |
| 177 | +#endif |
| 178 | +#ifdef HAL_OSPI_MODULE_ENABLED |
| 179 | + OSPI_HandleTypeDef ospi; |
| 180 | +#endif |
| 181 | +#ifdef HAL_QSPI_MODULE_ENABLED |
| 182 | + QSPI_HandleTypeDef qspi; |
| 183 | +#endif |
| 184 | +}; |
| 185 | + |
| 186 | +/* mspi data includes the controller specific config variable */ |
| 187 | +struct mspi_stm32_data { |
| 188 | + union hmspi_handle hmspi; |
| 189 | + uint32_t memmap_base_addr; |
| 190 | + struct mspi_context ctx; |
| 191 | + struct mspi_dev_id *dev_id; |
| 192 | + struct k_mutex lock; |
| 193 | + struct k_sem sync; |
| 194 | + struct mspi_dev_cfg dev_cfg; |
| 195 | + struct mspi_xip_cfg xip_cfg; |
| 196 | + struct stream dma_tx; |
| 197 | + struct stream dma_rx; |
| 198 | + struct stream dma; |
| 199 | +}; |
| 200 | + |
| 201 | +#endif /* ZEPHYR_DRIVERS_MSPI_STM32_H_ */ |
0 commit comments