xref: /rk3399_rockchip-uboot/arch/arm/mach-at91/mpddrc.c (revision c2ad76c4bdfb8ffbe8946c0e6627b37a11effdf7)
1 /*
2  * Copyright (C) 2013 Atmel Corporation
3  *		      Bo Shen <voice.shen@atmel.com>
4  *
5  * Copyright (C) 2015 Atmel Corporation
6  *		      Wenyou Yang <wenyou.yang@atmel.com>
7  *
8  * SPDX-License-Identifier:	GPL-2.0+
9  */
10 
11 #include <common.h>
12 #include <asm/io.h>
13 #include <asm/arch/atmel_mpddrc.h>
14 
15 static inline void atmel_mpddr_op(const struct atmel_mpddr *mpddr,
16 	      int mode,
17 	      u32 ram_address)
18 {
19 	writel(mode, &mpddr->mr);
20 	writel(0, ram_address);
21 }
22 
23 static int ddr2_decodtype_is_seq(u32 cr)
24 {
25 #if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) || \
26 	defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAM9N12)
27 	if (cr & ATMEL_MPDDRC_CR_DECOD_INTERLEAVED)
28 		return 0;
29 #endif
30 	return 1;
31 }
32 
33 
34 int ddr2_init(const unsigned int base,
35 	      const unsigned int ram_address,
36 	      const struct atmel_mpddrc_config *mpddr_value)
37 {
38 	const struct atmel_mpddr *mpddr = (struct atmel_mpddr *)base;
39 
40 	u32 ba_off, cr;
41 
42 	/* Compute bank offset according to NC in configuration register */
43 	ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9;
44 	if (ddr2_decodtype_is_seq(mpddr_value->cr))
45 		ba_off += ((mpddr_value->cr & ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11;
46 
47 	ba_off += (mpddr_value->md & ATMEL_MPDDRC_MD_DBW_MASK) ? 1 : 2;
48 
49 	/* Program the memory device type into the memory device register */
50 	writel(mpddr_value->md, &mpddr->md);
51 
52 	/* Program the configuration register */
53 	writel(mpddr_value->cr, &mpddr->cr);
54 
55 	/* Program the timing register */
56 	writel(mpddr_value->tpr0, &mpddr->tpr0);
57 	writel(mpddr_value->tpr1, &mpddr->tpr1);
58 	writel(mpddr_value->tpr2, &mpddr->tpr2);
59 
60 	/* Issue a NOP command */
61 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
62 
63 	/* A 200 us is provided to precede any signal toggle */
64 	udelay(200);
65 
66 	/* Issue a NOP command */
67 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
68 
69 	/* Issue an all banks precharge command */
70 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address);
71 
72 	/* Issue an extended mode register set(EMRS2) to choose operation */
73 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
74 		       ram_address + (0x2 << ba_off));
75 
76 	/* Issue an extended mode register set(EMRS3) to set EMSR to 0 */
77 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
78 		       ram_address + (0x3 << ba_off));
79 
80 	/*
81 	 * Issue an extended mode register set(EMRS1) to enable DLL and
82 	 * program D.I.C (output driver impedance control)
83 	 */
84 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
85 		       ram_address + (0x1 << ba_off));
86 
87 	/* Enable DLL reset */
88 	cr = readl(&mpddr->cr);
89 	writel(cr | ATMEL_MPDDRC_CR_DLL_RESET_ENABLED, &mpddr->cr);
90 
91 	/* A mode register set(MRS) cycle is issued to reset DLL */
92 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address);
93 
94 	/* Issue an all banks precharge command */
95 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address);
96 
97 	/* Two auto-refresh (CBR) cycles are provided */
98 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address);
99 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address);
100 
101 	/* Disable DLL reset */
102 	cr = readl(&mpddr->cr);
103 	writel(cr & (~ATMEL_MPDDRC_CR_DLL_RESET_ENABLED), &mpddr->cr);
104 
105 	/* A mode register set (MRS) cycle is issued to disable DLL reset */
106 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address);
107 
108 	/* Set OCD calibration in default state */
109 	cr = readl(&mpddr->cr);
110 	writel(cr | ATMEL_MPDDRC_CR_OCD_DEFAULT, &mpddr->cr);
111 
112 	/*
113 	 * An extended mode register set (EMRS1) cycle is issued
114 	 * to OCD default value
115 	 */
116 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
117 		       ram_address + (0x1 << ba_off));
118 
119 	 /* OCD calibration mode exit */
120 	cr = readl(&mpddr->cr);
121 	writel(cr & (~ATMEL_MPDDRC_CR_OCD_DEFAULT), &mpddr->cr);
122 
123 	/*
124 	 * An extended mode register set (EMRS1) cycle is issued
125 	 * to enable OCD exit
126 	 */
127 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
128 		       ram_address + (0x1 << ba_off));
129 
130 	/* A nornal mode command is provided */
131 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NORMAL_CMD, ram_address);
132 
133 	/* Perform a write access to any DDR2-SDRAM address */
134 	writel(0, ram_address);
135 
136 	/* Write the refresh rate */
137 	writel(mpddr_value->rtr, &mpddr->rtr);
138 
139 	return 0;
140 }
141 
142 int ddr3_init(const unsigned int base,
143 	      const unsigned int ram_address,
144 	      const struct atmel_mpddrc_config *mpddr_value)
145 {
146 	struct atmel_mpddr *mpddr = (struct atmel_mpddr *)base;
147 	u32 ba_off;
148 
149 	/* Compute bank offset according to NC in configuration register */
150 	ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9;
151 	if (ddr2_decodtype_is_seq(mpddr_value->cr))
152 		ba_off += ((mpddr_value->cr &
153 			   ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11;
154 
155 	ba_off += (mpddr_value->md & ATMEL_MPDDRC_MD_DBW_MASK) ? 1 : 2;
156 
157 	/* Program the memory device type */
158 	writel(mpddr_value->md, &mpddr->md);
159 
160 	/*
161 	 * Program features of the DDR3-SDRAM device and timing parameters
162 	 */
163 	writel(mpddr_value->cr, &mpddr->cr);
164 
165 	writel(mpddr_value->tpr0, &mpddr->tpr0);
166 	writel(mpddr_value->tpr1, &mpddr->tpr1);
167 	writel(mpddr_value->tpr2, &mpddr->tpr2);
168 
169 	/* A NOP command is issued to the DDR3-SRAM */
170 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
171 
172 	/* A pause of at least 500us must be observed before a single toggle. */
173 	udelay(500);
174 
175 	/* A NOP command is issued to the DDR3-SDRAM */
176 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
177 
178 	/*
179 	 * An Extended Mode Register Set (EMRS2) cycle is issued to choose
180 	 * between commercial or high temperature operations.
181 	 */
182 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
183 		       ram_address + (0x2 << ba_off));
184 	/*
185 	 * Step 7: An Extended Mode Register Set (EMRS3) cycle is issued to set
186 	 * the Extended Mode Register to 0.
187 	 */
188 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
189 		       ram_address + (0x3 << ba_off));
190 	/*
191 	 * An Extended Mode Register Set (EMRS1) cycle is issued to disable and
192 	 * to program O.D.S. (Output Driver Strength).
193 	 */
194 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
195 		       ram_address + (0x1 << ba_off));
196 
197 	/*
198 	 * Write a one to the DLL bit (enable DLL reset) in the MPDDRC
199 	 * Configuration Register.
200 	 */
201 
202 	/* A Mode Register Set (MRS) cycle is issued to reset DLL. */
203 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address);
204 
205 	udelay(50);
206 
207 	/*
208 	 * A Calibration command (MRS) is issued to calibrate RTT and RON
209 	 * values for the Process Voltage Temperature (PVT).
210 	 */
211 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_DEEP_CMD, ram_address);
212 
213 	/* A Normal Mode command is provided. */
214 	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NORMAL_CMD, ram_address);
215 
216 	/* Perform a write access to any DDR3-SDRAM address. */
217 	writel(0, ram_address);
218 
219 	/*
220 	 * Write the refresh rate into the COUNT field in the MPDDRC
221 	 * Refresh Timer Register (MPDDRC_RTR):
222 	 */
223 	writel(mpddr_value->rtr, &mpddr->rtr);
224 
225 	return 0;
226 }
227