1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 
7 /*******************************************************************************************************************//**
8  * @defgroup BSP_SDRAM BSP SDRAM support
9  * @ingroup RENESAS_COMMON
10  * @brief Code that initializes the SDRAMC and SDR SDRAM device memory.
11  *
12  * @{
13  **********************************************************************************************************************/
14 
15 /***********************************************************************************************************************
16  * Includes
17  **********************************************************************************************************************/
18 #include "bsp_api.h"
19 
20 /***********************************************************************************************************************
21  * Macro definitions
22  **********************************************************************************************************************/
23 
24 /* Due to hardware limitations of the SDRAM peripheral,
25  * it is not expected any of these need to be changable by end user.
26  * Only sequential, single access at a time is supported. */
27 #define BSP_PRV_SDRAM_MR_WB_SINGLE_LOC_ACC    (1U) /* MR.M9                : Single Location Access */
28 #define BSP_PRV_SDRAM_MR_OP_MODE              (0U) /* MR.M8:M7             : Standard Operation */
29 #define BSP_PRV_SDRAM_MR_BT_SEQUENTIAL        (0U) /* MR.M3 Burst Type     : Sequential */
30 #define BSP_PRV_SDRAM_MR_BURST_LENGTH         (0U) /* MR.M2:M0 Burst Length: 0(1 burst) */
31 
32 /***********************************************************************************************************************
33  * Typedef definitions
34  **********************************************************************************************************************/
35 
36 /***********************************************************************************************************************
37  * Private function prototypes
38  **********************************************************************************************************************/
39 
40 /***********************************************************************************************************************
41  * Private global variables
42  **********************************************************************************************************************/
43 
44 /***********************************************************************************************************************
45  * Functions
46  **********************************************************************************************************************/
47 
48 #if 0 != BSP_FEATURE_SDRAM_START_ADDRESS
49 
50 /*******************************************************************************************************************//**
51  * @brief   Initializes SDRAM.
52  * @param   init_memory  If true, this function will execute the initialization of the external modules.
53  *                       Otherwise, it will only initialize the SDRAMC and leave the memory in self-refresh mode.
54  *
55  * This function initializes SDRAMC and SDR SDRAM device.
56  *
57  * @note This function must only be called once after reset.
58  **********************************************************************************************************************/
59 void R_BSP_SdramInit (bool init_memory)
60 {
61     /** Setting for SDRAM initialization sequence */
62     while (R_BUS->SDRAM.SDSR)
63     {
64         /* According to h/w manual, need to confirm that all the status bits in SDSR are 0 before SDICR modification. */
65     }
66 
67     /* Must only write to SDIR once after reset. */
68     R_BUS->SDRAM.SDIR = ((BSP_CFG_SDRAM_INIT_ARFI - 3U) << R_BUS_SDRAM_SDIR_ARFI_Pos) |
69                         (BSP_CFG_SDRAM_INIT_ARFC << R_BUS_SDRAM_SDIR_ARFC_Pos) |
70                         ((BSP_CFG_SDRAM_INIT_PRC - 3U) << R_BUS_SDRAM_SDIR_PRC_Pos);
71 
72     R_BUS->SDRAM.SDCCR = (BSP_CFG_SDRAM_BUS_WIDTH << R_BUS_SDRAM_SDCCR_BSIZE_Pos); /* set SDRAM bus width */
73 
74     if (init_memory)
75     {
76         /* Enable the SDCLK output. */
77         R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_CGC);
78         R_SYSTEM->SDCKOCR = 1;
79         R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_CGC);
80 
81         /** If requested, start SDRAM initialization sequence. */
82         R_BUS->SDRAM.SDICR = 1U;
83         while (R_BUS->SDRAM.SDSR_b.INIST)
84         {
85             /* Wait the end of initialization sequence. */
86         }
87     }
88 
89     /** Setting for SDRAM controller */
90     R_BUS->SDRAM.SDAMOD = BSP_CFG_SDRAM_ACCESS_MODE; /* enable continuous access */
91     R_BUS->SDRAM.SDCMOD = BSP_CFG_SDRAM_ENDIAN_MODE; /* set endian mode for SDRAM address space */
92 
93     while (R_BUS->SDRAM.SDSR)
94     {
95         /* According to h/w manual, need to confirm that all the status bits in SDSR are 0 before SDMOD modification. */
96     }
97 
98     if (init_memory)
99     {
100         /** Using LMR command, program the mode register */
101         R_BUS->SDRAM.SDMOD = (BSP_PRV_SDRAM_MR_WB_SINGLE_LOC_ACC << 9) |
102                              (BSP_PRV_SDRAM_MR_OP_MODE << 7) |
103                              (BSP_CFG_SDRAM_TCL << 4) |
104                              (BSP_PRV_SDRAM_MR_BT_SEQUENTIAL << 3) |
105                              (BSP_PRV_SDRAM_MR_BURST_LENGTH << 0);
106 
107         /** wait at least tMRD time */
108         while (R_BUS->SDRAM.SDSR_b.MRSST)
109         {
110             /* Wait until Mode Register setting done. */
111         }
112     }
113 
114     /** Set timing parameters for SDRAM. Must do in single write. */
115     R_BUS->SDRAM.SDTR = ((BSP_CFG_SDRAM_TRAS - 1U) << R_BUS_SDRAM_SDTR_RAS_Pos) |
116                         ((BSP_CFG_SDRAM_TRCD - 1U) << R_BUS_SDRAM_SDTR_RCD_Pos) |
117                         ((BSP_CFG_SDRAM_TRP - 1U) << R_BUS_SDRAM_SDTR_RP_Pos) |
118                         ((BSP_CFG_SDRAM_TWR - 1U) << R_BUS_SDRAM_SDTR_WR_Pos) |
119                         (BSP_CFG_SDRAM_TCL << R_BUS_SDRAM_SDTR_CL_Pos);
120 
121     /** Set row address offset for target SDRAM */
122     R_BUS->SDRAM.SDADR = BSP_CFG_SDRAM_MULTIPLEX_ADDR_SHIFT;
123 
124     /* Set Auto-Refresh timings. */
125     R_BUS->SDRAM.SDRFCR = ((BSP_CFG_SDRAM_TREFW - 1U) << R_BUS_SDRAM_SDRFCR_REFW_Pos) |
126                           ((BSP_CFG_SDRAM_TRFC - 1U) << R_BUS_SDRAM_SDRFCR_RFC_Pos);
127 
128     /** Start Auto-refresh */
129     R_BUS->SDRAM.SDRFEN = 1U;
130 
131     if (init_memory)
132     {
133         /** Enable SDRAM access */
134         R_BUS->SDRAM.SDCCR = R_BUS_SDRAM_SDCCR_EXENB_Msk | (BSP_CFG_SDRAM_BUS_WIDTH << R_BUS_SDRAM_SDCCR_BSIZE_Pos);
135     }
136     else
137     {
138         /* If not initializing memory modules, start in self-refresh mode. */
139         while (R_BUS->SDRAM.SDCCR_b.EXENB || (0U != R_BUS->SDRAM.SDSR))
140         {
141             /* Wait for access to be disabled and no status bits set. */
142         }
143 
144         /* Enable the self-refresh mode. */
145         R_BUS->SDRAM.SDSELF = 1U;
146     }
147 }
148 
149 /*******************************************************************************************************************//**
150  * @brief   Changes SDRAM from Auto-refresh to Self-refresh
151  *
152  * This function allows Software Standby and Deep Software Standby modes to be entered without data loss.
153  *
154  * @note SDRAM cannot be accessed after calling this function. Use @ref R_BSP_SdramSelfRefreshDisable to resume normal
155  *  SDRAM operation.
156  **********************************************************************************************************************/
157 void R_BSP_SdramSelfRefreshEnable (void)
158 {
159     R_BUS->SDRAM.SDCCR = (BSP_CFG_SDRAM_BUS_WIDTH << R_BUS_SDRAM_SDCCR_BSIZE_Pos);
160     while (R_BUS->SDRAM.SDCCR_b.EXENB || (0U != R_BUS->SDRAM.SDSR))
161     {
162         /* Wait for access to be disabled and no status bits set. */
163     }
164 
165     /* Enable the self-refresh mode. */
166     R_BUS->SDRAM.SDSELF = 1U;
167 }
168 
169 /*******************************************************************************************************************//**
170  * @brief   Changes SDRAM from Self-refresh to Auto-refresh
171  *
172  * This function changes back to Auto-refresh and allows normal SDRAM operation to resume.
173  *
174  **********************************************************************************************************************/
175 void R_BSP_SdramSelfRefreshDisable (void)
176 {
177     if (0 == R_SYSTEM->SDCKOCR)
178     {
179         /* Enable the SDCLK output. It may not already be enabled here if recovering from Deep Software Standby. */
180         R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_CGC);
181         R_SYSTEM->SDCKOCR = 1;
182         R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_CGC);
183     }
184 
185     while (0U != R_BUS->SDRAM.SDSR)
186     {
187         /* Wait for all status bits to be cleared. */
188     }
189 
190     /* Disable the self-refresh mode. */
191     R_BUS->SDRAM.SDSELF = 0U;
192 
193     /* Reenable SDRAM bus access. */
194     R_BUS->SDRAM.SDCCR = R_BUS_SDRAM_SDCCR_EXENB_Msk | (BSP_CFG_SDRAM_BUS_WIDTH << R_BUS_SDRAM_SDCCR_BSIZE_Pos);
195 }
196 
197 #endif
198 
199 /** @} (end addtogroup BSP_SDRAM) */
200