1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_sdram.h"
10 
11 /*******************************************************************************
12  * Definitions
13  ******************************************************************************/
14 
15 /* Defines the sdram nop delay counts in initialize sequence. */
16 #define SDRAM_DELAY_COUNTS (125U)
17 
18 /*******************************************************************************
19  * Prototypes
20  ******************************************************************************/
21 
22 static status_t SDRAM_InitSequence(SDRAM_Type *base,
23                                    uint32_t address,
24                                    sdramc_block_selection_t whichBlock,
25                                    sdram_burst_len_t burstLen,
26                                    sdram_burst_type_t burstType,
27                                    sdram_cas_latency_t casLatency,
28                                    sdram_operation_mode_t opMode,
29                                    sdram_write_burst_mode_t writeBurstMode);
30 
31 /*******************************************************************************
32  * Code
33  ******************************************************************************/
34 
SDRAM_Init(SDRAM_Type * base,uint32_t address,uint32_t busClock_Hz)35 status_t SDRAM_Init(SDRAM_Type *base, uint32_t address, uint32_t busClock_Hz)
36 {
37     assert(address);
38 
39     sdramc_config_t config;
40     sdramc_refresh_config_t refConfig;
41     sdramc_blockctl_config_t ctlConfig;
42 
43     /* SDRAM refresh timing configuration. */
44     refConfig.refreshTime = kSDRAMC_RefreshThreeClocks;
45     /* Refresh time 4096 rows/ 64ms. */
46     refConfig.sdramRefreshRow = 15625;
47     refConfig.busClock_Hz     = busClock_Hz;
48 
49     /* SDRAM controller configuration. */
50     /* Port size: 16 bit, Command bit location: bit 20. */
51     ctlConfig.portSize = kSDRAMC_PortSize16Bit;
52     ctlConfig.location = kSDRAMC_Commandbit20;
53     ctlConfig.block    = kSDRAMC_Block0;
54     /* SDRAM with trcd-15ns(min), trp-15ns(min), tras-37ns (min). */
55     ctlConfig.latency     = kSDRAMC_LatencyOne;
56     ctlConfig.address     = address;
57     ctlConfig.addressMask = 0xfc0000;
58 
59     config.refreshConfig  = &refConfig;
60     config.blockConfig    = &ctlConfig;
61     config.numBlockConfig = 1;
62 
63     /* SDRAM controller initialization. */
64     SDRAMC_Init(base, &config);
65 
66     /* SDRAM initialization sequence. */
67     return SDRAM_InitSequence(base, address, kSDRAMC_Block0, kSDRAM_MrsBurstLenOne, kSDRAM_MrsSequential,
68                               kSDRAM_MrsLatencyTwo, kSDRAM_MrsStandOperation, kSDRAM_MrsWriteBurst);
69 }
70 
71 /*!
72  * @brief The SDRAM Initializes sequence.
73  *
74  */
SDRAM_InitSequence(SDRAM_Type * base,uint32_t address,sdramc_block_selection_t whichBlock,sdram_burst_len_t burstLen,sdram_burst_type_t burstType,sdram_cas_latency_t casLatency,sdram_operation_mode_t opMode,sdram_write_burst_mode_t writeBurstMode)75 static status_t SDRAM_InitSequence(SDRAM_Type *base,
76                                    uint32_t address,
77                                    sdramc_block_selection_t whichBlock,
78                                    sdram_burst_len_t burstLen,
79                                    sdram_burst_type_t burstType,
80                                    sdram_cas_latency_t casLatency,
81                                    sdram_operation_mode_t opMode,
82                                    sdram_write_burst_mode_t writeBurstMode)
83 {
84     uint32_t count   = SDRAM_DELAY_COUNTS;
85     uint8_t *mrsAddr = NULL;
86     uint32_t addr    = 0U;
87 
88     /* Issue a PALL command. */
89     SDRAMC_SendCommand(base, whichBlock, kSDRAMC_PrechargeCommand);
90 
91     /* Accessing a SDRAM location. */
92     *(uint8_t *)(address) = SDRAM_COMMAND_ACCESSVALUE;
93 
94     /* Enable the refresh. */
95     SDRAMC_SendCommand(base, whichBlock, kSDRAMC_AutoRefreshEnableCommand);
96 
97     /* Wait for at least 8 refresh cycles. */
98     while (count != 0U)
99     {
100         __NOP();
101         count--;
102     }
103 
104     /* Issue MSR command. */
105     SDRAMC_SendCommand(base, whichBlock, kSDRAMC_ImrsCommand);
106 
107     /* Put the right value on SDRAM address bus for SDRAM mode register,
108      *  The address of SDRAM Pins is as below:
109      *  A2 ~ A0:   burst length   0
110      *     000->1
111      *     001->2
112      *     010->4
113      *     011->8
114      *     res
115      * A3:   burst type
116      *        0 -> seq
117      *        1 -> Interleave
118      *
119      * A6 ~ A4:  CAS latency  (should be set to equal to the tcasl in "sdram_latency_t")
120      *       000-> res
121      *       001-> 1
122      *       010-> 2
123      *       011-> 3
124      *       res
125      * A8 ~ A7:  Operationg Mode
126      *       00->Stardard Operation
127      *       res
128      * A9:    Write Burst Mode
129      *       0-> Programmed Burst Length
130      *      1-> Single Location Access
131      */
132     /* A2-A0. */
133     if (((uint8_t)burstLen & 0x1U) != 0x00U)
134     {
135         addr |= 1UL << SDRAM_A0;
136     }
137     if (((uint8_t)burstLen & 0x2U) != 0x00U)
138     {
139         addr |= 1UL << SDRAM_A1;
140     }
141     if (((uint8_t)burstLen & 0x4U) != 0x00U)
142     {
143         addr |= 1UL << SDRAM_A2;
144     }
145 
146     /* Sdram address A3. */
147     if (((uint8_t)burstType & 0x1U) != 0x00U)
148     {
149         addr |= 1UL << SDRAM_A3;
150     }
151 
152     /* Sdram address A6-A4. */
153     if (((uint8_t)casLatency & 0x1U) != 0x00U)
154     {
155         addr |= 1UL << SDRAM_A4;
156     }
157     if (((uint8_t)casLatency & 0x2U) != 0x00U)
158     {
159         addr |= 1UL << SDRAM_A5;
160     }
161     if (((uint8_t)casLatency & 0x4U) != 0x00U)
162     {
163         addr |= 1UL << SDRAM_A6;
164     }
165 
166     /* Sdram address A8-A7. */
167     if (((uint8_t)opMode & 0x1U) != 0x00U)
168     {
169         addr |= 1UL << SDRAM_A7;
170     }
171     if (((uint8_t)opMode & 0x2U) != 0x00U)
172     {
173         addr |= 1UL << SDRAM_A8;
174     }
175 
176     /* Sdram address A9. */
177     if (((uint8_t)writeBurstMode & 0x1U) != 0x00U)
178     {
179         addr |= 1UL << SDRAM_A9;
180     }
181     /* Set MRS register. */
182     mrsAddr = (uint8_t *)(address + addr);
183     /* Access sdram location. */
184     *mrsAddr = SDRAM_COMMAND_ACCESSVALUE;
185 
186     return kStatus_Success;
187 }
188