1 /***********************************************************************************************************************
2  * Copyright [2020-2023] Renesas Electronics Corporation and/or its affiliates.  All Rights Reserved.
3  *
4  * This software and documentation are supplied by Renesas Electronics America Inc. and may only be used with products
5  * of Renesas Electronics Corp. and its affiliates ("Renesas").  No other uses are authorized.  Renesas products are
6  * sold pursuant to Renesas terms and conditions of sale.  Purchasers are solely responsible for the selection and use
7  * of Renesas products and Renesas assumes no liability.  No license, express or implied, to any intellectual property
8  * right is granted by Renesas. This software is protected under all applicable laws, including copyright laws. Renesas
9  * reserves the right to change or discontinue this software and/or this documentation. THE SOFTWARE AND DOCUMENTATION
10  * IS DELIVERED TO YOU "AS IS," AND RENESAS MAKES NO REPRESENTATIONS OR WARRANTIES, AND TO THE FULLEST EXTENT
11  * PERMISSIBLE UNDER APPLICABLE LAW, DISCLAIMS ALL WARRANTIES, WHETHER EXPLICITLY OR IMPLICITLY, INCLUDING WARRANTIES
12  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT, WITH RESPECT TO THE SOFTWARE OR
13  * DOCUMENTATION.  RENESAS SHALL HAVE NO LIABILITY ARISING OUT OF ANY SECURITY VULNERABILITY OR BREACH.  TO THE MAXIMUM
14  * EXTENT PERMITTED BY LAW, IN NO EVENT WILL RENESAS BE LIABLE TO YOU IN CONNECTION WITH THE SOFTWARE OR DOCUMENTATION
15  * (OR ANY PERSON OR ENTITY CLAIMING RIGHTS DERIVED FROM YOU) FOR ANY LOSS, DAMAGES, OR CLAIMS WHATSOEVER, INCLUDING,
16  * WITHOUT LIMITATION, ANY DIRECT, CONSEQUENTIAL, SPECIAL, INDIRECT, PUNITIVE, OR INCIDENTAL DAMAGES; ANY LOST PROFITS,
17  * OTHER ECONOMIC DAMAGE, PROPERTY DAMAGE, OR PERSONAL INJURY; AND EVEN IF RENESAS HAS BEEN ADVISED OF THE POSSIBILITY
18  * OF SUCH LOSS, DAMAGES, CLAIMS OR COSTS.
19  **********************************************************************************************************************/
20 
21 /***********************************************************************************************************************
22  * Includes   <System Includes> , "Project Includes"
23  **********************************************************************************************************************/
24 
25 #include "r_ioport.h"
26 #include "bsp_cfg.h"
27 #include "bsp_pin_cfg.h"
28 
29 #include <rtthread.h>
30 
31 #define DRV_DEBUG
32 #define LOG_TAG         "drv_sdram"
33 #include <drv_log.h>
34 
35 /*
36  * Set ACTIVE-to-PRECHARGE command (tRAS) timing
37  * e.g. tRAS = 42ns -> 6cycles are needed at SDCLK 120MHz
38  *      tRAS = 37ns -> 5cycles are needed at SDCLK 120MHz
39  */
40 #define BSP_PRV_SDRAM_TRAS                     (6U)
41 
42 /*
43  * Set ACTIVE-to-READ or WRITE delay tRCD (tRCD) timing
44  * e.g. tRCD = 18ns -> 3cycles are needed at SDCLK 120MHz
45  *      tRCD = 15ns -> 2cycles are needed at SDCLK 120MHz
46  */
47 #define BSP_PRV_SDRAM_TRCD                     (3U)
48 
49 /*
50  * Set PRECHARGE command period (tRP) timing
51  * e.g. tRP  = 18ns -> 3cycles are needed at SDCLK 120MHz
52  *      tRP  = 15ns -> 2cycles are needed at SDCLK 120MHz
53  */
54 #define BSP_PRV_SDRAM_TRP                      (3U)
55 
56 /*
57  * Set WRITE recovery time (tWR) timing
58  * e.g. tWR  = 1CLK + 6ns -> 2cycles are needed at SDCLK 120MHz
59  *      tWR  = 1CLK + 7ns -> 2cycles are needed at SDCLK 120MHz
60  */
61 #define BSP_PRV_SDRAM_TWR                      (2U)
62 
63 /*
64  * Set CAS (READ) latency (CL) timing
65  * e.g. CL = 18ns -> 3cycles are needed at SDCLK 120MHz
66  * e.g. CL = 15ns -> 2cycles are needed at SDCLK 120MHz
67  */
68 #define BSP_PRV_SDRAM_CL                       (3U)
69 
70 /*
71  * Set AUTO REFRESH period (tRFC) timing
72  * e.g. tRFC = 60nS -> 8cycles are needed at SDCLK 120MHz
73  *      tRFC = 66nS -> 8cycles are needed at SDCLK 120MHz
74  */
75 #define BSP_PRV_SDRAM_TRFC                     (8U)
76 
77 /*
78  * Set Average Refresh period
79  * e.g. tREF = 64ms/8192rows -> 7.8125us/each row.  937cycles are needed at SDCLK 120MHz
80  */
81 #define BSP_PRV_SDRAM_REF_CMD_INTERVAL         (937U)
82 
83 /*
84  * Set Auto-Refresh issue times in initialization sequence needed for SDRAM device
85  * Typical SDR SDRAM device needs twice of Auto-Refresh command issue
86  */
87 #define BSP_PRV_SDRAM_SDIR_REF_TIMES           (2U)
88 
89 /*
90  * Set RAW address offset
91  * Available settings are
92  * 8  : 8-bit
93  * 9  : 9-bit
94  * 10 : 10-bit
95  * 11 : 11-bit
96  */
97 #define BSP_PRV_SDRAM_SDADR_ROW_ADDR_OFFSET    (9U)
98 
99 /*
100  * Select endian mode for SDRAM address space
101  * 0 : Endian of SDRAM address space is the same as the endian of operating mode
102  * 1 : Endian of SDRAM address space is not the endian of operating mode
103  */
104 #define BSP_PRV_SDRAM_ENDIAN_MODE              (0U)
105 
106 /*
107  * Select access mode
108  * Typically Continuous access should be enabled to get better SDRAM bandwidth
109  * 0: Continuous access is disabled
110  * 1: Continuous access is enabled
111  */
112 #define BSP_PRV_SDRAM_CONTINUOUS_ACCESSMODE    (1U)
113 
114 /*
115  * Select bus width
116  * 0: 16-bit
117  * 1: 32-bit
118  * 2: 8-bit
119  */
120 #define BSP_PRV_SDRAM_BUS_WIDTH                (0U)
121 
122 #if ((BSP_PRV_SDRAM_SDADR_ROW_ADDR_OFFSET != 8U) && (BSP_PRV_SDRAM_SDADR_ROW_ADDR_OFFSET != 9U) \
123     && (BSP_PRV_SDRAM_SDADR_ROW_ADDR_OFFSET != 10U) && (BSP_PRV_SDRAM_SDADR_ROW_ADDR_OFFSET > 11U))
124 #error "BSP_PRV_SDRAM_SDADR_ROW_ADDR_OFFSET must be either of 8,9,10 or 11"
125 #endif
126 
127 #if ((BSP_PRV_SDRAM_BUS_WIDTH != 0) && (BSP_PRV_SDRAM_BUS_WIDTH != 1U) && (BSP_PRV_SDRAM_BUS_WIDTH != 2U))
128     #error "BSP_PRV_SDRAM_BUS_WIDTH must be either of 0(16-bit) or 1(32-bit) or 2(8-bit)"
129 #endif
130 
131 #if ((BSP_PRV_SDRAM_ENDIAN_MODE != 0) && (BSP_PRV_SDRAM_ENDIAN_MODE != 1))
132     #error \
133     "BSP_PRV_SDRAM_ENDIAN_MODE must be either of 0(same endian as operating mode) or 2(another endian against operating mode)"
134 #endif
135 
136 #if ((BSP_PRV_SDRAM_CONTINUOUS_ACCESSMODE != 0) && (BSP_PRV_SDRAM_CONTINUOUS_ACCESSMODE != 1))
137     #error \
138     "BSP_PRV_SDRAM_CONTINUOUS_ACCESSMODE must be either of 0(continuous access is disabled) or 1(continuous access is enabled)"
139 #endif
140 
141 #define BSP_PRV_SDRAM_MR_WB_SINGLE_LOC_ACC    (1U) /* MR.M9                : Single Location Access */
142 #define BSP_PRV_SDRAM_MR_OP_MODE              (0U) /* MR.M8:M7             : Standard Operation */
143 #define BSP_PRV_SDRAM_MR_BT_SEQUENCTIAL       (0U) /* MR.M3 Burst Type     : Sequential */
144 #define BSP_PRV_SDRAM_MR_BURST_LENGTH         (0U) /* MR.M2:M0 Burst Length: 0(1 burst) */
145 
146 /***********************************************************************************************************************
147  * Typedef definitions
148  **********************************************************************************************************************/
149 
150 /***********************************************************************************************************************
151  * Exported global variables (to be accessed by other files)
152  **********************************************************************************************************************/
153 
154 /***********************************************************************************************************************
155  * Private global variables and functions
156  **********************************************************************************************************************/
157 
drv_sdram_init(void)158 void drv_sdram_init(void)
159 {
160     /** Setting for SDRAM initialization sequence */
161 #if (BSP_PRV_SDRAM_TRP < 3)
162     R_BUS->SDRAM.SDIR_b.PRC = 3U;
163 #else
164     R_BUS->SDRAM.SDIR_b.PRC = BSP_PRV_SDRAM_TRP - 3U;
165 #endif
166 
167     while (R_BUS->SDRAM.SDSR)
168     {
169         /* According to h/w maual, need to confirm that all the status bits in SDSR are 0 before SDIR modification. */
170     }
171 
172     R_BUS->SDRAM.SDIR_b.ARFC = BSP_PRV_SDRAM_SDIR_REF_TIMES;
173 
174     while (R_BUS->SDRAM.SDSR)
175     {
176         /* According to h/w maual, need to confirm that all the status bits in SDSR are 0 before SDIR modification. */
177     }
178 
179 #if (BSP_PRV_SDRAM_TRFC < 3)
180     R_BUS->SDRAM.SDIR_b.ARFI = 0U;
181 #else
182     R_BUS->SDRAM.SDIR_b.ARFI = BSP_PRV_SDRAM_TRFC - 3U;
183 #endif
184 
185     while (R_BUS->SDRAM.SDSR)
186     {
187         /* According to h/w maual, need to confirm that all the status bits in SDSR are 0 before SDICR modification. */
188     }
189 
190     /** Start SDRAM initialization sequence.
191      * Following operation is automatically done when set SDICR.INIRQ bit.
192      * Perform a PRECHARGE ALL command and wait at least tRP time.
193      * Issue an AUTO REFRESH command and wait at least tRFC time.
194      * Issue an AUTO REFRESH command and wait at least tRFC time.
195      */
196     R_BUS->SDRAM.SDICR_b.INIRQ = 1U;
197     while (R_BUS->SDRAM.SDSR_b.INIST)
198     {
199         /* Wait the end of initialization sequence. */
200     }
201 
202     /** Setting for SDRAM controller */
203     R_BUS->SDRAM.SDCCR_b.BSIZE  = BSP_PRV_SDRAM_BUS_WIDTH;             /* set SDRAM bus width */
204     R_BUS->SDRAM.SDAMOD_b.BE    = BSP_PRV_SDRAM_CONTINUOUS_ACCESSMODE; /* enable continuous access */
205     R_BUS->SDRAM.SDCMOD_b.EMODE = BSP_PRV_SDRAM_ENDIAN_MODE;           /* set endian mode for SDRAM address space */
206 
207     while (R_BUS->SDRAM.SDSR)
208     {
209         /* According to h/w maual, need to confirm that all the status bits in SDSR are 0 before SDMOD modification. */
210     }
211 
212     /** Using LMR command, program the mode register */
213     R_BUS->SDRAM.SDMOD = ((((uint16_t)(BSP_PRV_SDRAM_MR_WB_SINGLE_LOC_ACC << 9) |
214                             (uint16_t)(BSP_PRV_SDRAM_MR_OP_MODE << 7)) |
215                            (uint16_t)(BSP_PRV_SDRAM_CL << 4)) |
216                           (uint16_t)(BSP_PRV_SDRAM_MR_BT_SEQUENCTIAL << 3)) |
217                          (uint16_t)(BSP_PRV_SDRAM_MR_BURST_LENGTH << 0);
218 
219     /** wait at least tMRD time */
220     while (R_BUS->SDRAM.SDSR_b.MRSST)
221     {
222         /* Wait until Mode Register setting done. */
223     }
224 
225     /** Set timing parameters for SDRAM */
226     R_BUS->SDRAM.SDTR_b.RAS = BSP_PRV_SDRAM_TRAS - 1U; /* set ACTIVE-to-PRECHARGE command cycles*/
227     R_BUS->SDRAM.SDTR_b.RCD = BSP_PRV_SDRAM_TRCD - 1U; /* set ACTIVE to READ/WRITE delay cycles */
228     R_BUS->SDRAM.SDTR_b.RP  = BSP_PRV_SDRAM_TRP - 1U;  /* set PRECHARGE command period cycles */
229     R_BUS->SDRAM.SDTR_b.WR  = BSP_PRV_SDRAM_TWR - 1U;  /* set write recovery cycles */
230     R_BUS->SDRAM.SDTR_b.CL  = BSP_PRV_SDRAM_CL;        /* set SDRAM column latency cycles */
231 
232     /** Set row address offset for target SDRAM */
233     R_BUS->SDRAM.SDADR_b.MXC = BSP_PRV_SDRAM_SDADR_ROW_ADDR_OFFSET - 8U;
234 
235     R_BUS->SDRAM.SDRFCR_b.REFW = (uint16_t)(BSP_PRV_SDRAM_TRFC - 1U);  /* set Auto-Refresh issuing cycle */
236     R_BUS->SDRAM.SDRFCR_b.RFC  = BSP_PRV_SDRAM_REF_CMD_INTERVAL - 1U;  /* set Auto-Refresh period */
237 
238     /** Start Auto-refresh */
239     R_BUS->SDRAM.SDRFEN_b.RFEN = 1U;
240 
241     /** Enable SDRAM access */
242     R_BUS->SDRAM.SDCCR_b.EXENB = 1U;
243 }
244 
245 #ifdef BSP_USING_SDRAM
246 #ifdef RT_USING_MEMHEAP_AS_HEAP
247     struct rt_memheap system_heap;
248 #endif
249 
SDRAM_Init(void)250 static int SDRAM_Init(void)
251 {
252     drv_sdram_init();
253 
254     LOG_D("sdram init success, mapped at 0x%X, size is %d bytes, data width is %d", 0x68000000, BSP_USING_SDRAM_SIZE, 16);
255 #ifdef RT_USING_MEMHEAP_AS_HEAP
256     /* If RT_USING_MEMHEAP_AS_HEAP is enabled, SDRAM is initialized to the heap */
257     rt_memheap_init(&system_heap, "sdram", (void *)0x68000000, BSP_USING_SDRAM_SIZE);
258 #endif
259     return RT_EOK;
260 }
261 INIT_BOARD_EXPORT(SDRAM_Init);
262 #endif
263