• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;              /**< Tcks */
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;        /**< Tdpl */
124     uint8_t self_refresh_recover_in_ns; /**< Txsr */
125     uint8_t refresh_recover_in_ns;      /**< Txsr */
126     uint8_t refresh_in_ms;              /**< Tref */
127     uint8_t idle_timeout_in_ns;
128     uint8_t data_width_in_byte;
129     uint8_t auto_refresh_count_in_one_burst;
130     uint8_t delay_cell_value;           /**< Delay cell value */
131 } femc_sdram_config_t;
132 
133 /**
134  * @brief Structure for specifying the configuration of SRAM
135  */
136 typedef struct {
137     uint32_t base_address;              /**< external SRAM base address */
138     uint32_t size_in_byte;              /**< external SRAM size in byte */
139     uint8_t address_mode;               /**< address mode */
140     uint8_t port_size;                  /**< port size */
141     uint8_t adv_hold_state;             /**< adv hold level */
142     uint8_t adv_polarity;               /**< adv polarity */
143     uint8_t oeh_in_ns;                  /**< OE high time */
144     uint8_t oel_in_ns;                  /**< OE low time */
145     uint8_t weh_in_ns;                  /**< WE high time */
146     uint8_t wel_in_ns;                  /**< WE low time */
147     uint8_t ah_in_ns;                   /**< address hold time */
148     uint8_t as_in_ns;                   /**< address setup time */
149     uint8_t ceh_in_ns;                  /**< chip enable hold time */
150     uint8_t ces_in_ns;                  /**< chip enable setup time */
151 } femc_sram_config_t;
152 
153 /**
154  * @brief Structure for specifying the configuration of FEMC
155  */
156 typedef struct {
157     uint8_t dqs;                        /**< DQS setting */
158     uint8_t cmd_timeout;                /**< command timeout */
159     uint8_t bus_timeout;                /**< bus timeout */
160     femc_axi_q_weight_t axi_q_weight[FEMC_AXI_Q_COUNT];
161 } femc_config_t;
162 
163 /**
164  * @brief Structure for FEMC command
165  */
166 typedef struct {
167     uint32_t opcode;
168     uint32_t data;
169 } femc_cmd_t;
170 
171 /*
172  * @brief FEMC specific status
173  */
174 enum {
175     status_femc_cmd_err = MAKE_STATUS(status_group_femc, 1),
176 };
177 
178 #ifdef __cplusplus
179 extern "C" {
180 #endif
181 
182 /**
183  * @brief femc enable
184  *
185  * Enable FEMC
186  *
187  * @param[in] ptr FEMC base address
188  */
femc_enable(FEMC_Type * ptr)189 static inline void femc_enable(FEMC_Type *ptr)
190 {
191     ptr->CTRL &= ~FEMC_CTRL_DIS_MASK;
192 }
193 
194 /**
195  * @brief femc disable
196  *
197  * Disable FEMC
198  *
199  * @param[in] ptr FEMC base address
200  */
femc_disable(FEMC_Type * ptr)201 static inline void femc_disable(FEMC_Type *ptr)
202 {
203     while ((ptr->STAT0 & (uint32_t) FEMC_STAT0_IDLE_MASK) == 0) {
204     }
205     ptr->CTRL |= FEMC_CTRL_DIS_MASK;
206 }
207 
208 /**
209  * @brief femc software reset
210  *
211  * Perform software reset
212  *
213  * @param[in] ptr FEMC base address
214  */
femc_sw_reset(FEMC_Type * ptr)215 static inline void femc_sw_reset(FEMC_Type *ptr)
216 {
217     ptr->CTRL = FEMC_CTRL_RST_MASK;
218     while ((ptr->CTRL & (uint32_t) FEMC_CTRL_RST_MASK) != 0) {
219     }
220 }
221 
222 /**
223  * @brief femc get default config
224  *
225  * Get FEMC default parameters
226  *
227  * @param[in] ptr FEMC base address
228  * @param[out] config femc_config_t address
229  */
230 void femc_default_config(FEMC_Type *ptr, femc_config_t *config);
231 
232 /**
233  * @brief femc init controller
234  *
235  * Initialize FEMC with give femc_config_t
236  *
237  * @param[in] ptr FEMC base address
238  * @param[in] config femc_config_t to initialize femc
239  */
240 void femc_init(FEMC_Type *ptr, femc_config_t *config);
241 
242 /**
243  * @brief femc get typical sdram config
244  *
245  * Fill out the structure of femc_sdram_config_t with typical SDRAM parameters which should work
246  * with most SDRAMs.
247  *
248  * @param[in] ptr FEMC base address
249  * @param[out] config femc_sdram_config_t sdram configuration struction to config femc
250  */
251 void femc_get_typical_sdram_config(FEMC_Type *ptr, femc_sdram_config_t *config);
252 
253 /**
254  * @brief femc config sdram
255  *
256  * Configure FEMC controlling external SDRAM using parameters specified in femc_sdram_config_t
257  *
258  * @param[in] ptr FEMC base address
259  * @param[in] clk_in_hz femc source clock frequency in Hz
260  * @param[in] config femc_sdram_config_t sdram configuration struction to config femc
261  */
262 hpm_stat_t femc_config_sdram(FEMC_Type *ptr, uint32_t clk_in_hz, femc_sdram_config_t *config);
263 
264 /**
265  * @brief femc get typical sram config
266  *
267  * Fill out the structure of femc_sram_config_t with typical SRAM parameters which should work
268  * with most SRAMs.
269  *
270  * @param[in] ptr FEMC base address
271  * @param[out] config femc_sdram_config_t sdram configuration struction to config femc
272  */
273 void femc_get_typical_sram_config(FEMC_Type *ptr, femc_sram_config_t *config);
274 
275 /**
276  * @brief femc config sram
277  *
278  * Configure FEMC controlling external SRAM using parameters specified in femc_sram_config_t
279  *
280  * @param[in] ptr FEMC base address
281  * @param[in] clk_in_hz femc source clock frequency in Hz
282  * @param[in] config femc_sram_config_t sram configuration struction to config femc
283  */
284 hpm_stat_t femc_config_sram(FEMC_Type *ptr, uint32_t clk_in_hz, femc_sram_config_t *config);
285 
286 #ifdef __cplusplus
287 }
288 #endif
289 /**
290  * @}
291  */
292 #endif    /* _HPM_FEMC_DRV_H */
293 
294