]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Drivers/PL34xDmc/PL341Dmc.c
Sync up ArmPkg with patch from mailing list. Changed name of BdsLib.h to BdsUnixLib...
[mirror_edk2.git] / ArmPkg / Drivers / PL34xDmc / PL341Dmc.c
1 /** @file
2 *
3 * Copyright (c) 2011, ARM Limited. All rights reserved.
4 *
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
9 *
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 *
13 **/
14
15 #include <Library/IoLib.h>
16 #include <Library/DebugLib.h>
17 #include <Drivers/PL341Dmc.h>
18
19 //
20 // DMC Configuration Register Map
21 //
22 #define DMC_STATUS_REG 0x00
23 #define DMC_COMMAND_REG 0x04
24 #define DMC_DIRECT_CMD_REG 0x08
25 #define DMC_MEMORY_CONFIG_REG 0x0C
26 #define DMC_REFRESH_PRD_REG 0x10
27 #define DMC_CAS_LATENCY_REG 0x14
28 #define DMC_WRITE_LATENCY_REG 0x18
29 #define DMC_T_MRD_REG 0x1C
30 #define DMC_T_RAS_REG 0x20
31 #define DMC_T_RC_REG 0x24
32 #define DMC_T_RCD_REG 0x28
33 #define DMC_T_RFC_REG 0x2C
34 #define DMC_T_RP_REG 0x30
35 #define DMC_T_RRD_REG 0x34
36 #define DMC_T_WR_REG 0x38
37 #define DMC_T_WTR_REG 0x3C
38 #define DMC_T_XP_REG 0x40
39 #define DMC_T_XSR_REG 0x44
40 #define DMC_T_ESR_REG 0x48
41 #define DMC_MEMORY_CFG2_REG 0x4C
42 #define DMC_MEMORY_CFG3_REG 0x50
43 #define DMC_T_FAW_REG 0x54
44
45 // Returns the state of the memory controller:
46 #define DMC_STATUS_CONFIG 0x0
47 #define DMC_STATUS_READY 0x1
48 #define DMC_STATUS_PAUSED 0x2
49 #define DMC_STATUS_LOWPOWER 0x3
50
51 // Changes the state of the memory controller:
52 #define DMC_COMMAND_GO 0x0
53 #define DMC_COMMAND_SLEEP 0x1
54 #define DMC_COMMAND_WAKEUP 0x2
55 #define DMC_COMMAND_PAUSE 0x3
56 #define DMC_COMMAND_CONFIGURE 0x4
57 #define DMC_COMMAND_ACTIVEPAUSE 0x7
58
59 // Determines the command required
60 #define DMC_DIRECT_CMD_MEMCMD_PRECHARGEALL 0x0
61 #define DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH (0x1 << 18)
62 #define DMC_DIRECT_CMD_MEMCMD_MODEREG (0x2 << 18)
63 #define DMC_DIRECT_CMD_MEMCMD_EXTMODEREG (0x2 << 18)
64 #define DMC_DIRECT_CMD_MEMCMD_NOP (0x3 << 18)
65 #define DMC_DIRECT_CMD_MEMCMD_DPD (0x1 << 22)
66 #define DMC_DIRECT_CMD_BANKADDR(n) ((n & 0x3) << 16)
67 #define DMC_DIRECT_CMD_CHIP_ADDR(n) ((n & 0x3) << 20)
68
69
70 //
71 // AXI ID configuration register map
72 //
73 #define DMC_ID_0_CFG_REG 0x100
74 #define DMC_ID_1_CFG_REG 0x104
75 #define DMC_ID_2_CFG_REG 0x108
76 #define DMC_ID_3_CFG_REG 0x10C
77 #define DMC_ID_4_CFG_REG 0x110
78 #define DMC_ID_5_CFG_REG 0x114
79 #define DMC_ID_6_CFG_REG 0x118
80 #define DMC_ID_7_CFG_REG 0x11C
81 #define DMC_ID_8_CFG_REG 0x120
82 #define DMC_ID_9_CFG_REG 0x124
83 #define DMC_ID_10_CFG_REG 0x128
84 #define DMC_ID_11_CFG_REG 0x12C
85 #define DMC_ID_12_CFG_REG 0x130
86 #define DMC_ID_13_CFG_REG 0x134
87 #define DMC_ID_14_CFG_REG 0x138
88 #define DMC_ID_15_CFG_REG 0x13C
89
90 // Set the QoS
91 #define DMC_ID_CFG_QOS_DISABLE 0
92 #define DMC_ID_CFG_QOS_ENABLE 1
93 #define DMC_ID_CFG_QOS_MIN 2
94
95
96 //
97 // Chip configuration register map
98 //
99 #define DMC_CHIP_0_CFG_REG 0x200
100 #define DMC_CHIP_1_CFG_REG 0x204
101 #define DMC_CHIP_2_CFG_REG 0x208
102 #define DMC_CHIP_3_CFG_REG 0x20C
103
104 //
105 // User Defined Pins
106 //
107 #define DMC_USER_STATUS_REG 0x300
108 #define DMC_USER_0_CFG_REG 0x304
109 #define DMC_USER_1_CFG_REG 0x308
110 #define DMC_FEATURE_CRTL_REG 0x30C
111 #define DMC_USER_2_CFG_REG 0x310
112
113
114 //
115 // PHY Register Settings
116 //
117 #define TC_UIOLHNC_MASK 0x000003C0
118 #define TC_UIOLHNC_SHIFT 0x6
119 #define TC_UIOLHPC_MASK 0x0000003F
120 #define TC_UIOLHPC_SHIFT 0x2
121 #define TC_UIOHOCT_MASK 0x2
122 #define TC_UIOHOCT_SHIFT 0x1
123 #define TC_UIOHSTOP_SHIFT 0x0
124 #define TC_UIOLHXC_VALUE 0x4
125
126 //
127 // Extended Mode Register settings
128 //
129 #define DDR_EMR_OCD_MASK 0x0000380
130 #define DDR_EMR_OCD_SHIFT 0x7
131 #define DDR_EMR_RTT_MASK 0x00000044 // DDR2 Device RTT (ODT) settings
132 #define DDR_EMR_RTT_SHIFT 0x2
133 #define DDR_EMR_ODS_MASK 0x00000002 // DDR2 Output Drive Strength
134 #define DDR_EMR_ODS_SHIFT 0x0001
135 // Termination Values:
136 #define DDR_EMR_RTT_50 0x00000044 // DDR2 50 Ohm termination
137 #define DDR_EMR_RTT_75R 0x00000004 // DDR2 75 Ohm termination
138 #define DDR_EMR_RTT_150 0x00000040 // DDR2 150 Ohm termination
139 // Output Drive Strength Values:
140 #define DDR_EMR_ODS_FULL 0x0 // DDR2 Full Drive Strength
141 #define DDR_EMR_ODS_HALF 0x1 // DDR2 Half Drive Strength
142 // OCD values
143 #define DDR_EMR_OCD_DEFAULT 0x7
144 #define DDR_EMR_OCD_NS 0x0
145
146 #define DDR_EMR_ODS_VAL DDR_EMR_ODS_FULL
147
148
149
150 #define DmcWriteReg(reg,val) MmioWrite32(DmcBase + reg, val)
151 #define DmcReadReg(reg) MmioRead32(DmcBase + reg)
152
153 // Initialize PL341 Dynamic Memory Controller
154 VOID PL341DmcInit(struct pl341_dmc_config *config) {
155 UINTN DmcBase = config->base;
156 UINT32 i, chip, val32;
157
158 // Set config mode
159 DmcWriteReg(DMC_COMMAND_REG, DMC_COMMAND_CONFIGURE);
160
161 //
162 // Setup the QoS AXI ID bits
163 //
164
165 if (config->has_qos) {
166 // CLCD AXIID = 000
167 DmcWriteReg(DMC_ID_0_CFG_REG, DMC_ID_CFG_QOS_ENABLE | DMC_ID_CFG_QOS_MIN);
168
169 // Default disable QoS
170 DmcWriteReg(DMC_ID_1_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
171 DmcWriteReg(DMC_ID_2_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
172 DmcWriteReg(DMC_ID_3_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
173 DmcWriteReg(DMC_ID_4_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
174 DmcWriteReg(DMC_ID_5_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
175 DmcWriteReg(DMC_ID_6_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
176 DmcWriteReg(DMC_ID_7_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
177 DmcWriteReg(DMC_ID_8_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
178 DmcWriteReg(DMC_ID_9_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
179 DmcWriteReg(DMC_ID_10_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
180 DmcWriteReg(DMC_ID_11_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
181 DmcWriteReg(DMC_ID_12_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
182 DmcWriteReg(DMC_ID_13_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
183 DmcWriteReg(DMC_ID_14_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
184 DmcWriteReg(DMC_ID_15_CFG_REG, DMC_ID_CFG_QOS_DISABLE);
185 }
186
187 //
188 // Initialise memory controlller
189 //
190 DmcWriteReg(DMC_REFRESH_PRD_REG, config->refresh_prd);
191 DmcWriteReg(DMC_CAS_LATENCY_REG, config->cas_latency);
192 DmcWriteReg(DMC_WRITE_LATENCY_REG, config->write_latency);
193 DmcWriteReg(DMC_T_MRD_REG, config->t_mrd);
194 DmcWriteReg(DMC_T_RAS_REG, config->t_ras);
195 DmcWriteReg(DMC_T_RC_REG, config->t_rc);
196 DmcWriteReg(DMC_T_RCD_REG, config->t_rcd);
197 DmcWriteReg(DMC_T_RFC_REG, config->t_rfc);
198 DmcWriteReg(DMC_T_RP_REG, config->t_rp);
199 DmcWriteReg(DMC_T_RRD_REG, config->t_rrd);
200 DmcWriteReg(DMC_T_WR_REG, config->t_wr);
201 DmcWriteReg(DMC_T_WTR_REG, config->t_wtr);
202 DmcWriteReg(DMC_T_XP_REG, config->t_xp);
203 DmcWriteReg(DMC_T_XSR_REG, config->t_xsr);
204 DmcWriteReg(DMC_T_ESR_REG, config->t_esr);
205 DmcWriteReg(DMC_T_FAW_REG, config->t_faw);
206
207 // =======================================================================
208 // Initialise PL341 Mem Config Registers
209 // =======================================================================
210
211 // |======================================
212 // | Set PL341 Memory Config
213 // |======================================
214 DmcWriteReg(DMC_MEMORY_CONFIG_REG, config->memory_cfg);
215
216 // |======================================
217 // | Set PL341 Memory Config 2
218 // |======================================
219 DmcWriteReg(DMC_MEMORY_CFG2_REG, config->memory_cfg2);
220
221 // |======================================
222 // | Set PL341 Chip Select <n>
223 // |======================================
224 DmcWriteReg(DMC_CHIP_0_CFG_REG, config->chip_cfg0);
225 DmcWriteReg(DMC_CHIP_1_CFG_REG, config->chip_cfg1);
226 DmcWriteReg(DMC_CHIP_2_CFG_REG, config->chip_cfg2);
227 DmcWriteReg(DMC_CHIP_3_CFG_REG, config->chip_cfg3);
228
229 // |======================================
230 // | Set PL341 Memory Config 3
231 // |======================================
232 DmcWriteReg(DMC_MEMORY_CFG3_REG, config->memory_cfg3);
233
234 // |========================================================
235 // |Set Test Chip PHY Registers via PL341 User Config Reg
236 // |Note that user_cfgX registers are Write Only
237 // |
238 // |DLL Freq set = 250MHz - 266MHz
239 // |========================================================
240 DmcWriteReg(DMC_USER_0_CFG_REG, 0x7C924924);
241
242 // user_config2
243 // ------------
244 // Set defaults before calibrating the DDR2 buffer impendence
245 // -Disable ODT
246 // -Default drive strengths
247 DmcWriteReg(DMC_USER_2_CFG_REG, 0x40000198);
248
249 // |=======================================================
250 // |Auto calibrate the DDR2 buffers impendence
251 // |=======================================================
252 val32 = DmcReadReg(DMC_USER_STATUS_REG);
253 while (!(val32 & 0x100)) {
254 val32 = DmcReadReg(DMC_USER_STATUS_REG);
255 }
256
257 // Set the output driven strength
258 DmcWriteReg(DMC_USER_2_CFG_REG, 0x40800000 |
259 (TC_UIOLHXC_VALUE << TC_UIOLHNC_SHIFT) |
260 (TC_UIOLHXC_VALUE << TC_UIOLHPC_SHIFT) |
261 (0x1 << TC_UIOHOCT_SHIFT) |
262 (0x1 << TC_UIOHSTOP_SHIFT));
263
264 // |======================================
265 // | Set PL341 Feature Control Register
266 // |======================================
267 // | Disable early BRESP - use to optimise CLCD performance
268 DmcWriteReg(DMC_FEATURE_CRTL_REG, 0x00000001);
269
270 //=================
271 // Config memories
272 //=================
273
274 for (chip = 0; chip <= config-> max_chip; chip++) {
275 // send nop
276 DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_NOP);
277 // pre-charge all
278 DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_PRECHARGEALL);
279
280 // delay
281 for (i = 0; i < 10; i++) {
282 val32 = DmcReadReg(DMC_STATUS_REG);
283 }
284
285 // set (EMR2) extended mode register 2
286 DmcWriteReg(DMC_DIRECT_CMD_REG,
287 DMC_DIRECT_CMD_CHIP_ADDR(chip) |
288 DMC_DIRECT_CMD_BANKADDR(2) |
289 DMC_DIRECT_CMD_MEMCMD_EXTMODEREG);
290 // set (EMR3) extended mode register 3
291 DmcWriteReg(DMC_DIRECT_CMD_REG,
292 DMC_DIRECT_CMD_CHIP_ADDR(chip) |
293 DMC_DIRECT_CMD_BANKADDR(3) |
294 DMC_DIRECT_CMD_MEMCMD_EXTMODEREG);
295
296 // =================================
297 // set (EMR) Extended Mode Register
298 // ==================================
299 // Put into OCD default state
300 DmcWriteReg(DMC_DIRECT_CMD_REG,
301 DMC_DIRECT_CMD_CHIP_ADDR(chip) |
302 DMC_DIRECT_CMD_BANKADDR(1) |
303 DMC_DIRECT_CMD_MEMCMD_EXTMODEREG);
304
305 // ===========================================================
306 // set (MR) mode register - With DLL reset
307 // ===========================================================
308 // Burst Length = 4 (010)
309 // Burst Type = Seq (0)
310 // Latency = 4 (100)
311 // Test mode = Off (0)
312 // DLL reset = Yes (1)
313 // Wr Recovery = 4 (011)
314 // PD = Normal (0)
315 DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | 0x00080742);
316
317 // pre-charge all
318 DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_PRECHARGEALL);
319 // auto-refresh
320 DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH);
321 // auto-refresh
322 DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH);
323
324 // delay
325 for (i = 0; i < 10; i++) {
326 val32 = DmcReadReg(DMC_STATUS_REG);
327 }
328
329 // ===========================================================
330 // set (MR) mode register - Without DLL reset
331 // ===========================================================
332 // auto-refresh
333 DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH);
334 DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | 0x00080642);
335
336 // delay
337 for (i = 0; i < 10; i++) {
338 val32 = DmcReadReg(DMC_STATUS_REG);
339 }
340
341 // ======================================================
342 // set (EMR) extended mode register - Enable OCD defaults
343 // ======================================================
344 val32 = 0; //NOP
345 DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | 0x00090000 |
346 (DDR_EMR_OCD_DEFAULT << DDR_EMR_OCD_SHIFT) |
347 DDR_EMR_RTT_75R |
348 (DDR_EMR_ODS_VAL << DDR_EMR_ODS_MASK));
349
350 // delay
351 for (i = 0; i < 10; i++) {
352 val32 = DmcReadReg(DMC_STATUS_REG);
353 }
354
355 // Set (EMR) extended mode register - OCD Exit
356 val32 = 0; //NOP
357 DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | 0x00090000 |
358 (DDR_EMR_OCD_NS << DDR_EMR_OCD_SHIFT) |
359 DDR_EMR_RTT_75R |
360 (DDR_EMR_ODS_VAL << DDR_EMR_ODS_MASK));
361
362 }
363
364 //----------------------------------------
365 // go command
366 DmcWriteReg(DMC_COMMAND_REG, DMC_COMMAND_GO);
367
368 // wait for ready
369 val32 = DmcReadReg(DMC_STATUS_REG);
370 while (!(val32 & DMC_STATUS_READY)) {
371 val32 = DmcReadReg(DMC_STATUS_REG);
372 }
373 }