1 /*
2 * Copyright (c) 2021-2022 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef _HPM_FEMC_DRV_H
9 #define _HPM_FEMC_DRV_H
10 #include "hpm_femc_regs.h"
11
12 /**
13 * @brief femc driver APIs
14 * @defgroup dram_interface femc driver APIs
15 * @ingroup io_interfaces
16 * @{
17 *
18 */
19
20 #define FEMC_SDRAM_MAX_BURST_LENGTH_IN_BYTE (8UL)
21 /* @brief femc sdram column address bit width */
22 #define FEMC_SDRAM_COLUMN_ADDR_12_BITS (0U)
23 #define FEMC_SDRAM_COLUMN_ADDR_11_BITS (1U)
24 #define FEMC_SDRAM_COLUMN_ADDR_10_BITS (2U)
25 #define FEMC_SDRAM_COLUMN_ADDR_9_BITS (3U)
26 #define FEMC_SDRAM_COLUMN_ADDR_8_BITS (4U)
27 /* @brief cas latency */
28 #define FEMC_SDRAM_CAS_LATENCY_1 (1U)
29 #define FEMC_SDRAM_CAS_LATENCY_2 (2U)
30 #define FEMC_SDRAM_CAS_LATENCY_3 (3U)
31 /* @brief iomux options */
32 #define FEMC_IO_MUX_NOT_USED (0U)
33 #define FEMC_IO_MUX_CSX0 (1U)
34 #define FEMC_IO_MUX_CSX1 (2U)
35 #define FEMC_IO_MUX_CSX2 (3U)
36 #define FEMC_IO_MUX_CSX3 (4U)
37 #define FEMC_IO_MUX_RDY (5U)
38 /* @brief sdram bank number */
39 #define FEMC_SDRAM_BANK_NUM_4 (0U)
40 #define FEMC_SDRAM_BANK_NUM_2 (1U)
41 /* @brief chip select */
42 #define FEMC_SDRAM_CS0 (0U)
43 #define FEMC_SDRAM_CS1 (1U)
44 /* @brief sdram port size */
45 #define FEMC_SDRAM_PORT_SIZE_8_BITS (0U)
46 #define FEMC_SDRAM_PORT_SIZE_16_BITS (1U)
47 #define FEMC_SDRAM_PORT_SIZE_32_BITS (2U)
48
49 #define FEMC_AXI_Q_COUNT (2U)
50 #define FEMC_AXI_Q_A (0U)
51 #define FEMC_AXI_Q_B (1U)
52 /* @brief DQS option */
53 #define FEMC_DQS_INTERNAL (0U)
54 #define FEMC_DQS_FROM_PAD (1U)
55
56 #define FEMC_BR_COUNT (2U)
57
58 #define FEMC_CMD_KEY FEMC_IPCMD_KEY_SET(0xA55A)
59 #define FEMC_CMD_WRITE_FLAG (1UL << 31)
60 #define FEMC_CMD_SDRAM_READ (0x8U)
61 #define FEMC_CMD_SDRAM_WRITE (FEMC_CMD_WRITE_FLAG | 0x9U)
62 #define FEMC_CMD_SDRAM_MODE_SET (FEMC_CMD_WRITE_FLAG | 0xAU)
63 #define FEMC_CMD_SDRAM_ACTIVE (0xBU)
64 #define FEMC_CMD_SDRAM_AUTO_REFRESH (0xCU)
65 #define FEMC_CMD_SDRAM_SELF_REFRESH (0xDU)
66 #define FEMC_CMD_SDRAM_PRECHARGE (0xEU)
67 #define FEMC_CMD_SDRAM_PRECHARGE_ALL (0xFU)
68
69 /* @brief sram address mode */
70 #define FEMC_SRAM_AD_MUX_MODE (0U)
71 #define FEMC_SRAM_AD_NONMUX_MODE (3U)
72
73 /* @brief sram adv hold state */
74 #define FEMC_SRAM_ADV_HOLD_HIGH (0U)
75 #define FEMC_SRAM_ADV_HOLD_LOW (1U)
76
77 /* @brief sram adv polarity */
78 #define FEMC_SRAM_ADV_ACTIVE_LOW (0U)
79 #define FEMC_SRAM_ADV_ACTIVE_HIGH (1U)
80
81 /* @brief sram port size */
82 #define FEMC_SRAM_PORT_SIZE_8_BITS (0U)
83 #define FEMC_SRAM_PORT_SIZE_16_BITS (1U)
84
85 /* @brief IO_CSX selection */
86 #define FEMC_IO_CSX_SDRAM_CS1 (1U)
87 #define FEMC_IO_CSX_SRAM_CE (6U)
88
89 /**
90 * @brief Structure for specifying the configuration of AXI queue weight
91 */
92 typedef struct {
93 bool enable; /**< Enable AXI weight setting flag */
94 uint8_t qos;
95 uint8_t age;
96 uint8_t slave_hit_wo_rw;
97 uint8_t slave_hit; /**< only available for queue A */
98 uint8_t page_hit; /**< only available for queue B */
99 uint8_t bank_rotation; /**< only available for queue B */
100 } femc_axi_q_weight_t;
101
102 /**
103 * @brief Structure for specifying the configuration of SDRAM
104 */
105 typedef struct {
106 uint32_t base_address; /**< external SDRAM base address */
107 uint32_t size_in_byte; /**< external SDRAM size in byte */
108 uint32_t refresh_count; /**< referesh count */
109 uint8_t col_addr_bits; /**< column address bit count */
110 uint8_t cas_latency; /**< CAS latency */
111 uint8_t cs; /**< chip select */
112 uint8_t cs_mux_pin; /**< chip select mux */
113 uint8_t bank_num; /**< bank number */
114 uint8_t prescaler; /**< presecaler */
115 uint8_t port_size; /**< SDRAM port size */
116 uint8_t burst_len_in_byte; /**< 1/2/4/8 bytes */
117 uint8_t cke_off_in_ns;
118 uint8_t act_to_precharge_in_ns; /**< Tras */
119 uint8_t precharge_to_act_in_ns; /**< Trp */
120 uint8_t act_to_rw_in_ns; /**< Trcd */
121 uint8_t act_to_act_in_ns; /**< Trrd */
122 uint8_t refresh_to_refresh_in_ns; /**< Trc */
123 uint8_t write_recover_in_ns; /**< Twr */
124 uint8_t self_refresh_recover_in_ns; /**< Txsr */
125 uint8_t refresh_recover_in_ns; /**< Trc */
126 uint8_t refresh_in_ms; /**< Tref */
127 uint8_t idle_timeout_in_ns;
128 uint8_t cmd_data_width;
129 uint8_t auto_refresh_count_in_one_burst;
130 bool delay_cell_disable; /**< Delay cell disable */
131 uint8_t delay_cell_value; /**< Delay cell value */
132 } femc_sdram_config_t;
133
134 /**
135 * @brief Structure for specifying the configuration of SRAM
136 */
137 typedef struct {
138 uint32_t base_address; /**< external SRAM base address */
139 uint32_t size_in_byte; /**< external SRAM size in byte */
140 uint8_t address_mode; /**< address mode */
141 uint8_t port_size; /**< port size */
142 uint8_t adv_hold_state; /**< adv hold level */
143 uint8_t adv_polarity; /**< adv polarity */
144 uint8_t oeh_in_ns; /**< OE high time */
145 uint8_t oel_in_ns; /**< OE low time */
146 uint8_t weh_in_ns; /**< WE high time */
147 uint8_t wel_in_ns; /**< WE low time */
148 uint8_t ah_in_ns; /**< address hold time */
149 uint8_t as_in_ns; /**< address setup time */
150 uint8_t ceh_in_ns; /**< chip enable hold time */
151 uint8_t ces_in_ns; /**< chip enable setup time */
152 } femc_sram_config_t;
153
154 /**
155 * @brief Structure for specifying the configuration of FEMC
156 */
157 typedef struct {
158 uint8_t dqs; /**< DQS setting */
159 uint8_t cmd_timeout; /**< command timeout */
160 uint8_t bus_timeout; /**< bus timeout */
161 femc_axi_q_weight_t axi_q_weight[FEMC_AXI_Q_COUNT];
162 } femc_config_t;
163
164 /**
165 * @brief Structure for FEMC command
166 */
167 typedef struct {
168 uint32_t opcode;
169 uint32_t data;
170 } femc_cmd_t;
171
172 /*
173 * @brief FEMC specific status
174 */
175 enum {
176 status_femc_cmd_err = MAKE_STATUS(status_group_femc, 1),
177 };
178
179 #ifdef __cplusplus
180 extern "C" {
181 #endif
182
183 /**
184 * @brief femc enable
185 *
186 * Enable FEMC
187 *
188 * @param[in] ptr FEMC base address
189 */
femc_enable(FEMC_Type * ptr)190 static inline void femc_enable(FEMC_Type *ptr)
191 {
192 ptr->CTRL &= ~FEMC_CTRL_DIS_MASK;
193 }
194
195 /**
196 * @brief femc disable
197 *
198 * Disable FEMC
199 *
200 * @param[in] ptr FEMC base address
201 */
femc_disable(FEMC_Type * ptr)202 static inline void femc_disable(FEMC_Type *ptr)
203 {
204 while ((ptr->STAT0 & (uint32_t) FEMC_STAT0_IDLE_MASK) == 0) {
205 }
206 ptr->CTRL |= FEMC_CTRL_DIS_MASK;
207 }
208
209 /**
210 * @brief femc software reset
211 *
212 * Perform software reset
213 *
214 * @param[in] ptr FEMC base address
215 */
femc_sw_reset(FEMC_Type * ptr)216 static inline void femc_sw_reset(FEMC_Type *ptr)
217 {
218 ptr->CTRL = FEMC_CTRL_RST_MASK;
219 while ((ptr->CTRL & (uint32_t) FEMC_CTRL_RST_MASK) != 0) {
220 }
221 }
222
223 /**
224 * @brief femc get default config
225 *
226 * Get FEMC default parameters
227 *
228 * @param[in] ptr FEMC base address
229 * @param[out] config femc_config_t address
230 */
231 void femc_default_config(FEMC_Type *ptr, femc_config_t *config);
232
233 /**
234 * @brief femc init controller
235 *
236 * Initialize FEMC with give femc_config_t
237 *
238 * @param[in] ptr FEMC base address
239 * @param[in] config femc_config_t to initialize femc
240 */
241 void femc_init(FEMC_Type *ptr, femc_config_t *config);
242
243 /**
244 * @brief femc get typical sdram config
245 *
246 * Fill out the structure of femc_sdram_config_t with typical SDRAM parameters which should work
247 * with most SDRAMs.
248 *
249 * @param[in] ptr FEMC base address
250 * @param[out] config femc_sdram_config_t sdram configuration struction to config femc
251 */
252 void femc_get_typical_sdram_config(FEMC_Type *ptr, femc_sdram_config_t *config);
253
254 /**
255 * @brief femc config sdram
256 *
257 * Configure FEMC controlling external SDRAM using parameters specified in femc_sdram_config_t
258 *
259 * @param[in] ptr FEMC base address
260 * @param[in] clk_in_hz femc source clock frequency in Hz
261 * @param[in] config femc_sdram_config_t sdram configuration struction to config femc
262 */
263 hpm_stat_t femc_config_sdram(FEMC_Type *ptr, uint32_t clk_in_hz, femc_sdram_config_t *config);
264
265 /**
266 * @brief femc get typical sram config
267 *
268 * Fill out the structure of femc_sram_config_t with typical SRAM parameters which should work
269 * with most SRAMs.
270 *
271 * @param[in] ptr FEMC base address
272 * @param[out] config femc_sdram_config_t sdram configuration struction to config femc
273 */
274 void femc_get_typical_sram_config(FEMC_Type *ptr, femc_sram_config_t *config);
275
276 /**
277 * @brief femc config sram
278 *
279 * Configure FEMC controlling external SRAM using parameters specified in femc_sram_config_t
280 *
281 * @param[in] ptr FEMC base address
282 * @param[in] clk_in_hz femc source clock frequency in Hz
283 * @param[in] config femc_sram_config_t sram configuration struction to config femc
284 */
285 hpm_stat_t femc_config_sram(FEMC_Type *ptr, uint32_t clk_in_hz, femc_sram_config_t *config);
286
287 #ifdef __cplusplus
288 }
289 #endif
290 /**
291 * @}
292 */
293 #endif /* _HPM_FEMC_DRV_H */
294
295