sam3x-ek sdram initialization: add needed includes
[bertos.git] / boards / sam3x-ek / hw / hw_sdram.h
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2011 Develer S.r.l. (http://www.develer.com/)
30  *
31  * -->
32  *
33  * \brief MT48LC16M16A2 SDRAM initialization for Atmel SAM3X-EK board.
34  *
35  * \author Stefano Fedrigo <aleph@develer.com>
36  *
37  * SDRAMC register settings and comments are from Atmel Softpack, see licence below:
38  *
39  * ----------------------------------------------------------------------------
40  *         ATMEL Microcontroller Software Support
41  * ----------------------------------------------------------------------------
42  * Copyright (c) 2010, Atmel Corporation
43  *
44  * All rights reserved.
45  *
46  * Redistribution and use in source and binary forms, with or without
47  * modification, are permitted provided that the following conditions are met:
48  *
49  * - Redistributions of source code must retain the above copyright notice,
50  * this list of conditions and the disclaimer below.
51  *
52  * Atmel's name may not be used to endorse or promote products derived from
53  * this software without specific prior written permission.
54  *
55  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
56  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
57  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
58  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
59  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
60  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
61  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
62  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
63  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
64  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65  * ----------------------------------------------------------------------------
66  */
67
68 #ifndef HW_SAM3X_SDRAM_H
69 #define HW_SAM3X_SDRAM_H
70
71 #include "cfg/macros.h"
72 #include <cpu/types.h>
73 #include <io/sam3.h>
74 #include <drv/timer.h>
75
76 /*
77  * SDRAM properties
78  */
79 #define SDRAM_BASE      0x70000000
80 #define SDRAM_SIZE      (32*1024*1024)
81 #define SDRAM_BUSWIDTH  16
82 #define SDRAM_CLK       CPU_FREQ
83
84 /*
85  * IO pins
86  */
87 // port C, peripheral A
88 #define PIO_SDRAM_DATA     (0xFFFF << 2)  // Data bus, 2-17
89 #define PIO_SDRAM_SDA0_A7  (0xFF << 23)   // Address bus, 23-30
90 #define PIO_SDRAM_NBS0     BV(21)         // Data mask enable 0
91 // port D, peripheral A
92 #define PIO_SDRAM_SDCKE    BV(13)         // Clock enable
93 #define PIO_SDRAM_SDCS     BV(12)         // Chip select
94 #define PIO_SDRAM_RAS      BV(15)         // Row
95 #define PIO_SDRAM_CAS      BV(16)         // Column
96 #define PIO_SDRAM_BA0      BV(6)          // Bank select 0
97 #define PIO_SDRAM_BA1      BV(7)          // Bank select 1
98 #define PIO_SDRAM_SDWE     BV(14)         // Write enable
99 #define PIO_SDRAM_NBS1     BV(10)         // Data mask enable 1
100 #define PIO_SDRAM_SDA8     BV(22)
101 #define PIO_SDRAM_SDA9     BV(23)
102 #define PIO_SDRAM_SDA10    BV(11)
103 #define PIO_SDRAM_SDA11    BV(25)
104 #define PIO_SDRAM_SDA12    BV(4)
105 // port D, PIO output
106 #define PIO_SDRAM_EN       BV(18)         // Enable
107
108 #define SDRAM_PORTC_PERIPH  (PIO_SDRAM_DATA | PIO_SDRAM_SDA0_A7 | PIO_SDRAM_NBS0)
109 #define SDRAM_PORTD_PERIPH  (PIO_SDRAM_SDCKE | PIO_SDRAM_SDCS  | PIO_SDRAM_RAS   | \
110                              PIO_SDRAM_CAS   | PIO_SDRAM_BA0   | PIO_SDRAM_BA1   | \
111                              PIO_SDRAM_SDWE  | PIO_SDRAM_NBS1  | PIO_SDRAM_SDA8  | \
112                              PIO_SDRAM_SDA9  | PIO_SDRAM_SDA10 | PIO_SDRAM_SDA11 | \
113                              PIO_SDRAM_SDA12)
114 #define SDRAM_PORTD_OUTPUT  PIO_SDRAM_EN
115
116
117 INLINE void sdram_init(void)
118 {
119         HWREG(PIOC_BASE + PIO_PDR_OFF) = SDRAM_PORTC_PERIPH;
120         HWREG(PIOC_BASE + PIO_PUER_OFF) = SDRAM_PORTC_PERIPH;
121         PIO_PERIPH_SEL(PIOC_BASE, SDRAM_PORTC_PERIPH, PIO_PERIPH_A);
122
123         HWREG(PIOD_BASE + PIO_PDR_OFF) = SDRAM_PORTD_PERIPH;
124         HWREG(PIOD_BASE + PIO_PUER_OFF) = SDRAM_PORTD_PERIPH;
125         PIO_PERIPH_SEL(PIOD_BASE, SDRAM_PORTD_PERIPH, PIO_PERIPH_A);
126
127         HWREG(PIOD_BASE + PIO_PER_OFF) = SDRAM_PORTD_OUTPUT;
128         HWREG(PIOD_BASE + PIO_OER_OFF) = SDRAM_PORTD_OUTPUT;
129         HWREG(PIOD_BASE + PIO_SODR_OFF) = SDRAM_PORTD_OUTPUT;
130
131         pmc_periphEnable(SMC_SDRAMC_ID);
132
133         // SDRAM device configuration
134         SDRAMC_CR =
135                 SDRAMC_CR_NC_COL9 | SDRAMC_CR_NR_ROW13 | SDRAMC_CR_NB_BANK4 |
136                 SDRAMC_CR_CAS_LATENCY2 | SDRAMC_CR_DBW |
137                 SDRAMC_CR_TWR(2) | SDRAMC_CR_TRC_TRFC(9) | SDRAMC_CR_TRP(3) |
138                 SDRAMC_CR_TRCD(3) | SDRAMC_CR_TRAS(6) | SDRAMC_CR_TXSR(10);
139
140         SDRAMC_LPR = 0;
141         SDRAMC_MDR = SDRAMC_MDR_MD_SDRAM;
142
143         /*
144          * A minimum pause of 200 us needed before any signal toggle
145          * (6 core cycles per iteration).
146          */
147         timer_delay(1);
148
149         /*
150          * A NOP command is issued to the SDR-SDRAM. Program NOP command into
151          * Mode Register, the application must set Mode to 1 in the Mode Register.
152          * Perform a write access to any SDR-SDRAM address to acknowledge this command.
153          * Now the clock which drives SDR-SDRAM device is enabled.
154          */
155         SDRAMC_MR = SDRAMC_MR_MODE_NOP;
156         *(uint32_t *)SDRAM_BASE = 0;
157
158         /*
159          * An all banks precharge command is issued to the SDR-SDRAM. Program all
160          * banks precharge command into Mode Register, the application must set Mode to
161          * 2 in the Mode Register . Perform a write access to any SDRSDRAM address to
162          * acknowledge this command.
163          */
164         SDRAMC_MR = SDRAMC_MR_MODE_ALLBANKS_PRECHARGE;
165         *(uint32_t *)SDRAM_BASE = 0;
166
167         /*
168          * Eight auto-refresh (CBR) cycles are provided. Program the auto refresh
169          * command (CBR) into Mode Register, the application must set Mode to 4 in
170          * the Mode Register. Once in the idle state, two AUTO REFRESH cycles must
171          * be performed.
172          */
173         SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH;
174         *(uint32_t *)SDRAM_BASE = 0;
175
176         SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH;
177         *(uint32_t *)SDRAM_BASE = 0;
178
179         /*
180          * A Mode Register set (MRS) cycle is issued to program the parameters of
181          * the SDRAM devices, in particular CAS latency and burst length.
182          */
183         SDRAMC_MR = SDRAMC_MR_MODE_LOAD_MODEREG;
184         *(uint32_t *)(SDRAM_BASE + 9) = 0xc001babe;
185
186         /*
187          * For low-power SDR-SDRAM initialization, an Extended Mode Register set
188          * (EMRS) cycle is issued to program the SDR-SDRAM parameters (TCSR, PASR, DS).
189          * The write address must be chosen so that BA[1] is set to 1 and BA[0] is set
190          * to 0: BK1 is at bit 24, 1+9+13+1.
191          */
192         SDRAMC_MR = SDRAMC_MR_MODE_EXT_LOAD_MODEREG;
193         *(uint32_t *)(SDRAM_BASE + (1 << 24)) = 0;
194
195         /*
196          * The application must go into Normal Mode, setting Mode to 0 in the Mode
197          * Register and perform a write access at any location in the SDRAM to
198          * acknowledge this command.
199          */
200         SDRAMC_MR = SDRAMC_MR_MODE_NORMAL;
201         *(uint32_t *)SDRAM_BASE = 0;
202
203         /*
204          * Write the refresh rate into the count field in the SDRAMC Refresh
205          * Timer register. Set Refresh timer 15.625 us
206          */
207         SDRAMC_TR = SDRAMC_TR_COUNT(SDRAM_CLK / 1000 * 15625 / 1000000) ;
208 }
209
210 #endif /* HW_SAM3X_SDRAM_H */