1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef _FSL_EMC_H_
9 #define _FSL_EMC_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup emc
15  * @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 
22 /*! @name Driver version */
23 /*@{*/
24 /*! @brief EMC driver version. */
25 #define FSL_EMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
26 /*@}*/
27 
28 /*! @brief Define the chip numbers for dynamic and static memory devices. */
29 #define EMC_STATIC_MEMDEV_NUM   (4U)
30 #define EMC_DYNAMIC_MEMDEV_NUM  (4U)
31 #define EMC_ADDRMAP_SHIFT       EMC_DYNAMIC_DYNAMICCONFIG_AM0_SHIFT
32 #define EMC_ADDRMAP_MASK        (EMC_DYNAMIC_DYNAMICCONFIG_AM0_MASK | EMC_DYNAMIC_DYNAMICCONFIG_AM1_MASK)
33 #define EMC_ADDRMAP(x)          (((uint32_t)(((uint32_t)(x)) << EMC_ADDRMAP_SHIFT)) & EMC_ADDRMAP_MASK)
34 #define EMC_HZ_ONEMHZ           (1000000U)
35 #define EMC_MILLISECS_ONESEC    (1000U)
36 #define EMC_SDRAM_MODE_CL_SHIFT (4U)
37 #define EMC_SDRAM_MODE_CL_MASK  (0x70U)
38 /*! @brief EDMA_SDRAM NOP command wait us */
39 #ifndef EMC_SDRAM_NOP_DELAY_US
40 #define EMC_SDRAM_NOP_DELAY_US (100U)
41 #endif
42 /*! @brief EDMA_SDRAM precharge command wait us */
43 #ifndef EMC_SDRAM_PRECHARGE_DELAY_US
44 #define EMC_SDRAM_PRECHARGE_DELAY_US (100U)
45 #endif
46 /*! @brief EDMA_SDRAM auto refresh wait us */
47 #ifndef EMC_SDRAM_AUTO_REFRESH_DELAY_US
48 #define EMC_SDRAM_AUTO_REFRESH_DELAY_US (50U)
49 #endif
50 /*!
51  * @brief Define EMC memory width for static memory device.
52  */
53 typedef enum _emc_static_memwidth
54 {
55     kEMC_8BitWidth = 0x0U, /*!< 8 bit memory width. */
56     kEMC_16BitWidth,       /*!< 16 bit memory width. */
57     kEMC_32BitWidth        /*!< 32 bit memory width. */
58 } emc_static_memwidth_t;
59 
60 /*!
61  * @brief Define EMC static configuration.
62  */
63 typedef enum _emc_static_special_config
64 {
65     kEMC_AsynchronosPageEnable = 0x0008U, /*!< Enable the asynchronous page mode. page length four. */
66     kEMC_ActiveHighChipSelect  = 0x0040U, /*!< Chip select active high. */
67     kEMC_ByteLaneStateAllLow   = 0x0080U, /*!< Reads/writes the respective valuie bits in BLS3:0 are low. */
68     kEMC_ExtWaitEnable         = 0x0100U, /*!< Extended wait enable. */
69     kEMC_BufferEnable          = 0x80000U /*!< Buffer enable. */
70 } emc_static_special_config_t;
71 
72 /*! @brief EMC dynamic memory device. */
73 typedef enum _emc_dynamic_device
74 {
75     kEMC_Sdram = 0x0U, /*!< Dynamic memory device: SDRAM. */
76     kEMC_Lpsdram,      /*!< Dynamic memory device: Low-power SDRAM. */
77 } emc_dynamic_device_t;
78 
79 /*! @brief EMC dynamic read strategy. */
80 typedef enum _emc_dynamic_read
81 {
82     kEMC_NoDelay = 0x0U,      /*!< No delay. */
83     kEMC_Cmddelay,            /*!< Command delayed strategy, using EMCCLKDELAY. */
84     kEMC_CmdDelayPulseOneclk, /*!< Command delayed strategy pluse one clock cycle using EMCCLKDELAY. */
85     kEMC_CmddelayPulsetwoclk, /*!< Command delayed strategy pulse two clock cycle using EMCCLKDELAY. */
86 } emc_dynamic_read_t;
87 
88 /*! @brief EMC endian mode. */
89 typedef enum _emc_endian_mode
90 {
91     kEMC_LittleEndian = 0x0U, /*!< Little endian mode. */
92     kEMC_BigEndian,           /*!< Big endian mode. */
93 } emc_endian_mode_t;
94 
95 /*! @brief EMC Feedback clock input source select. */
96 typedef enum _emc_fbclk_src
97 {
98     kEMC_IntloopbackEmcclk = 0U, /*!< Use the internal loop back from EMC_CLK output. */
99     kEMC_EMCFbclkInput           /*!< Use the external EMC_FBCLK input. */
100 } emc_fbclk_src_t;
101 
102 /*! @brief EMC dynamic timing/delay configure structure. */
103 typedef struct _emc_dynamic_timing_config
104 {
105     emc_dynamic_read_t readConfig;  /* Dynamic read strategy. */
106     uint32_t refreshPeriod_Nanosec; /*!< The refresh period in unit of nanosecond. */
107     uint32_t tRp_Ns;                /*!< Precharge command period in unit of nanosecond. */
108     uint32_t tRas_Ns;               /*!< Active to precharge command period in unit of nanosecond. */
109     uint32_t tSrex_Ns;              /*!< Self-refresh exit time in unit of nanosecond. */
110     uint32_t tApr_Ns;               /*!< Last data out to active command time in unit of nanosecond. */
111     uint32_t tDal_Ns;               /*!< Data-in to active command in unit of nanosecond. */
112     uint32_t tWr_Ns;                /*!< Write recovery time in unit of nanosecond. */
113     uint32_t tRc_Ns;                /*!< Active to active command period in unit of nanosecond. */
114     uint32_t tRfc_Ns;  /*!< Auto-refresh period and auto-refresh to active command period in unit of nanosecond. */
115     uint32_t tXsr_Ns;  /*!< Exit self-refresh to active command time in unit of nanosecond. */
116     uint32_t tRrd_Ns;  /*!< Active bank A to active bank B latency in unit of nanosecond. */
117     uint8_t tMrd_Nclk; /*!< Load mode register to active command time in unit of EMCCLK cycles.*/
118 } emc_dynamic_timing_config_t;
119 
120 /*!
121  * @brief EMC dynamic memory controller independent chip configuration structure.
122  * Please take refer to the address mapping table in the RM in EMC chapter when you
123  * set the "devAddrMap". Choose the right Bit 14 Bit12 ~ Bit 7 group in the table
124  * according to the bus width/banks/row/colum length for you device.
125  * Set devAddrMap with the value make up with the seven bits (bit14 bit12 ~ bit 7)
126  * and inset the bit 13 with 0.
127  * for example, if the bit 14 and bit12 ~ bit7 is 1000001 is choosen according to the
128  * 32bit high-performance bus width with 2 banks, 11 row lwngth, 8 column length.
129  * Set devAddrMap with 0x81.
130  */
131 typedef struct _emc_dynamic_chip_config
132 {
133     uint8_t chipIndex; /*!< Chip Index, range from 0 ~ EMC_DYNAMIC_MEMDEV_NUM - 1. */
134     emc_dynamic_device_t
135         dynamicDevice;        /*!< All chips shall use the same device setting. mixed use are not supported. */
136     uint8_t rAS_Nclk;         /*!< Active to read/write delay tRCD. */
137     uint16_t sdramModeReg;    /*!< Sdram mode register setting. */
138     uint16_t sdramExtModeReg; /*!< Used for low-power sdram device. The extended mode register. */
139     uint8_t devAddrMap; /*!< dynamic device address mapping, choose the address mapping for your specific device. */
140 } emc_dynamic_chip_config_t;
141 
142 /*!
143  * @brief EMC static memory controller independent chip configuration structure.
144  */
145 typedef struct _emc_static_chip_config
146 {
147     uint8_t chipIndex;
148     emc_static_memwidth_t memWidth; /*!< Memory width. */
149     uint32_t specailConfig;         /*!< Static configuration,a logical OR of "emc_static_special_config_t". */
150     uint32_t tWaitWriteEn_Ns;       /*!< The delay form chip select to write enable in unit of nanosecond. */
151     uint32_t tWaitOutEn_Ns;         /*!< The delay from chip selcet to output enable in unit of nanosecond. */
152     uint32_t
153         tWaitReadNoPage_Ns;    /*!< In No-page mode, the delay from chip select to read access in unit of nanosecond. */
154     uint32_t tWaitReadPage_Ns; /*!< In page mode, the read after the first read wait states in unit of nanosecond. */
155     uint32_t tWaitWrite_Ns;    /*!< The delay from chip select to write access in unit of nanosecond. */
156     uint32_t tWaitTurn_Ns;     /*!< The Bus turn-around time in unit of nanosecond. */
157 } emc_static_chip_config_t;
158 
159 /*!
160  * @brief EMC module basic configuration structure.
161  *
162  * Defines the static memory controller configure structure and
163  * uses the EMC_Init() function to make necessary initializations.
164  *
165  */
166 typedef struct _emc_basic_config
167 {
168     emc_endian_mode_t endian; /*!< Endian mode . */
169     emc_fbclk_src_t fbClkSrc; /*!< The feedback clock source. */
170     uint8_t emcClkDiv;        /*!< EMC_CLK = AHB_CLK / (emc_clkDiv + 1). */
171 } emc_basic_config_t;
172 
173 /*******************************************************************************
174  * API
175  ******************************************************************************/
176 
177 #if defined(__cplusplus)
178 extern "C" {
179 #endif
180 
181 /*!
182  * @name EMC Initialize and de-initialize opeartion
183  * @{
184  */
185 /*!
186  * @brief Initializes the basic for EMC.
187  * This function ungates the EMC clock, initializes the emc system configure
188  * and enable the EMC module. This function must be called in the first step to initialize
189  * the external memory.
190  *
191  * @param base EMC peripheral base address.
192  * @param config The EMC basic configuration.
193  */
194 void EMC_Init(EMC_Type *base, emc_basic_config_t *config);
195 
196 /*!
197  * @brief Initializes the dynamic memory controller.
198  * This function initializes the dynamic memory controller in external memory controller.
199  * This function must be called after EMC_Init and before accessing the external dynamic memory.
200  *
201  * @param base EMC peripheral base address.
202  * @param timing The timing and latency for dynamica memory controller setting. It shall
203  *        be used for all dynamica memory chips, threfore the worst timing value for all
204  *        used chips must be given.
205  * @param config The EMC dynamic memory controller chip independent configuration pointer.
206  *       This configuration pointer is actually pointer to a configration array. the array number
207  *       depends on the "totalChips".
208  * @param totalChips The total dynamic memory chip numbers been used or the length of the
209  *        "emc_dynamic_chip_config_t" type memory.
210  */
211 void EMC_DynamicMemInit(EMC_Type *base,
212                         emc_dynamic_timing_config_t *timing,
213                         emc_dynamic_chip_config_t *config,
214                         uint32_t totalChips);
215 
216 /*!
217  * @brief Initializes the static memory controller.
218  * This function initializes the static memory controller in external memory controller.
219  * This function must be called after EMC_Init and before accessing the external static memory.
220  *
221  * @param base EMC peripheral base address.
222  * @param extWait_Ns The extended wait timeout or the read/write transfer time.
223  *        This is common for all static memory chips and set with NULL if not required.
224  * @param config The EMC static memory controller chip independent configuration pointer.
225  *       This configuration pointer is actually pointer to a configration array. the array number
226  *       depends on the "totalChips".
227  * @param totalChips The total static memory chip numbers been used or the length of the
228  *        "emc_static_chip_config_t" type memory.
229  */
230 void EMC_StaticMemInit(EMC_Type *base, uint32_t *extWait_Ns, emc_static_chip_config_t *config, uint32_t totalChips);
231 
232 /*!
233  * @brief Deinitializes the EMC module and gates the clock.
234  * This function gates the EMC controller clock. As a result, the EMC
235  * module doesn't work after calling this function.
236  *
237  * @param base EMC peripheral base address.
238  */
239 void EMC_Deinit(EMC_Type *base);
240 
241 /* @} */
242 
243 /*!
244  * @name EMC Basic Operation
245  * @{
246  */
247 
248 /*!
249  * @brief Enables/disables the EMC module.
250  *
251  * @param base EMC peripheral base address.
252  * @param enable True enable EMC module, false disable.
253  */
EMC_Enable(EMC_Type * base,bool enable)254 static inline void EMC_Enable(EMC_Type *base, bool enable)
255 {
256     if (enable)
257     {
258         base->CONTROL |= EMC_CONTROL_E_MASK;
259     }
260     else
261     {
262         base->CONTROL &= ~EMC_CONTROL_E_MASK;
263     }
264 }
265 
266 /*!
267  * @brief Enables/disables the EMC Dynaimc memory controller.
268  *
269  * @param base EMC peripheral base address.
270  * @param enable True enable EMC dynamic memory controller, false disable.
271  */
EMC_EnableDynamicMemControl(EMC_Type * base,bool enable)272 static inline void EMC_EnableDynamicMemControl(EMC_Type *base, bool enable)
273 {
274     if (enable)
275     {
276         base->DYNAMICCONTROL |= (EMC_DYNAMICCONTROL_CE_MASK | EMC_DYNAMICCONTROL_CS_MASK);
277     }
278     else
279     {
280         base->DYNAMICCONTROL &= ~(EMC_DYNAMICCONTROL_CE_MASK | EMC_DYNAMICCONTROL_CS_MASK);
281     }
282 }
283 
284 /*!
285  * @brief Enables/disables the EMC address mirror.
286  * Enable the address mirror the EMC_CS1is mirrored to both EMC_CS0
287  * and EMC_DYCS0 memory areas. Disable the address mirror enables
288  * EMC_cS0 and EMC_DYCS0 memory to be accessed.
289  *
290  * @param base EMC peripheral base address.
291  * @param enable True enable the address mirror, false disable the address mirror.
292  */
EMC_MirrorChipAddr(EMC_Type * base,bool enable)293 static inline void EMC_MirrorChipAddr(EMC_Type *base, bool enable)
294 {
295     if (enable)
296     {
297         base->CONTROL |= EMC_CONTROL_M_MASK;
298     }
299     else
300     {
301         base->CONTROL &= ~EMC_CONTROL_M_MASK;
302     }
303 }
304 
305 /*!
306  * @brief Enter the self-refresh mode for dynamic memory controller.
307  * This function provided self-refresh mode enter or exit for application.
308  *
309  * @param base EMC peripheral base address.
310  * @param enable   True enter the self-refresh mode, false to exit self-refresh
311  *                 and enter the normal mode.
312  */
EMC_EnterSelfRefreshCommand(EMC_Type * base,bool enable)313 static inline void EMC_EnterSelfRefreshCommand(EMC_Type *base, bool enable)
314 {
315     if (enable)
316     {
317         base->DYNAMICCONTROL |= EMC_DYNAMICCONTROL_SR_MASK;
318     }
319     else
320     {
321         base->DYNAMICCONTROL &= ~EMC_DYNAMICCONTROL_SR_MASK;
322     }
323 }
324 
325 /*!
326  * @brief Get the operating mode of the EMC.
327  * This function can be used to get the operating mode of the EMC.
328  *
329  * @param base EMC peripheral base address.
330  * @return The EMC in self-refresh mode if true, else in normal mode.
331  */
EMC_IsInSelfrefreshMode(EMC_Type * base)332 static inline bool EMC_IsInSelfrefreshMode(EMC_Type *base)
333 {
334     return (0U != (base->STATUS & EMC_STATUS_SA_MASK));
335 }
336 
337 /*!
338  * @brief Enter/exit the low-power mode.
339  *
340  * @param base EMC peripheral base address.
341  * @param enable True Enter the low-power mode, false exit low-power mode
342  *        and return to normal mode.
343  */
EMC_EnterLowPowerMode(EMC_Type * base,bool enable)344 static inline void EMC_EnterLowPowerMode(EMC_Type *base, bool enable)
345 {
346     if (enable)
347     {
348         base->CONTROL |= EMC_CONTROL_L_MASK;
349     }
350     else
351     {
352         base->CONTROL &= ~EMC_CONTROL_L_MASK;
353     }
354 }
355 
356 /* @} */
357 
358 #if defined(__cplusplus)
359 }
360 #endif
361 
362 /*! @}*/
363 
364 #endif /* _FSL_EMC_H_*/
365