change source file mode to 0644 instead of 0755
[profile/mobile/platform/kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc8825 / sdram.c
1 #include <asm/arch/sci_types.h>\r
2 \r
3 #define REG32(x)              (*((volatile uint32 *)(x)))\r
4 \r
5 #define MEM_CS0_TYPE          MEM_CS_4096MB\r
6 #if defined CONFIG_GARDA && defined CONFIG_SC8825\r
7 #define MEM_CS1_TYPE          MEM_CS_2048MB\r
8 #else\r
9 #define MEM_CS1_TYPE          MEM_CS_0MB          //caution: if CS1 is not available, modify it to MEM_CS_0Mb\r
10 #endif\r
11 //#define MEMORY_TYPE           LPDDR1\r
12 #define MEMORY_TYPE           LPDDR2   //typedef enum int {LPDDR2,LPDDR1,DDR3} MEM_TYPE_ENUM;\r
13 \r
14 #define DQSR_VALUE            4\r
15 #define GATE_TRAING_ON        1\r
16 #define GATE_EARLY_LATE       2\r
17 #ifndef SC8825_EMC_FREQ\r
18 #define SC8825_EMC_FREQ       400   //ddr clock\r
19 #endif\r
20 \r
21 #if (MEMORY_TYPE == LPDDR1)\r
22 #define SC8825_EMC_DRV        40\r
23 #else\r
24 #define SC8825_EMC_DRV        48\r
25 #endif\r
26 \r
27 #define ZQ_CALIBRE_DPSLEEP    0x0\r
28 #define SOFTWARE_ENABLE_VREF  0\r
29 \r
30 #define ANALOG_DIE_REG_BASE   0x42000600\r
31 #define ANALOG_DCDC_CTRL_CAL  0x50\r
32 #define ANALOG_DCDC_CTRL_DS   0x4C\r
33 #define ANA_DDR2_BUF_CTRL1_DS 0x420006D0\r
34 \r
35 //=====================================================================================\r
36 //CAUTIONS:\r
37 //There are some configuration restrictions for SNPS uMCTL/uPCTL controller\r
38 //refer to P287 section M1.7 for details. Also copied here for notification\r
39 //- Memory burst type sequential is not supported for mDDR and LPDDR2 with BL8.\r
40 //- Memory burst type interleaved is not supported for mDDR with BL16.\r
41 //Also, Must read M2.2.10.5 Considerations for Memory Initialization\r
42 //=====================================================================================\r
43 #define MEM_WIDTH             X32\r
44 \r
45 #define BASE_ADDR_AHBREG      (0x20900200)\r
46 #define ADDR_AHBREG_ARMCLK    (BASE_ADDR_AHBREG+0x0024)\r
47 #define ADDR_AHBREG_AHB_CTRL0 (BASE_ADDR_AHBREG+0x0000)\r
48 #define GLB_REG_WR_REG_GEN1   (0x4B000018)\r
49 #define GLB_REG_DPLL_CTRL     (0x4B000040)\r
50 #define UMCTL_REG_BASE        0x60200000\r
51 #define PUBL_REG_BASE         0x60201000\r
52 #define EMC_MEM_BASE_ADDR     0x80000000\r
53 #define _LPDDR1_BL_           8 //2,4,8,16. seems must be 8 now\r
54 #define _LPDDR1_BT_           1 //0: sequential\r
55 //1: interleaving\r
56 #define _LPDDR1_CL_           3 //2,3,4\r
57 #define _LPDDR2_BL_           4 //4,8,16\r
58 #define _LPDDR2_BT_           0 //0: sequential\r
59 //1: interleaving\r
60 #define _LPDDR2_WC_           1 //0: wrap\r
61 //1: no wrap\r
62 \r
63 typedef enum  { Init_mem = 0, Config = 1, Config_req = 2, Access = 3, Access_req = 4, Low_power = 5,\r
64                 Low_power_entry_req = 6, Low_power_exit_req = 7} uPCTL_STATE_ENUM;\r
65 typedef enum  {INIT = 0, CFG = 1, GO = 2, SLEEP = 3, WAKEUP = 4} uPCTL_STATE_CMD_ENUM;\r
66 typedef enum  {LPDDR2, LPDDR1, DDR2, DDR3} MEM_TYPE_ENUM;\r
67 typedef enum  {MEM_64Mb, MEM_128Mb, MEM_256Mb, MEM_512Mb, MEM_1024Mb, MEM_2048Mb, MEM_4096Mb, MEM_8192Mb} MEM_DENSITY_ENUM;\r
68 typedef enum  {X8, X16, X32} MEM_WIDTH_ENUM;\r
69 typedef enum  {LPDDR2_S2, LPDDR2_S4} MEM_COL_TYPE_ENUM;\r
70 typedef enum  {BL2 = 2, BL4 = 4, BL8 = 8, BL16 = 16} MEM_BL_ENUM;\r
71 typedef enum  {SEQ, INTLV} MEM_BT_ENUM;\r
72 \r
73 typedef enum\r
74 {\r
75         MEM_CS_8192MB,\r
76         MEM_CS_4096MB,\r
77         MEM_CS_2048MB,\r
78         MEM_CS_1024MB,\r
79         MEM_CS_512MB,\r
80         MEM_CS_256MB,\r
81         MEM_CS_128MB,\r
82         MEM_CS_64MB,\r
83         MEM_CS_0MB,\r
84 }MEM_CS_TYPE;\r
85 \r
86 typedef enum\r
87 {\r
88         SDLL_PHS_DLY_MIN = 0,\r
89         SDLL_PHS_DLY_DEF = 0,\r
90         SDLL_PHS_DLY_36  = 0,\r
91         SDLL_PHS_DLY_54  = 1,\r
92         SDLL_PHS_DLY_72  = 2,\r
93         SDLL_PHS_DLY_90  = 3,\r
94         SDLL_PHS_DLY_108 = 4,\r
95         SDLL_PHS_DLY_126 = 5,\r
96         SDLL_PHS_DLY_144 = 6,\r
97         SDLL_PHS_DLY_MAX = 6,\r
98 }SDLL_PHS_DLY_E;\r
99 \r
100 typedef enum\r
101 {\r
102         DQS_PHS_DLY_MIN = 0,\r
103         DQS_PHS_DLY_90  = 0,\r
104         DQS_PHS_DLY_180 = 1,\r
105         DQS_PHS_DLY_DEF = 1,\r
106         DQS_PHS_DLY_270 = 2,\r
107         DQS_PHS_DLY_360 = 3,\r
108         DQS_PHS_DLY_MAX = 3,\r
109 }DQS_PHS_DLY_E;\r
110 \r
111 typedef enum\r
112 {\r
113         DXN_MIN = 0,\r
114         DXN0    = 0,\r
115         DXN1    = 1,\r
116         DXN2    = 2,\r
117         DXN3    = 3,\r
118         DXN_MAX = 3,\r
119 }DXN_E;\r
120 \r
121 \r
122 //umctl/upctl registers declaration//{{{\r
123 #define UMCTL_CFG_ADD_SCFG            0x000\r
124 #define UMCTL_CFG_ADD_SCTL            0x004//moves the uPCTL from one state to another\r
125 #define UMCTL_CFG_ADD_STAT            0x008//provides information about the current state of the uPCTL\r
126 #define UMCTL_CFG_ADD_MCMD            0x040\r
127 #define UMCTL_CFG_ADD_POWCTL          0x044\r
128 #define UMCTL_CFG_ADD_POWSTAT         0x048\r
129 #define UMCTL_CFG_ADD_MCFG1           0x07C\r
130 #define UMCTL_CFG_ADD_MCFG            0x080\r
131 #define UMCTL_CFG_ADD_PPCFG           0x084\r
132 #define UMCTL_CFG_ADD_TOGCNT1U        0x0c0\r
133 #define UMCTL_CFG_ADD_TINIT           0x0c4\r
134 #define UMCTL_CFG_ADD_TRSTH           0x0c8\r
135 #define UMCTL_CFG_ADD_TOGCNT100N      0x0cc\r
136 #define UMCTL_CFG_ADD_TREFI           0x0d0\r
137 #define UMCTL_CFG_ADD_TMRD            0x0d4\r
138 #define UMCTL_CFG_ADD_TRFC            0x0d8\r
139 #define UMCTL_CFG_ADD_TRP             0x0dc\r
140 #define UMCTL_CFG_ADD_TRTW            0x0e0\r
141 #define UMCTL_CFG_ADD_TAL             0x0e4\r
142 #define UMCTL_CFG_ADD_TCL             0x0e8\r
143 #define UMCTL_CFG_ADD_TCWL            0x0ec\r
144 #define UMCTL_CFG_ADD_TRAS            0x0f0\r
145 #define UMCTL_CFG_ADD_TRC             0x0f4\r
146 #define UMCTL_CFG_ADD_TRCD            0x0f8\r
147 #define UMCTL_CFG_ADD_TRRD            0x0fc\r
148 #define UMCTL_CFG_ADD_TRTP            0x100\r
149 #define UMCTL_CFG_ADD_TWR             0x104\r
150 #define UMCTL_CFG_ADD_TWTR            0x108\r
151 #define UMCTL_CFG_ADD_TEXSR           0x10c\r
152 #define UMCTL_CFG_ADD_TXP             0x110\r
153 #define UMCTL_CFG_ADD_TXPDLL          0x114\r
154 #define UMCTL_CFG_ADD_TZQCS           0x118\r
155 #define UMCTL_CFG_ADD_TZQCSI          0x11C\r
156 #define UMCTL_CFG_ADD_TDQS            0x120\r
157 #define UMCTL_CFG_ADD_TCKSRE          0x124\r
158 #define UMCTL_CFG_ADD_TCKSRX          0x128\r
159 #define UMCTL_CFG_ADD_TCKE            0x12c\r
160 #define UMCTL_CFG_ADD_TMOD            0x130\r
161 #define UMCTL_CFG_ADD_TRSTL           0x134\r
162 #define UMCTL_CFG_ADD_TZQCL           0x138\r
163 #define UMCTL_CFG_ADD_TCKESR          0x13c\r
164 #define UMCTL_CFG_ADD_TDPD            0x140\r
165 #define UMCTL_CFG_ADD_DTUWACTL        0x200\r
166 #define UMCTL_CFG_ADD_DTURACTL        0x204\r
167 #define UMCTL_CFG_ADD_DTUCFG          0x208\r
168 #define UMCTL_CFG_ADD_DTUECTL         0x20C\r
169 #define UMCTL_CFG_ADD_DTUWD0          0x210\r
170 #define UMCTL_CFG_ADD_DTUWD1          0x214\r
171 #define UMCTL_CFG_ADD_DTUWD2          0x218\r
172 #define UMCTL_CFG_ADD_DTUWD3          0x21c\r
173 #define UMCTL_CFG_ADD_DTURD0          0x224\r
174 #define UMCTL_CFG_ADD_DTURD1          0x228\r
175 #define UMCTL_CFG_ADD_DTURD2          0x22C\r
176 #define UMCTL_CFG_ADD_DTURD3          0x230\r
177 #define UMCTL_CFG_ADD_DFITPHYWRDATA   0x250\r
178 #define UMCTL_CFG_ADD_DFITPHYWRLAT    0x254\r
179 #define UMCTL_CFG_ADD_DFITRDDATAEN    0x260\r
180 #define UMCTL_CFG_ADD_DFITPHYRDLAT    0x264\r
181 #define UMCTL_CFG_ADD_DFISTSTAT0      0x2c0\r
182 #define UMCTL_CFG_ADD_DFISTCFG0       0x2c4\r
183 #define UMCTL_CFG_ADD_DFISTCFG1       0x2c8\r
184 #define UMCTL_CFG_ADD_DFISTCFG2       0x2d8\r
185 #define UMCTL_CFG_ADD_DFILPCFG0       0x2f0\r
186 #define UMCTL_CFG_ADD_PCFG_0          0x400\r
187 #define UMCTL_CFG_ADD_PCFG_1          0x404\r
188 #define UMCTL_CFG_ADD_PCFG_2          0x408\r
189 #define UMCTL_CFG_ADD_PCFG_3          0x40c\r
190 #define UMCTL_CFG_ADD_PCFG_4          0x410\r
191 #define UMCTL_CFG_ADD_PCFG_5          0x414\r
192 #define UMCTL_CFG_ADD_PCFG_6          0x418\r
193 #define UMCTL_CFG_ADD_PCFG_7          0x41c\r
194 #define UMCTL_CFG_ADD_DCFG_CS0        0x484\r
195 #define UMCTL_CFG_ADD_DCFG_CS1        0x494\r
196 //}}}\r
197 \r
198 //publ configure registers declaration.//{{{\r
199 //copied from PUBL FPGA cfg module. here shift them(<< 2)\r
200 #define PUBL_CFG_ADD_RIDR          (0x00 * 4) // R   - Revision Identification Register\r
201 #define PUBL_CFG_ADD_PIR           (0x01 * 4) // R/W - PHY Initialization Register\r
202 #define PUBL_CFG_ADD_PGCR          (0x02 * 4) // R/W - PHY General Configuration Register\r
203 #define PUBL_CFG_ADD_PGSR          (0x03 * 4) // R   - PHY General Status Register\r
204 #define PUBL_CFG_ADD_DLLGCR        (0x04 * 4) // R/W - DLL General Control Register\r
205 #define PUBL_CFG_ADD_ACDLLCR       (0x05 * 4) // R/W - AC DLL Control Register\r
206 #define PUBL_CFG_ADD_PTR0          (0x06 * 4) // R/W - PHY Timing Register 0\r
207 #define PUBL_CFG_ADD_PTR1          (0x07 * 4) // R/W - PHY Timing Register 1\r
208 #define PUBL_CFG_ADD_PTR2          (0x08 * 4) // R/W - PHY Timing Register 2\r
209 #define PUBL_CFG_ADD_ACIOCR        (0x09 * 4) // R/W - AC I/O Configuration Register\r
210 #define PUBL_CFG_ADD_DXCCR         (0x0A * 4) // R/W - DATX8 I/O Configuration Register\r
211 #define PUBL_CFG_ADD_DSGCR         (0x0B * 4) // R/W - DFI Configuration Register\r
212 #define PUBL_CFG_ADD_DCR           (0x0C * 4) // R/W - DRAM Configuration Register\r
213 #define PUBL_CFG_ADD_DTPR0         (0x0D * 4) // R/W - SDRAM Timing Parameters Register 0\r
214 #define PUBL_CFG_ADD_DTPR1         (0x0E * 4) // R/W - SDRAM Timing Parameters Register 1\r
215 #define PUBL_CFG_ADD_DTPR2         (0x0F * 4) // R/W - SDRAM Timing Parameters Register 2\r
216 #define PUBL_CFG_ADD_MR0           (0x10 * 4) // R/W - Mode Register\r
217 #define PUBL_CFG_ADD_MR1           (0x11 * 4) // R/W - Ext}ed Mode Register\r
218 #define PUBL_CFG_ADD_MR2           (0x12 * 4) // R/W - Ext}ed Mode Register 2\r
219 #define PUBL_CFG_ADD_MR3           (0x13 * 4) // R/W - Ext}ed Mode Register 3\r
220 #define PUBL_CFG_ADD_ODTCR         (0x14 * 4) // R/W - ODT Configuration Register\r
221 #define PUBL_CFG_ADD_DTAR          (0x15 * 4) // R/W - Data Training Address Register\r
222 #define PUBL_CFG_ADD_DTDR0         (0x16 * 4) // R/W - Data Training Data Register 0\r
223 #define PUBL_CFG_ADD_DTDR1         (0x17 * 4) // R/W - Data Training Data Register 1\r
224 #define PUBL_CFG_ADD_DCUAR         (0x30 * 4) // R/W - DCU Address Register\r
225 #define PUBL_CFG_ADD_DCUDR         (0x31 * 4) // R/W - DCU Data Register\r
226 #define PUBL_CFG_ADD_DCURR         (0x32 * 4) // R/W - DCU Run Register\r
227 #define PUBL_CFG_ADD_DCUSR0        (0x36 * 4) // R/W - DCU status register\r
228 #define PUBL_CFG_ADD_BISTRR        (0x40 * 4) // R/W - BIST run register\r
229 #define PUBL_CFG_ADD_BISTMSKR0     (0x41 * 4) // R/W - BIST Mask Register 0\r
230 #define PUBL_CFG_ADD_BISTMSKR1     (0x42 * 4) // R/W - BIST Mask Register 1\r
231 #define PUBL_CFG_ADD_BISTWCR       (0x43 * 4) // R/W - BIST Word Count Register\r
232 #define PUBL_CFG_ADD_BISTLSR       (0x44 * 4) // R/W - BIST LFSR Seed Register \r
233 #define PUBL_CFG_ADD_BISTAR0       (0x45 * 4) // R/W - BIST Address Register 0\r
234 #define PUBL_CFG_ADD_BISTAR1       (0x46 * 4) // R/W - BIST Address Register 1\r
235 #define PUBL_CFG_ADD_BISTAR2       (0x47 * 4) // R/W - BIST Address Register 2\r
236 #define PUBL_CFG_ADD_BISTUDPR      (0x48 * 4) // R/W - BIST User Data Pattern Register\r
237 #define PUBL_CFG_ADD_BISTGSR       (0x49 * 4) // R/W - BIST General Status Register\r
238 #define PUBL_CFG_ADD_BISTWER       (0x4a * 4) // R/W - BIST Word Error Register\r
239 #define PUBL_CFG_ADD_BISTBER0      (0x4b * 4) // R/W - BIST Bit Error Register 0\r
240 #define PUBL_CFG_ADD_BISTBER1      (0x4c * 4) // R/W - BIST Bit Error Register 1\r
241 #define PUBL_CFG_ADD_BISTBER2      (0x4d * 4) // R/W - BIST Bit Error Register 2\r
242 #define PUBL_CFG_ADD_BISTWCSR      (0x4e * 4) // R/W - BIST Word Count Status Register\r
243 #define PUBL_CFG_ADD_BISTFWR0      (0x4f * 4) // R/W - BIST Fail Word Register 0\r
244 #define PUBL_CFG_ADD_BISTFWR1      (0x50 * 4) // R/W - BIST Fail Word Register 1\r
245 #define PUBL_CFG_ADD_ZQ0CR0        (0x60 * 4) // R/W - ZQ 0 Impedance Control Register 0\r
246 #define PUBL_CFG_ADD_ZQ0CR1        (0x61 * 4) // R/W - ZQ 0 Impedance Control Register 1\r
247 #define PUBL_CFG_ADD_ZQ0SR0        (0x62 * 4) // R/W - ZQ 0 Impedance Status Register 0\r
248 #define PUBL_CFG_ADD_ZQ0SR1        (0x63 * 4) // R/W - ZQ 0 Impedance Status Register 1\r
249 \r
250 #define PUBL_CFG_ADD_DX0GCR        (0x70 * 4) // R/W - DATX8 0 General Configuration Register\r
251 #define PUBL_CFG_ADD_DX0GSR0       (0x71 * 4) // R   - DATX8 0 General Status Register 0\r
252 #define PUBL_CFG_ADD_DX0GSR1       (0x72 * 4) // R   - DATX8 0 General Status Register 1\r
253 #define PUBL_CFG_ADD_DX0DLLCR      (0x73 * 4) // R   - DATX8 0 DLL Control Register\r
254 #define PUBL_CFG_ADD_DX0DQTR       (0x74 * 4) // R/W - DATX8 0 DQ Timing Register\r
255 #define PUBL_CFG_ADD_DX0DQSTR      (0x75 * 4) // R/W\r
256 \r
257 #define PUBL_CFG_ADD_DX1GCR        (0x80 * 4) // R/W - DATX8 1 General Configuration Register\r
258 #define PUBL_CFG_ADD_DX1GSR0       (0x81 * 4) // R   - DATX8 1 General Status Register 0\r
259 #define PUBL_CFG_ADD_DX1GSR1       (0x82 * 4) // R   - DATX8 1 General Status Register 1\r
260 #define PUBL_CFG_ADD_DX1DLLCR      (0x83 * 4) // R   - DATX8 1 DLL Control Register\r
261 #define PUBL_CFG_ADD_DX1DQTR       (0x84 * 4) // R   - DATX8 1 DLL Control Register\r
262 #define PUBL_CFG_ADD_DX1DQSTR      (0x85 * 4) // R/W\r
263 \r
264 #define PUBL_CFG_ADD_DX2GCR        (0x90 * 4) // R/W - DATX8 2 General Configuration Register\r
265 #define PUBL_CFG_ADD_DX2GSR0       (0x91 * 4) // R   - DATX8 2 General Status Register 0\r
266 #define PUBL_CFG_ADD_DX2GSR1       (0x92 * 4) // R   - DATX8 2 General Status Register 1\r
267 #define PUBL_CFG_ADD_DX2DLLCR      (0x93 * 4) // R   - DATX8 2 DLL Control Register\r
268 #define PUBL_CFG_ADD_DX2DQTR       (0x94 * 4) // R   - DATX8 2 DLL Control Register\r
269 #define PUBL_CFG_ADD_DX2DQSTR      (0x95 * 4) // R/W\r
270 \r
271 #define PUBL_CFG_ADD_DX3GCR        (0xa0 * 4) // R/W - DATX8 3 General Configuration Register\r
272 #define PUBL_CFG_ADD_DX3GSR0       (0xa1 * 4) // R   - DATX8 3 General Status Register 0\r
273 #define PUBL_CFG_ADD_DX3GSR1       (0xa2 * 4) // R   - DATX8 3 General Status Register 1\r
274 #define PUBL_CFG_ADD_DX3DLLCR      (0xa3 * 4) // R   - DATX8 3 DLL Control Register\r
275 #define PUBL_CFG_ADD_DX3DQTR       (0xa4 * 4) // R/W - DATX8 3 DQ Timing Register\r
276 #define PUBL_CFG_ADD_DX3DQSTR      (0xa5 * 4) // R/W\r
277 \r
278 static void modify_reg_field(uint32 addr, uint32 start_bit, uint32 bit_num, uint32 value)\r
279 {\r
280         uint32 temp, i;\r
281         temp = REG32(addr);\r
282         for (i=0; i<bit_num; i++)\r
283         {\r
284                 temp &= ~(0x1<<(start_bit+i));\r
285         }\r
286         temp |= value<<start_bit;\r
287         REG32(addr) = temp;\r
288 }\r
289 \r
290 static void modify_adie_reg_field(uint32 addr, uint32 start_bit, uint32 bit_num, uint32 value)\r
291 {\r
292         uint32 temp, i;\r
293         temp = ADI_Analogdie_reg_read(addr);\r
294         for (i=0; i<bit_num; i++)\r
295         {\r
296                 temp &= ~(0x1<<(start_bit+i));\r
297         }\r
298         temp |= value<<start_bit;\r
299         REG32(addr) = temp;\r
300 }\r
301 \r
302 static uint32 polling_reg_bit_field(uint32 addr, uint32 start_bit, uint32 bit_num, uint32 value)\r
303 {\r
304         uint32 temp, i;\r
305         uint32 exp_value;\r
306         uint32 mask;\r
307 \r
308         mask = 0;\r
309         for (i=0; i<bit_num; i++)\r
310         {\r
311                 mask |= 1<<(start_bit+i);\r
312         }\r
313         exp_value = value << start_bit;\r
314         do {temp = REG32(addr);} while((temp & mask) != exp_value);\r
315         return temp;\r
316 }\r
317 \r
318 static void wait_n_pclk_cycle(uint32 num)\r
319 {\r
320         volatile uint32 i;\r
321         uint32          value_temp;\r
322         for (i=0; i<num; i++)\r
323         {\r
324                 value_temp = REG32(PUBL_REG_BASE+PUBL_CFG_ADD_PGSR);\r
325         }\r
326 }\r
327 \r
328 static void wait_100ns()\r
329 {\r
330         uint32 i;\r
331         for (i=0; i<100; i++);\r
332 }\r
333 \r
334 static void wait_1us()\r
335 {\r
336         uint32 i;\r
337         for (i=0; i<1000; i++);\r
338 }\r
339 \r
340 static void wait_us(uint32 us)\r
341 {\r
342         uint32 i;\r
343         for (i=0; i<us; i++)\r
344         {\r
345                 wait_1us();\r
346         }\r
347 }\r
348 \r
349 static void write_upctl_state_cmd(uPCTL_STATE_CMD_ENUM cmd)\r
350 {\r
351         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_SCTL) = cmd;\r
352 }\r
353 \r
354 static void poll_upctl_state (uPCTL_STATE_ENUM state)\r
355 {\r
356         uPCTL_STATE_ENUM state_poll;\r
357         uint32 value_temp;\r
358         do\r
359         {\r
360                 value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);\r
361                 state_poll = value_temp & 0x7;\r
362         }\r
363         while(state_poll != state);\r
364         return;\r
365 }\r
366 \r
367 static void move_upctl_state_to_initmem(void)\r
368 {\r
369         uPCTL_STATE_ENUM upctl_state;\r
370         uPCTL_STATE_CMD_ENUM  upctl_state_cmd;\r
371         uint32 tmp_val ;\r
372         //tmp_val = upctl_state ;\r
373         tmp_val = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);\r
374         //while(upctl_state!= Init_mem) {\r
375         while((tmp_val & 0x7) != Init_mem)\r
376         {\r
377                 switch((tmp_val & 0x7))\r
378                 {\r
379                         case Config:\r
380                                 {\r
381                                         write_upctl_state_cmd(INIT);\r
382                                         poll_upctl_state(Init_mem);\r
383                                         upctl_state = Init_mem;\r
384                                         tmp_val = upctl_state ;\r
385                                         break;\r
386                                 }\r
387                         case Access:\r
388                                 {\r
389                                         write_upctl_state_cmd(CFG);\r
390                                         poll_upctl_state(Config);\r
391                                         upctl_state = Config;\r
392                                         tmp_val = upctl_state ;\r
393                                         break;\r
394                                 }\r
395                         case Low_power:\r
396                                 {\r
397                                         write_upctl_state_cmd(WAKEUP);\r
398                                         poll_upctl_state(Access);\r
399                                         upctl_state = Access;\r
400                                         tmp_val = upctl_state ;\r
401                                         break;\r
402                                 }\r
403                         default:   //transitional state\r
404                                 {\r
405                                         tmp_val = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);\r
406                                         break;\r
407                                 }\r
408                 }\r
409         }\r
410 }\r
411 \r
412 static void move_upctl_state_to_config(void)\r
413 {\r
414         uPCTL_STATE_ENUM upctl_state;\r
415         //uPCTL_STATE_CMD_ENUM  upctl_state_cmd;\r
416         uint32  tmp_val ;\r
417         tmp_val = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);\r
418         upctl_state = tmp_val & 0x7;\r
419         while(upctl_state != Config)\r
420         {\r
421 \r
422                 switch(upctl_state)\r
423                 {\r
424                         case Low_power:\r
425                                 {\r
426                                         write_upctl_state_cmd(WAKEUP);\r
427                                         poll_upctl_state(Access);\r
428                                         upctl_state = Access;\r
429                                         break;\r
430                                 }\r
431                         case Init_mem:\r
432                                 {\r
433                                         write_upctl_state_cmd(CFG);\r
434                                         poll_upctl_state(Config);\r
435                                         upctl_state = Config;\r
436                                         break;\r
437                                 }\r
438                         case Access:\r
439                                 {\r
440                                         write_upctl_state_cmd(CFG);\r
441                                         poll_upctl_state(Config);\r
442                                         upctl_state = Config;\r
443                                         break;\r
444                                 }\r
445                         default:   //transitional state\r
446                                 {\r
447                                         tmp_val = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);\r
448                                         upctl_state = tmp_val & 0x7;\r
449                                 }\r
450                 }\r
451         }\r
452 }\r
453 \r
454 static void move_upctl_state_to_low_power(void)\r
455 {\r
456         uPCTL_STATE_ENUM upctl_state;\r
457         //uPCTL_STATE_CMD_ENUM  upctl_state_cmd;\r
458         uint32  tmp_val ;\r
459         tmp_val = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);\r
460         upctl_state = tmp_val & 0x7;\r
461         while(upctl_state != Low_power)\r
462         {\r
463                 switch(upctl_state)\r
464                 {\r
465                         case Access:\r
466                                 {\r
467                                         write_upctl_state_cmd(SLEEP);\r
468                                         poll_upctl_state(Low_power);\r
469                                         upctl_state = Low_power;\r
470                                         break;\r
471                                 }\r
472                         case Config:\r
473                                 {\r
474                                         write_upctl_state_cmd(GO);\r
475                                         poll_upctl_state(Access);\r
476                                         upctl_state = Access;\r
477                                         break;\r
478                                 }\r
479                         case Init_mem:\r
480                                 {\r
481                                         write_upctl_state_cmd(CFG);\r
482                                         poll_upctl_state(Config);\r
483                                         upctl_state = Config;\r
484                                         break;\r
485                                 }\r
486                         default:   //transitional state\r
487                                 {\r
488                                         tmp_val = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);\r
489                                         upctl_state = tmp_val & 0x7;\r
490                                 }\r
491                 }\r
492         }\r
493 }\r
494 \r
495 \r
496 static void move_upctl_state_to_access(void)\r
497 {\r
498         uPCTL_STATE_ENUM upctl_state;\r
499         uint32  tmp_val ;\r
500         tmp_val = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);\r
501         upctl_state = tmp_val & 0x7;\r
502 \r
503         while(upctl_state != Access)\r
504         {\r
505                 switch(upctl_state)\r
506                 {\r
507                         case Access:\r
508                                 {\r
509                                         break;\r
510                                 }\r
511                         case Config:\r
512                                 {\r
513                                         write_upctl_state_cmd(GO);\r
514                                         poll_upctl_state(Access);\r
515                                         upctl_state = Access;\r
516                                         break;\r
517                                 }\r
518                         case Init_mem:\r
519                                 {\r
520                                         write_upctl_state_cmd(CFG);\r
521                                         poll_upctl_state(Config);\r
522                                         upctl_state = Config;\r
523                                         break;\r
524                                 }\r
525                         case Low_power:\r
526                                 {\r
527                                         write_upctl_state_cmd(WAKEUP);\r
528                                         poll_upctl_state(Access);\r
529                                         upctl_state = Access;\r
530                                         break;\r
531                                 }\r
532                         default:   //transitional state\r
533                                 {\r
534                                         tmp_val = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);\r
535                                         upctl_state = tmp_val & 0x7;\r
536                                 }\r
537                 }\r
538         }\r
539 }\r
540 \r
541 //return 1 if OK, 0 if fail\r
542 static uint32 ddr_rw_chk_single(uint32 offset, uint32 data)\r
543 {\r
544         uint32 rd;\r
545         *(volatile uint32 *)(EMC_MEM_BASE_ADDR + offset) = data;\r
546         rd = *(volatile uint32 *)(EMC_MEM_BASE_ADDR + offset);\r
547         if(rd == data)\r
548                 return 1;\r
549         else\r
550                 return 0;\r
551 }\r
552 //return 1 if OK, 0 if fail\r
553 static uint32 ddr_rw_chk(uint32 offset)\r
554 {\r
555         uint32 i;\r
556         uint32 data;\r
557         for(i = 0; i < 6; i++)\r
558         {\r
559                 if(i == 0)\r
560                 {\r
561                         data = 0x00000000;\r
562                 }\r
563                 else if(i == 1)\r
564                 {\r
565                         data = 0xffffffff;\r
566                 }\r
567                 else if(i == 2)\r
568                 {\r
569                         data = 0x12345678;\r
570                 }\r
571                 else if(i == 3)\r
572                 {\r
573                         data = 0x87654321;\r
574                 }\r
575                 else if(i == 4)\r
576                 {\r
577                         data = 0x5a5a5a5a;\r
578                 }\r
579                 else if(i == 5)\r
580                 {\r
581                         data = 0xa5a5a5a5;\r
582                 }\r
583                 if(ddr_rw_chk_single(offset, data) == 0)\r
584                         return 0;\r
585                 if(ddr_rw_chk_single(offset + 0x4, data) == 0)\r
586                         return 0;\r
587                 if(ddr_rw_chk_single(offset + 0x8, data) == 0)\r
588                         return 0;\r
589                 if(ddr_rw_chk_single(offset + 0xc, data) == 0)\r
590                         return 0;\r
591         }\r
592         return 1;\r
593 }\r
594 static uint32 dq_training(uint32 offset)\r
595 {\r
596         uint32 i;\r
597         uint32 B0, B1, B2, B3;\r
598         for(B0 = 0; B0 < 16; B0++)\r
599         {\r
600                 *(volatile uint32 *)(PUBL_REG_BASE + PUBL_CFG_ADD_DX0DQSTR) = B0 | (B0 << 4);\r
601                 for(B1 = 0; B1 < 16; B1++)\r
602                 {\r
603                         *(volatile uint32 *)(PUBL_REG_BASE + PUBL_CFG_ADD_DX1DQSTR) = B1 | (B1 << 4);\r
604                         for(B2 = 0; B2 < 16; B2++)\r
605                         {\r
606                                 *(volatile uint32 *)(PUBL_REG_BASE + PUBL_CFG_ADD_DX2DQSTR) = B2 | (B2 << 4);\r
607                                 for(B3 = 0; B3 < 16; B3++)\r
608                                 {\r
609                                         *(volatile uint32 *)(PUBL_REG_BASE + PUBL_CFG_ADD_DX3DQSTR) = B3 | (B3 << 4);\r
610                                         //for(j=0;j<100;j++); //wait some time after changing config register\r
611                                         if(ddr_rw_chk(offset))\r
612                                         {\r
613                                                 // *(volatile uint32 *)(EMC_MEM_BASE_ADDR+0x1000+i)=(0xBA55<<16)|(B3<<12)|(B2<<8)|(B1<<4)|B0;\r
614                                                 return 1;\r
615                                         }\r
616                                         else\r
617                                         {\r
618                                                 //*(volatile uint32 *)(EMC_MEM_BASE_ADDR+0x1000+i)=(0xFA11<<16)|(B3<<12)|(B2<<8)|(B1<<4)|B0;\r
619                                         }\r
620                                         i = i + 4;\r
621                                 }\r
622                         }\r
623                 }\r
624         }\r
625         //if not found, set as default value,and set rank2/3 as all one to flag the error\r
626         *(volatile uint32 *)(PUBL_REG_BASE + PUBL_CFG_ADD_DX0DQSTR) = 0xffffffaa;\r
627         *(volatile uint32 *)(PUBL_REG_BASE + PUBL_CFG_ADD_DX1DQSTR) = 0xffffffaa;\r
628         *(volatile uint32 *)(PUBL_REG_BASE + PUBL_CFG_ADD_DX2DQSTR) = 0xffffffaa;\r
629         *(volatile uint32 *)(PUBL_REG_BASE + PUBL_CFG_ADD_DX3DQSTR) = 0xffffffaa;\r
630         return 0;\r
631 }\r
632 \r
633 static void emc_publ_do_gate_training(void)\r
634 {\r
635         uint32  value_temp, i;\r
636         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PIR) = 0x81;\r
637 \r
638         //check data training done\r
639         //according to PUBL databook on PIR operation.\r
640         //10 configuration clock cycle must be waited before polling PGSR\r
641         //repeat(10)@(posedge `HIER_ARM_SYS.u_sys_wrap.u_DWC_ddr3phy_pub.pclk);\r
642         //for(i = 0; i < 100; i++);\r
643         wait_n_pclk_cycle(5);\r
644         do\r
645                 value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PGSR);\r
646         while((value_temp & 0x10) != 0x10);\r
647         if((value_temp&(0x3 << 5)) != 0x0)\r
648         {\r
649                 if((value_temp & 0x40) != 0)\r
650                 {\r
651                         while(1);\r
652                 }\r
653                 if((value_temp & 0x20) != 0)\r
654                 {\r
655                         while(1);\r
656                 }\r
657         }\r
658         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DX0GSR0);\r
659         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DX1GSR0);\r
660         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DX2GSR0);\r
661         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DX3GSR0);\r
662 }\r
663 \r
664 static void set_value_ddrphy_ret_en(uint32 value)\r
665 {\r
666         if (value == 0x1)\r
667         {\r
668                 REG32(0x4B001080) = 0x1;  //set ret_en to 1\r
669         }\r
670         else if (value == 0x0)\r
671         {\r
672                 REG32(0x4B002080) = 0x1;  //clear set_en to 1\r
673         }\r
674 }\r
675 \r
676 static void publ_do_zq_calibration()\r
677 {\r
678         uint32 value_temp, i;\r
679         REG32(PUBL_REG_BASE+PUBL_CFG_ADD_ZQ0CR0) = 1<<30;\r
680 \r
681         value_temp = polling_reg_bit_field(PUBL_REG_BASE+PUBL_CFG_ADD_ZQ0SR0, 31, 1, 1);\r
682         if ((value_temp & (0x1<<30)) == (0<<30))\r
683         {\r
684 \r
685         }\r
686         else\r
687         {\r
688 //zq cal has error\r
689                 while (1);\r
690         }\r
691 }\r
692 \r
693 static void emc_init_common_reg(MEM_TYPE_ENUM mem_type_enum,\r
694                 MEM_WIDTH_ENUM mem_width_enum, uint32 mem_drv)\r
695 {\r
696         uint32  value_temp;\r
697         uint32  TOGCNT1U, TOGCNT100N;\r
698 \r
699         if (mem_type_enum == LPDDR1)\r
700         {\r
701                 value_temp = (1<<31)|(1<<28)|(0xc<<5)|(0xc);\r
702                 REG32(PUBL_REG_BASE+PUBL_CFG_ADD_ZQ0CR0) = value_temp;\r
703         }\r
704 \r
705         //program common registers for ASIC/FPGA\r
706         //Memory Timing Configuration Registers\r
707         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_SCFG) = 0x00000420;\r
708         value_temp = 0x00e60041; //no auto low power enabled\r
709         value_temp &= ~(0x1 << 17);\r
710         value_temp &= ~(0x3 << 22);\r
711         value_temp &= ~(0x3 << 20);\r
712 \r
713 \r
714         switch(mem_type_enum)\r
715         {\r
716                 case LPDDR1:\r
717                         {\r
718                                 value_temp |= (0x2 << 22); //LPDDR1 enabled\r
719                                 value_temp |= (_LPDDR1_BL_ == 2  ? 0x0 :\r
720                                                 _LPDDR1_BL_ == 4  ? 0x1 :\r
721                                                 _LPDDR1_BL_ == 8  ? 0x2 :\r
722                                                 _LPDDR1_BL_ == 16 ? 0x3 : 0x0) << 20;\r
723                                 value_temp |= (0x1 << 17); //pd_exit_mode\r
724                                 break;\r
725                         }\r
726                 case LPDDR2:\r
727                         {\r
728                                 value_temp |= 0x3 << 22; //LPDDR2 enabled\r
729                                 value_temp |= (_LPDDR2_BL_ == 4  ? 0x1 :\r
730                                                 _LPDDR2_BL_ == 8  ? 0x2 :\r
731                                                 _LPDDR2_BL_ == 16 ? 0x3 : 0x2) << 20;\r
732                                 value_temp |= (0x1 << 17); //pd_exit_mode\r
733                                 break;\r
734                         }\r
735         }\r
736         value_temp &= ~(0xff << 24); //Clock stop idle period in n_clk cycles\r
737         value_temp &= ~(0xff << 8); //Power-down idle period in n_clk cycles\r
738         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCFG) =        value_temp;\r
739 \r
740         //sr_idle\r
741         value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCFG1);\r
742         value_temp &= ~0xff; //\r
743         value_temp &= ~(0xff << 16); //\r
744         //value_temp[7:0] = 0x7D; //125*32=4000 cycles\r
745         value_temp |= 0x00; //\r
746         value_temp |= (0x00 << 16); //hw_idle\r
747         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCFG1) =       value_temp;\r
748 \r
749         value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PPCFG);\r
750         value_temp &= ~0x1;\r
751         switch(mem_width_enum)\r
752         {\r
753                 case X16:\r
754                         {\r
755                                 value_temp |= 0x1;    //enable partial populated memory\r
756                                 break;\r
757                         }\r
758                 case X8:\r
759                 default:\r
760                         break;\r
761         }\r
762         REG32(UMCTL_REG_BASE+UMCTL_CFG_ADD_PPCFG) = value_temp;\r
763         if (0)\r
764         {\r
765                 TOGCNT100N = 100;\r
766                 TOGCNT1U   = 1000;\r
767         }\r
768         else\r
769         {\r
770                 switch (SC8825_EMC_FREQ)\r
771                 {\r
772                         case 100:\r
773                                 TOGCNT100N = 10;\r
774                                 TOGCNT1U   = 100;\r
775                                 break;\r
776                         case 200:\r
777                                 TOGCNT100N = 20;\r
778                                 TOGCNT1U   = 200;\r
779                                 break;\r
780                         case 400:\r
781                                 TOGCNT100N = 40;\r
782                                 TOGCNT1U   = 400;\r
783                                 break;\r
784                         default:\r
785                                 while(1);\r
786                 }\r
787         }\r
788 \r
789         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TOGCNT1U) =    TOGCNT1U;\r
790         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TOGCNT100N) =  TOGCNT100N;\r
791         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TRFC) =        0x00000034;\r
792 \r
793         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TINIT) =       0x000000C8;\r
794         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TRSTH) =       0x00000000;\r
795 \r
796         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TREFI) =       0x00000027;\r
797         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TMRD) =        0x00000005;\r
798 \r
799 \r
800         value_temp = (mem_type_enum == LPDDR2 ) ? 0x00010008 : 00000004 ; //compenstate for clk jitter\r
801         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TRP) =         value_temp;\r
802 \r
803         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TRTW) =        0x00000001; //caution, 1 enough?, xiohui@2012-11-26\r
804         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TAL) =         0x00000000; //no al for lpddr1/lpddr2\r
805 \r
806         value_temp = (mem_type_enum == LPDDR2 ) ? 6 : 3;\r
807         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TCL) =         value_temp;\r
808 \r
809         value_temp = (mem_type_enum == LPDDR2 ) ? 3 : 1;\r
810         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TCWL) =        value_temp;\r
811 \r
812 \r
813         value_temp = (mem_type_enum == LPDDR2 ) ? 0x00000011 : 0x00000008;\r
814         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TRAS) =        value_temp;\r
815         value_temp = (mem_type_enum == LPDDR2 ) ? 0x00000019 : 0x0000000c;\r
816         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TRC) =         value_temp;\r
817 \r
818         value_temp = (mem_type_enum == LPDDR2 ) ? 0x00000006 : 0x00000003; //compenstate for clk jitter\r
819         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TRCD) =        value_temp;\r
820         value_temp = (mem_type_enum == LPDDR2 ) ? 0x00000004 : 0x00000002;\r
821         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TRRD) =        value_temp;\r
822         value_temp = (mem_type_enum == LPDDR2 ) ? 0x00000003 : 0x00000001;\r
823         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TRTP) =        value_temp;\r
824         value_temp = (mem_type_enum == LPDDR2 ) ? 0x00000006 : 0x00000003;\r
825         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TWR) =         value_temp;\r
826 \r
827         //xiaohui change from 3 to 4 due to tWTR=7.5ns whereas clk_emc=2.348ns\r
828         value_temp = (mem_type_enum == LPDDR2 ) ? 0x00000003 : 0x00000002;\r
829         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TWTR) =        value_temp;\r
830         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TEXSR) =       0x00000038;\r
831         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TXP) =         0x00000004;\r
832         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TXPDLL) =      0x00000000;\r
833         //xiaohui change from 0x24 to 0x27 due to tZQCS=90ns whereas clk_emc=2.348ns\r
834         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TZQCS) =       0x00000024;\r
835 \r
836         //value_temp = mem_type_enum == LPDDR2 ? 0x190A4 : 0x0; //assume 0.4s need one calibration, see samsung lpddr2 on page 140\r
837         value_temp = 0x0; //assume 0.4s need one calibration, see samsung lpddr2 on page 140\r
838         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TZQCSI) =      value_temp;\r
839 \r
840         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TDQS) =        0x00000001;\r
841         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TCKSRE) =      0x00000000;\r
842         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TCKSRX) =      0x00000002;\r
843         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TCKE) =        0x00000003;\r
844         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TMOD) =        0x00000000;\r
845         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TRSTL) =       0x00000002;\r
846         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TZQCL) =       0x00000090;\r
847         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TCKESR) =      0x00000006;\r
848         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TDPD) =        0x00000001;\r
849 \r
850         //default value not compatible with real condition\r
851         value_temp = 0x00000011;\r
852         value_temp |= 1 << 8; //addr_map: bank based\r
853         value_temp &= ~(0xf << 2); //density\r
854         value_temp |= 0x1 << 6;   //check:!!dram_type:1: LPDDR2 S4 or MDDR row width 13 and col width 10, 0:    LPDDR2 S2 or MDDR row width 14 and col width 9\r
855         switch (MEM_CS0_TYPE)\r
856         {\r
857                 case MEM_CS_8192MB:\r
858                         value_temp |= (0x7 << 2);\r
859                         break;\r
860                 case MEM_CS_4096MB:\r
861                         value_temp |= (0x6 << 2);\r
862                         break;\r
863                 case MEM_CS_2048MB:\r
864                         value_temp |= (0x5 << 2);\r
865                         break;\r
866                 case MEM_CS_1024MB:\r
867                         value_temp |= (0x4 << 2);\r
868                         break;\r
869                 case MEM_CS_512MB:\r
870                         value_temp |= (0x3 << 2);\r
871                         break;\r
872                 case MEM_CS_256MB:\r
873                         value_temp |= (0x2 << 2);\r
874                         break;\r
875                 case MEM_CS_128MB:\r
876                         value_temp |= (0x1 << 2);\r
877                         break;\r
878                 case MEM_CS_64MB:\r
879                         value_temp |= (0x0 << 2);\r
880                         break;\r
881                 default:\r
882                         value_temp |= (0x6 << 2);\r
883         }\r
884         value_temp |= (mem_width_enum == X32) ? 0x3 :\r
885                 (mem_width_enum == X16) ? 0x2 :\r
886                 0x0;  //dram_io_width\r
887         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DCFG_CS0) = value_temp;\r
888 \r
889         value_temp &= ~(0xf << 2); //density\r
890 \r
891         switch (MEM_CS1_TYPE)\r
892         {\r
893                 case MEM_CS_8192MB:\r
894                         value_temp |= (0x7 << 2);\r
895                         break;\r
896                 case MEM_CS_4096MB:\r
897                         value_temp |= (0x6 << 2);\r
898                         break;\r
899                 case MEM_CS_2048MB:\r
900                         value_temp |= (0x5 << 2);\r
901                         break;\r
902                 case MEM_CS_1024MB:\r
903                         value_temp |= (0x4 << 2);\r
904                         break;\r
905                 case MEM_CS_512MB:\r
906                         value_temp |= (0x3 << 2);\r
907                         break;\r
908                 case MEM_CS_256MB:\r
909                         value_temp |= (0x2 << 2);\r
910                         break;\r
911                 case MEM_CS_128MB:\r
912                         value_temp |= (0x1 << 2);\r
913                         break;\r
914                 case MEM_CS_64MB:\r
915                         value_temp |= (0x0 << 2);\r
916                         break;\r
917                 default:\r
918                         value_temp |= (0x6 << 2);\r
919         }\r
920 \r
921         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DCFG_CS1) = value_temp;\r
922         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFITPHYWRDATA) = 0x00000001;\r
923 \r
924         value_temp = (mem_type_enum == LPDDR2 ) ? 3 : 0; //WL-1, see PUBL P143\r
925         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFITPHYWRLAT) = value_temp;\r
926 \r
927         switch(mem_type_enum)\r
928         {\r
929                 case LPDDR2:\r
930                         {\r
931                                 value_temp = 5;\r
932                                 break;\r
933                         };//??? RL-2, see PUBL P143\r
934                 case LPDDR1:\r
935                         {\r
936                                 value_temp = 1;\r
937                                 break;\r
938                         };\r
939                 default:\r
940                         break;//$stop(2);\r
941         }\r
942         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFITRDDATAEN) = value_temp;\r
943 \r
944         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFITPHYRDLAT) = 0x0000000f;\r
945 \r
946         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFISTCFG0) =   0x00000007;\r
947         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFISTCFG1) =   0x00000003;\r
948         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFISTCFG2) =   0x00000003;\r
949         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFILPCFG0) =   0x00078101; //dfi_lp_wakeup_sr=8\r
950 \r
951         //the priority settings is DSP > Disp > others > GPU\r
952         // so DSP/Disp/Camera are set to LL and all others set to BE\r
953         value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_0);\r
954         value_temp &= ~0xff;\r
955         value_temp &= ~(0xff<<16);\r
956         value_temp |= (0x10 << 16); //quantum\r
957         value_temp |= (0x0 << 7); //rdwr_ordered\r
958         value_temp |= (0x1 << 6); //st_fw_en\r
959         value_temp |= (0x1 << 5); //bp_rd_en, as per the coreconsultant\r
960         value_temp |= (0x1 << 4); //bp_wr_en\r
961         //value_temp[1:0] = 0x3; //qos dynamic mode by port signal\r
962         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_0) =      value_temp;\r
963 \r
964         value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_1);\r
965         value_temp &= ~0xff;\r
966         value_temp &= ~(0xff<<16);\r
967         value_temp |= (0x10 << 16); //quantum\r
968         value_temp |= (0x0 << 7); //rdwr_ordered\r
969         value_temp |= (0x1 << 6); //st_fw_en\r
970         value_temp |= (0x1 << 5); //bp_rd_en, as per the coreconsultant\r
971         value_temp |= (0x1 << 4); //bp_wr_en\r
972         //value_temp[1:0] = 0x3; //qos dynamic mode by port signal\r
973         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_1) =      value_temp;\r
974 \r
975         value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_2);\r
976         value_temp &= ~0xff;\r
977         value_temp &= ~(0xff<<16);\r
978         value_temp |= (0x10 << 16); //quantum\r
979         value_temp |= (0x1 << 7); //rdwr_ordered\r
980         value_temp |= (0x1 << 6); //st_fw_en\r
981         value_temp |= (0x1 << 5); //bp_rd_en, as per the coreconsultant\r
982         value_temp |= (0x1 << 4); //bp_wr_en\r
983         //value_temp[1:0] = 0x3; //qos dynamic mode by port signal\r
984         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_2) =      value_temp;\r
985 \r
986         value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_3);\r
987         value_temp &= ~0xff;\r
988         value_temp &= ~(0xff<<16);\r
989         value_temp |= (0x10 << 16); //quantum\r
990         value_temp |= (0x1 << 7); //rdwr_ordered\r
991         value_temp |= (0x1 << 6); //st_fw_en\r
992         value_temp |= (0x1 << 5); //bp_rd_en, as per the coreconsultant\r
993         value_temp |= (0x1 << 4); //bp_wr_en\r
994         value_temp |= 1;        //qos:LL\r
995         //value_temp[1:0] = 0x3; //qos dynamic mode by port signal\r
996         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_3) =      value_temp;\r
997 \r
998         value_temp = REG32( UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_4);\r
999         value_temp &= ~0xff;\r
1000         value_temp &= ~(0xff<<16);\r
1001         value_temp |= (0x10 << 16); //quantum\r
1002         value_temp |= (0x1 << 7); //rdwr_ordered\r
1003         value_temp |= (0x1 << 6); //st_fw_en\r
1004         value_temp |= (0x1 << 5); //bp_rd_en, as per the coreconsultant\r
1005         value_temp |= (0x1 << 4); //bp_wr_en\r
1006         value_temp |= 0x1;      //qos:LL\r
1007         //value_temp[1:0] = 0x3; //qos dynamic mode by port signal\r
1008         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_4) =      value_temp;\r
1009 \r
1010         value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_5);\r
1011         value_temp &= ~0xff;\r
1012         value_temp &= ~(0xff<<16);\r
1013         value_temp |= (0x10 << 16); //quantum\r
1014         value_temp |= (0x0 << 7); //rdwr_ordered\r
1015         value_temp |= (0x1 << 6); //st_fw_en\r
1016         value_temp |= (0x1 << 5); //bp_rd_en, as per the coreconsultant\r
1017         value_temp |= (0x1 << 4); //bp_wr_en\r
1018         value_temp |= 1;        //qos:LL\r
1019         //value_temp[1:0] = 0x3; //qos dynamic mode by port signal\r
1020         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_5) =      value_temp;\r
1021 \r
1022         value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_6);\r
1023         value_temp &= ~0xff;\r
1024         value_temp &= ~(0xff<<16);\r
1025         value_temp |= (0x10 << 16); //quantum\r
1026         value_temp |= (0x0 << 7); //rdwr_ordered\r
1027         value_temp |= (0x1 << 6); //st_fw_en\r
1028         value_temp |= (0x1 << 5); //bp_rd_en, as per the coreconsultant\r
1029         value_temp |= (0x1 << 4); //bp_wr_en\r
1030         value_temp |= 1;        //qos:LL\r
1031         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_6) =      value_temp;\r
1032 \r
1033         value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_7);\r
1034         value_temp &= ~0xff;\r
1035         value_temp &= ~(0xff<<16);\r
1036         value_temp |= (0x10 << 16); //quantum\r
1037         value_temp |= (0x1 << 7); //rdwr_ordered\r
1038         value_temp |= (0x1 << 6); //st_fw_en\r
1039         value_temp |= (0x1 << 5); //bp_rd_en, as per the coreconsultant\r
1040         value_temp |= (0x1 << 4); //bp_wr_en\r
1041         //value_temp[1:0] = 0x3; //qos dynamic mode by port signal\r
1042         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PCFG_7) =      value_temp;\r
1043 \r
1044         //REG32(PUBL_REG_BASE+PUBL_CFG_ADD_DTAR) = (0x7<<28)|(0x3fff<<12)|(0x3f0<<0);\r
1045         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DTAR) = (0x0 << 28) | (0x0 << 12) | (0x0 << 0);\r
1046 \r
1047         //ZQCR1\r
1048         value_temp = REG32(PUBL_REG_BASE+PUBL_CFG_ADD_ZQ0CR1);\r
1049 \r
1050         switch (MEMORY_TYPE)\r
1051         {\r
1052                 case LPDDR2:\r
1053                         value_temp &= ~(0xf<<4);\r
1054                         break;\r
1055                 case LPDDR1:\r
1056                         value_temp &= ~(0xf<<4);\r
1057                         break;\r
1058                 default:\r
1059                         while(1);\r
1060         }\r
1061         value_temp &= ~0xf;\r
1062         switch (mem_drv)\r
1063         {\r
1064                 case 34:\r
1065                         value_temp |= 0xD;  //output impdence divide select, 7:60ohm 9:48ohm 11:40ohm 13:34ohm\r
1066                         break;\r
1067                 case 40:\r
1068                         value_temp |= 0xB;  //output impdence divide select, 7:60ohm 9:48ohm 11:40ohm 13:34ohm\r
1069                         break;\r
1070                 case 48:\r
1071                         value_temp |= 0x9;  //output impdence divide select, 7:60ohm 9:48ohm 11:40ohm 13:34ohm\r
1072                         break;\r
1073                 case 60:\r
1074                         value_temp |= 0x7;  //output impdence divide select, 7:60ohm 9:48ohm 11:40ohm 13:34ohm\r
1075                         break;\r
1076                 case 80:\r
1077                         value_temp |= 0x5;  //output impdence divide select, 7:60ohm 9:48ohm 11:40ohm 13:34ohm\r
1078                         break;\r
1079                 default:\r
1080                         while(1);\r
1081         }\r
1082 \r
1083         REG32(PUBL_REG_BASE+PUBL_CFG_ADD_ZQ0CR1) = value_temp;\r
1084         value_temp = (8<<18) | (2750<<6) |27;   //per 533MHz\r
1085         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PTR0) = value_temp;\r
1086 \r
1087         //PTR1\r
1088         //value_temp[18:0] = count(200us/clk_emc_period);//CKE high time to first command (200 us)\r
1089         //value_temp[26:19] = don't care;//CKE low time with power and clock stable (100 ns) for lpddr2\r
1090         value_temp = (200 * 1000 * 10) / 25; //CKE high time to first command (200 us)\r
1091         value_temp |= (1000 / 25) << 19; //CKE low time with power and clock stable (100 ns) for lpddr2\r
1092         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PTR1 ) = value_temp;\r
1093 \r
1094         //PTR2\r
1095         //value_temp[16:0] = count((200us_for_ddr3 or 11us_for_lpddr2) /clk_emc_period);\r
1096         //value_temp[26:17] = count(1us/clk_emc_period);\r
1097         switch(mem_type_enum)\r
1098         {\r
1099                 case LPDDR1:\r
1100                         {\r
1101                                 value_temp = 0;\r
1102                                 break;\r
1103                         }\r
1104                 case LPDDR2:\r
1105                         {\r
1106                                 value_temp = (11 * 1000 * 10) / (25);\r
1107                                 break;\r
1108                         }\r
1109                 case DDR3:\r
1110                         {\r
1111                                 value_temp = (200 * 1000 * 10) / (25);\r
1112                                 break;\r
1113                         }\r
1114                 default:\r
1115                         break;\r
1116         }\r
1117         value_temp |= ((1 * 1000 * 10) / 25) << 17;\r
1118         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PTR2 ) = value_temp;\r
1119 \r
1120         //ACIOCR\r
1121         value_temp = (mem_type_enum == LPDDR1)?0x1:0x0;\r
1122         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_ACIOCR, 0, 1, value_temp);\r
1123 \r
1124         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DCR);\r
1125         value_temp &= ~(0x7);\r
1126         value_temp &= ~(0x1 << 3);\r
1127         value_temp &= ~(0x3 << 8);\r
1128         value_temp |= (mem_type_enum == LPDDR2 ) ? 0x4 : 0x0;\r
1129         value_temp |= ( (mem_type_enum == LPDDR2 ) ? 0x1 : 0x0) << 3;\r
1130         value_temp |= 0x00 << 8; //lpddr2-S4?????? xiaohui\r
1131         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DCR) = value_temp;\r
1132 \r
1133         //MR0\r
1134         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_MR0);\r
1135         switch(mem_type_enum)\r
1136         {\r
1137                 case LPDDR2:\r
1138                         {\r
1139                                 value_temp = 0x0; //not applicable\r
1140                                 break;\r
1141                         }\r
1142                 case LPDDR1:\r
1143                         {\r
1144                                 value_temp &= ~(0x7);\r
1145                                 value_temp &= ~(0x1 << 3);\r
1146                                 value_temp &= ~(0x7 << 4);\r
1147                                 value_temp &= ~(0x1 << 7);\r
1148                                 value_temp |= (_LPDDR1_BL_ == 2 ? 0x1 :\r
1149                                         _LPDDR1_BL_ == 4 ? 0x2 :\r
1150                                         _LPDDR1_BL_ == 8 ? 0x3 :\r
1151                                         _LPDDR1_BL_ == 16 ? 0x4 : 0x1);\r
1152                                 value_temp |= (_LPDDR1_BT_ << 3);\r
1153                                 value_temp |= (_LPDDR1_CL_ == 2 ? 0x2 :\r
1154                                         _LPDDR1_CL_ == 3 ? 0x3 :\r
1155                                         _LPDDR1_CL_ == 4 ? 0x4 : 0x3) << 4;\r
1156                                 value_temp |= 0x0 << 7; //normal operation\r
1157                                 break;\r
1158                         }\r
1159                 default:\r
1160                         break;\r
1161         }\r
1162         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_MR0) = value_temp;\r
1163 \r
1164         //MR1\r
1165         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_MR1);\r
1166         switch(mem_type_enum)\r
1167         {\r
1168                 case LPDDR1: {break;}\r
1169                 case LPDDR2:\r
1170                         {\r
1171                                 value_temp &= ~0x7;\r
1172                                 value_temp &= ~(0x3 << 3);\r
1173                                 value_temp &= ~(0x7 << 5);\r
1174                                 value_temp |= (_LPDDR2_BL_ == 4 ? 0x2 :\r
1175                                         _LPDDR2_BL_ == 8 ? 0x3 :\r
1176                                         _LPDDR2_BL_ == 16 ? 0x4 : 0x3);\r
1177                                 value_temp |= _LPDDR2_BT_ << 3;\r
1178                                 value_temp |= _LPDDR2_WC_ << 4;\r
1179                                 value_temp |= (0x4 << 5); //nWR=6 //!check\r
1180                                 break;\r
1181                         }\r
1182                 default:\r
1183                         break;\r
1184         }\r
1185         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_MR1) = value_temp;\r
1186 \r
1187         //MR2\r
1188         switch(mem_type_enum)\r
1189         {\r
1190                 case LPDDR1:\r
1191                         {\r
1192                                 value_temp = 0x0;    //extend mode\r
1193                                 break;\r
1194                         }\r
1195                 case LPDDR2:\r
1196                         {\r
1197                                 value_temp = 0x4;    //RL = 6 / WL = 3\r
1198                                 break;\r
1199                         }\r
1200                 default:\r
1201                         break;\r
1202         }\r
1203         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_MR2) = value_temp;\r
1204 \r
1205         //MR3\r
1206         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_MR3);\r
1207         value_temp &= ~0xf;\r
1208         value_temp |= 0x2;\r
1209         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_MR3) = value_temp;\r
1210 \r
1211         //ODTCR. disable ODT for wrtie and read for LPDDR2/LPDDR1\r
1212         value_temp = REG32(PUBL_REG_BASE+PUBL_CFG_ADD_ODTCR);\r
1213         switch(MEMORY_TYPE)\r
1214         {\r
1215                 case LPDDR1:\r
1216                         value_temp &= ~0xff;\r
1217                         value_temp &= ~(0xff<<16);\r
1218                         break;\r
1219                 case LPDDR2:\r
1220                         value_temp &= ~0xff;\r
1221                         value_temp &= ~(0xff<<16);\r
1222                         break;\r
1223                 default:\r
1224                         while(1);\r
1225         }\r
1226         REG32(PUBL_REG_BASE+PUBL_CFG_ADD_ODTCR) = value_temp;\r
1227 \r
1228         //DTPR0\r
1229         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DTPR0);\r
1230         switch(mem_type_enum)\r
1231         {\r
1232                 case LPDDR1:\r
1233                         {\r
1234                                 //value_temp[1:0] = 2;    //tMRD\r
1235                                 //value_temp[4:2] = 2;    //tRTP\r
1236                                 //value_temp[7:5] = (mem_type_enum == LPDDR2 ) ? 0x00000004: 0x00000002;\r
1237                                 //value_temp[11:8] = 4;    //tRP\r
1238                                 //value_temp[15:12] = 4;    //tRCD\r
1239                                 //value_temp[20:16] = 8;    //tRAS\r
1240                                 //value_temp[24:21] = 2;    //tRRD\r
1241                                 //value_temp[30:25] = 12;    //tRC\r
1242                                 //value_temp[31] = 0x0;    //tCCD: BL/2\r
1243                                 value_temp = (0x0 << 31) | (12 << 25) | (2 << 21) | (8 << 16) | (4 << 12) | (4 << 8) | (2 << 2) | (2);\r
1244                                 value_temp |= 0x00000002 << 5; //tWTR\r
1245                                 break;\r
1246                         }\r
1247                 case LPDDR2:\r
1248                         {\r
1249                                 value_temp = 0x36916a6d;//??? xiaohui\r
1250                                 break;\r
1251                         }\r
1252                 default:{while(1);}\r
1253         }\r
1254         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DTPR0) = value_temp;\r
1255 \r
1256         //DTPR1\r
1257         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DTPR1);\r
1258         value_temp &= ~0x3;\r
1259         value_temp &= ~(0xff << 16);\r
1260         switch(mem_type_enum)\r
1261         {\r
1262                 case LPDDR1:\r
1263                         {\r
1264                                 value_temp |= 0x1; //same with lpddr2 to avoid additional code size\r
1265                                 value_temp |= (32 << 16);  //tRFC\r
1266                                 break;\r
1267                         }\r
1268                 case LPDDR2:\r
1269                         {\r
1270                                 value_temp = 0x193400a0;//??? xiaohui\r
1271                                 break;\r
1272                         }\r
1273                 default:\r
1274                         break;\r
1275         }\r
1276         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DTPR1) = value_temp;\r
1277 \r
1278         //DTPR2\r
1279         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DTPR2);\r
1280         switch(mem_type_enum)\r
1281         {\r
1282                 case LPDDR1:\r
1283                                 break;\r
1284                 case LPDDR2:\r
1285                         {\r
1286                                 value_temp = 0x1001a0c8; //actually is default value\r
1287                                 break;\r
1288                         }\r
1289                 default:\r
1290                         break;\r
1291         }\r
1292         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DTPR2) = value_temp;\r
1293 \r
1294         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DXCCR);\r
1295         value_temp &= ~(0x1 << 1);\r
1296         value_temp &= ~(0xf << 4);\r
1297         value_temp &= ~(0xf << 8);\r
1298         value_temp &= ~(0x1 << 14);\r
1299         value_temp |= ((mem_type_enum == LPDDR1 ) ? 0x1 : 0x0) << 1; //iom. 0:LPDDR1, 1: others\r
1300         value_temp |= (((mem_type_enum == LPDDR2)|(mem_type_enum==LPDDR1)) ?   (DQSR_VALUE) : 0x0) << 4; //pull down resistor for DQS\r
1301         value_temp |= (((mem_type_enum == LPDDR2)|(mem_type_enum==LPDDR1)) ? (8|DQSR_VALUE) : 0x0) << 8; //pull down resistor for DQS_N\r
1302         value_temp |= ((mem_type_enum == LPDDR2 ) ? 0x0 : 0x1) << 14; //DQS# Reset\r
1303         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DXCCR) = value_temp;\r
1304 \r
1305         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DX0GCR);\r
1306         value_temp&=~((0x3<<9)|(1<<3)); //disable DQ/DQS Dynamic RTT Control\r
1307         value_temp|= ((mem_type_enum == LPDDR1)?0x1:0x0)<<3;\r
1308         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DX0GCR) = value_temp;\r
1309 \r
1310         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DX1GCR);\r
1311         value_temp&=~((0x3<<9)|(1<<3));   //disable DQ/DQS Dynamic RIT Control\r
1312         value_temp|= ((mem_type_enum == LPDDR1)?0x1:0x0)<<3;\r
1313         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DX1GCR) = value_temp;\r
1314 \r
1315         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DX2GCR);\r
1316         value_temp&=~((0x3<<9)|(1<<3));   //disable DQ/DQS Dynamic RIT Control\r
1317         value_temp|= ((mem_type_enum == LPDDR1)?0x1:0x0)<<3;\r
1318         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DX2GCR) = value_temp;\r
1319 \r
1320         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DX3GCR);\r
1321         value_temp&=~((0x3<<9)|(1<<3));   //disable DQ/DQS Dynamic RIT Control\r
1322         value_temp|= ((mem_type_enum == LPDDR1)?0x1:0x0)<<3;\r
1323         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DX3GCR) = value_temp;\r
1324 \r
1325         value_temp = (0 << 30) | (0x7fff << 13) | (0x7 << 10) | (0x300);\r
1326         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DTUWACTL) = value_temp;\r
1327         value_temp = (0 << 30) | (0x7fff << 13) | (0x7 << 10) | (0x300);\r
1328         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DTURACTL) = value_temp;\r
1329 \r
1330         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PGCR);\r
1331         value_temp &= ~0x7;\r
1332         value_temp &= ~(0xf << 18);\r
1333         value_temp |= (mem_type_enum == LPDDR2 ) ? 0x0 : 0x1; //0 = ITMS uses DQS and DQS#\r
1334         //1 = ITMS uses DQS only\r
1335         value_temp |= (0x1 << 1);\r
1336         if (MEM_CS1_TYPE == MEM_CS_0MB)\r
1337         {\r
1338                 value_temp |= (0x1<<18); //only enable CS0 for data training\r
1339         }\r
1340         else\r
1341         {\r
1342                 value_temp |= (0x3 << 18); //enable CS0/1 for data training\r
1343         }\r
1344         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PGCR) = value_temp;\r
1345 \r
1346         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DSGCR);\r
1347         value_temp &= ~0xfff;  //only applicable for LPDDR\r
1348 \r
1349         //CAUTION:[7:5] DQSGX, [10:8] DQSGE\r
1350         value_temp |= (0x1f | ((GATE_EARLY_LATE)<<8) | ((GATE_EARLY_LATE)<<5));  //only applicable for LPDDR\r
1351         value_temp &= ~(0x1<<2); // zq Update Enable,CHECK!!!!\r
1352         value_temp &= ~(0x1<<4); // Low Power DLL Power Down\r
1353         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DSGCR) = value_temp;\r
1354 } //emc_init_common_reg\r
1355 \r
1356 //all cs are initialized simultaneously\r
1357 void mem_init(MEM_TYPE_ENUM mem_type_enum, uint32 bl, MEM_BT_ENUM bt, uint32 zq)\r
1358 {\r
1359         uint32  value_temp, i;\r
1360         uint32  mode_ba;\r
1361         uint32  mode_a;\r
1362         switch(mem_type_enum)\r
1363         {\r
1364                 case LPDDR1:   //{{{\r
1365                 {\r
1366                         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD) = 0x85f04001;\r
1367                         do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1368                         while((value_temp & 0x80000000) != 0x0);\r
1369 \r
1370                         for(i = 0; i < 2; i++)\r
1371                         {\r
1372                                 REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD) = 0x85f04002;\r
1373                                 do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1374                                 while((value_temp & 0x80000000) != 0x0);\r
1375                         }\r
1376 \r
1377                         if(bl == 8 & bt == SEQ)\r
1378                         {\r
1379                                 while(1);\r
1380                         }\r
1381                         mode_ba = 0x0;\r
1382                         mode_a = bl == 2 ? 0x1 :\r
1383                                 bl == 4 ? 0x2 :\r
1384                                 bl == 8 ? 0x3 :\r
1385                                 bl == 16 ? 0x4 : 0x1;\r
1386                         mode_a |= bt << 3;\r
1387                         mode_a |= (_LPDDR1_CL_ == 2 ? 0x2 :\r
1388                                 _LPDDR1_CL_ == 3 ? 0x3 :\r
1389                                 _LPDDR1_CL_ == 4 ? 0x4 : 0x3) << 4;\r
1390                         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD) = 0x85f00003 | (mode_ba << 17) | (mode_a << 4);\r
1391                         do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1392                         while((value_temp & 0x80000000) != 0x0);\r
1393 \r
1394                         mode_ba = 0x2;\r
1395                         mode_a = 0x0;\r
1396                         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD) = 0x85f00003 | (mode_ba << 17) | (mode_a << 4);\r
1397                         do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1398                         while((value_temp & 0x80000000) != 0x0);\r
1399                         \r
1400                         break;\r
1401                 }\r
1402                 case LPDDR2:\r
1403                 {\r
1404                         //This register provides software with a method to program memory commands to the memory devices for\r
1405                         //initialization and mode register programming through the direct memory command channel. Writes to this\r
1406                         //register are ignored when MCMD[31] is set to 0x1, poll bit[31] to determine when uPCTL is ready\r
1407                         //to accept another command.\r
1408                         //MR63: reset memory\r
1409                         REG32(UMCTL_REG_BASE  + UMCTL_CFG_ADD_MCMD) = 0x89fee3f3;\r
1410                         do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1411                         while((value_temp & 0x80000000) != 0x0);\r
1412 \r
1413                         #if 1//must be followed in board test\r
1414                         //for (i=0; i<11000; i++); //tINIT5+tINIT4, at least 11us\r
1415                         wait_n_pclk_cycle(11*1000/25);\r
1416                         #endif\r
1417 \r
1418                         //MR10: I/O calibration\r
1419                         REG32(UMCTL_REG_BASE  + UMCTL_CFG_ADD_MCMD) = 0x891ff0a3;\r
1420                         do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1421                         while((value_temp & 0x80000000) != 0x0);\r
1422                         wait_n_pclk_cycle(40);\r
1423 \r
1424                         //MR10: I/O calibration\r
1425                         REG32(UMCTL_REG_BASE  + UMCTL_CFG_ADD_MCMD) = 0x892ff0a3;\r
1426                         do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1427                         while((value_temp & 0x80000000) != 0x0);\r
1428                         //for (i=0; i<1000;i++);\r
1429                         wait_n_pclk_cycle(40);\r
1430 \r
1431                         if(bl == 8 && bt == SEQ)\r
1432                         {\r
1433                                 while(1);\r
1434                         }\r
1435                         //MR01: Device feature 1\r
1436                         value_temp = 0x80f00013;\r
1437                         value_temp |= (bl == 4 ? 0x2 :\r
1438                                 bl == 8 ? 0x3 :\r
1439                                 bl == 16 ? 0x4 : 0x3) << 12;\r
1440                         value_temp |= bt << 15;\r
1441                         value_temp |= _LPDDR2_WC_ << 16;\r
1442                         value_temp |= 4 << 17; //nWR=6 for Auto precharge\r
1443                         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD) = value_temp;\r
1444                         do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1445                         while((value_temp & 0x80000000) != 0x0);\r
1446 \r
1447                         //MR02: Device feature 2\r
1448                         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD) = 0x80f04023;\r
1449                         do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1450                         while((value_temp & 0x80000000) != 0x0);\r
1451 \r
1452                         //MR03: I/O config-1. DS: 40 ohm typical (default)\r
1453                         value_temp = 0x80f02030;\r
1454                         switch (zq)\r
1455                         {\r
1456                                 case 34:\r
1457                                         value_temp |= 0x1<<12;\r
1458                                         break;\r
1459                                 case 40:\r
1460                                         value_temp |= 0x2<<12;\r
1461                                         break;\r
1462                                 case 48:\r
1463                                         value_temp |= 0x3<<12;\r
1464                                         break;\r
1465                                 case 60:\r
1466                                         value_temp |= 0x4<<12;\r
1467                                         break;\r
1468                                 case 80:\r
1469                                         value_temp |= 0x6<<12;\r
1470                                         break;\r
1471                                 default:\r
1472                                         while(1);\r
1473                         }\r
1474                         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD) = value_temp;\r
1475                         do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1476                         while((value_temp & 0x80000000) != 0x0);\r
1477 \r
1478                         //refresh\r
1479                         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD) = 0x80f00002;\r
1480                         do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1481                         while((value_temp & 0x80000000) != 0x0);\r
1482                         \r
1483                         break;\r
1484                 }\r
1485                 default:{while(1);}\r
1486         }\r
1487 }\r
1488 \r
1489 static void __emc_init(uint32 mem_drv)\r
1490 {\r
1491         uint32 value_temp, i;\r
1492         MEM_TYPE_ENUM mem_type_enum;\r
1493         MEM_WIDTH_ENUM mem_width_enum;\r
1494         mem_type_enum = MEMORY_TYPE;\r
1495         mem_width_enum = MEM_WIDTH;\r
1496 \r
1497         if (1)\r
1498         {\r
1499                 value_temp  = REG32(0x4B000080);\r
1500                 value_temp |= (0x1<<1);\r
1501                 REG32(0x4B000080) = value_temp;\r
1502         }\r
1503 \r
1504         //value_temp = REG32(0x2090_0308);\r
1505         //value_temp[9] = 0x1;\r
1506         //REG32_WR(0x2090_0308,value_temp);\r
1507 \r
1508         emc_init_common_reg(mem_type_enum, mem_width_enum, mem_drv);\r
1509 #if SOFTWARE_ENABLE_VREF\r
1510         polling_reg_bit_field(PUBL_REG_BASE+PUBL_CFG_ADD_PGSR, 0, 3, 7);//confirm zqcal done, because later will trigger it\r
1511 #endif\r
1512         //for LPDDR1, Vref is initially shut down, So zq calibration must be explicitly triggered by software\r
1513         //otherwise ouput impedance will have uncorrect value, thus marking DDR signals not toggling\r
1514         if (mem_type_enum == LPDDR1)\r
1515         {\r
1516 #if 0\r
1517                 {\r
1518                         REG32(PUBL_REG_BASE+PUBL_CFG_ADD_ZQ0CR0) = (1<<30);\r
1519                         for (i=0; i<=150; i++);\r
1520                         polling_reg_bit_field(PUBL_REG_BASE+PUBL_CFG_ADD_ZQ0CR0, 30, 1, 0);\r
1521                         value_temp = REG32(PUBL_REG_BASE+PUBL_CFG_ADD_ZQ0SR0);\r
1522                         if ((value_temp&0x0000001f) == 0x00000000)\r
1523                         {\r
1524                                 while(1);\r
1525                         }\r
1526                         if ((value_temp&0x000003e0) == 0x00000000)\r
1527                         {\r
1528                                 while(1);\r
1529                         }\r
1530                 }\r
1531 #endif\r
1532 #if SOFTWARE_ENABLE_VREF\r
1533                 {\r
1534                         value_temp = 0x9;\r
1535                         REG32(PUBL_REG_BASE+PUBL_CFG_ADD_PIR) = value_temp;\r
1536                         //according to PUBL databook on PIR operation.\r
1537                         //10 configuration clock cycle must be waited before polling PGSRi\r
1538                         for (i=0; i<=150; i++);\r
1539                         polling_reg_bit_field(PUBL_REG_BASE+PUBL_CFG_ADD_PGSR, 0, 1, 1); //init done\r
1540                         polling_reg_bit_field(PUBL_REG_BASE+PUBL_CFG_ADD_PGSR, 2, 1, 1); //zcal done\r
1541                         value_temp = REG32(PUBL_REG_BASE+PUBL_CFG_ADD_ZQ0SR0);\r
1542                         if ((value_temp & 0x0000001f) == 0x00000000)\r
1543                         {\r
1544                                 while(1); //zcal error must be 0\r
1545                         }\r
1546                         if ((value_temp & 0x000003e0) == 0x00000000)\r
1547                         {\r
1548                                 while(1); //zcal error must be 0\r
1549                         }\r
1550                 }\r
1551 #endif\r
1552         }\r
1553 \r
1554         value_temp = 0x9;\r
1555         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PIR) = value_temp;\r
1556         wait_n_pclk_cycle(5);\r
1557         for (i=0; i<100; i++);\r
1558         do value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PGSR);\r
1559         while((value_temp & 0x1) == 0);\r
1560 \r
1561         value_temp = (0x1<<18)|0x1; //Controller DRAM Initialization\r
1562         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PIR) = value_temp;\r
1563 \r
1564         //according to PUBL databook on PIR operation.\r
1565         //10 configuration clock cycle must be waited before polling PGSRi\r
1566         wait_n_pclk_cycle(5);\r
1567         do value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PGSR); \r
1568         while((value_temp & 0x1) == 0);\r
1569 \r
1570         //check dfi init complete\r
1571         do\r
1572         {\r
1573                 value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFISTSTAT0);\r
1574         } while((value_temp & 0x1) == 0);\r
1575 \r
1576         //Start the memory power up sequence\r
1577         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_POWCTL) = 0x00000001;\r
1578 \r
1579         //Returns the status of the memory power-up sequence\r
1580         do\r
1581         {\r
1582                 value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_POWSTAT);\r
1583         } while((value_temp & 0x1) == 0);\r
1584         //mem_init(mem_type_enum); //OK\r
1585         switch(mem_type_enum)\r
1586         {\r
1587                 case LPDDR1:\r
1588                         mem_init(mem_type_enum, _LPDDR1_BL_, _LPDDR1_BT_, mem_drv);\r
1589                         break;\r
1590                 case LPDDR2:\r
1591                         mem_init(mem_type_enum, _LPDDR2_BL_, _LPDDR2_BT_, mem_drv);\r
1592                         break;\r
1593         }\r
1594 \r
1595         move_upctl_state_to_config();\r
1596 #if GATE_TRAING_ON\r
1597         emc_publ_do_gate_training();\r
1598 #endif\r
1599         //disable emc auto self-refresh\r
1600         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_SCFG) = 0x00000421;\r
1601         move_upctl_state_to_access();\r
1602 }\r
1603 \r
1604 void emc_init_repowered(uint32 power_off)\r
1605 {\r
1606         uint32  value_temp, i;\r
1607         uint32  value_temp1;\r
1608         MEM_TYPE_ENUM mem_type_enum;\r
1609         MEM_WIDTH_ENUM mem_width_enum;\r
1610         mem_width_enum = MEM_WIDTH;\r
1611         //MEM_DENSITY_ENUM mem_density_enum;\r
1612         mem_type_enum = MEMORY_TYPE;\r
1613 \r
1614         //cfg clk emc to 200MHz if lpddr1\r
1615         //it must use AHB to config\r
1616 \r
1617         value_temp = REG32(0x4B000080);\r
1618         value_temp |= 0x1 << 1;\r
1619         REG32(0x4B000080) = value_temp;\r
1620 \r
1621         move_upctl_state_to_config();\r
1622 \r
1623         //value_temp = REG32(0x2090_0308);\r
1624         //value_temp[9] = 0x1;\r
1625         //REG32(0x2090_0308) = value_temp;\r
1626         if (power_off)\r
1627         {\r
1628                 emc_init_common_reg(mem_type_enum, mem_width_enum, SC8825_EMC_DRV);\r
1629         }\r
1630 \r
1631         do  value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PGSR);\r
1632         while((value_temp & 0x1) == 0);\r
1633 \r
1634         value_temp = 0x0;\r
1635         value_temp |= 1 << 30; //ZCALBYP\r
1636         value_temp |= 1 << 18; //Controller DRAM Initialization\r
1637         value_temp |= 1;\r
1638         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PIR) = value_temp;\r
1639 \r
1640         //according to PUBL databook on PIR operation.\r
1641         //10 configuration clock cycle must be waited before polling PGSR\r
1642         wait_n_pclk_cycle(5);\r
1643 \r
1644         do value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PGSR);\r
1645         while((value_temp & 0x1) == 0);\r
1646 \r
1647         do value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFISTSTAT0);\r
1648         while((value_temp & 0x1) == 0);\r
1649 \r
1650         /*\r
1651         do\r
1652         {\r
1653                 value_temp = REG32(UMCTL_REG_BASE+UMCTL_CFG_ADD_DFISTSTAT0);\r
1654         } while((value_temp&1)==0);\r
1655         REG32(UMCTL_REG_BASE+UMCTL_CFG_ADD_POWCTL)=1;\r
1656         do\r
1657         {\r
1658                 value_temp = REG32(UMCTL_REG_BASE+UMCTL_CFG_ADD_POWSTAT);\r
1659         } while((value_temp&1)==0);\r
1660         */\r
1661 \r
1662         value_temp1 = REG32(0x20900260);  //read the pre-retention value\r
1663         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_ZQ0CR0);\r
1664         value_temp &= ~0xfffff;\r
1665         value_temp &= ~(0x1 << 28);\r
1666         value_temp |= 1 << 28;\r
1667         value_temp |= (value_temp1 & 0xfffff);\r
1668         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_ZQ0CR0) = value_temp;\r
1669 \r
1670         if (power_off == 0x0)\r
1671         {\r
1672                 move_upctl_state_to_low_power();\r
1673         }\r
1674 \r
1675         value_temp = REG32(0x4B000080);\r
1676         value_temp &= ~(0x1 << 2);\r
1677         value_temp |= 0x1 << 2;\r
1678         REG32(0x4B000080) = value_temp;\r
1679         value_temp &= ~(0x1 << 2);\r
1680         REG32(0x4B000080) = value_temp;\r
1681 \r
1682         value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_ZQ0CR0);\r
1683         value_temp   &= ~(0x1 << 28);\r
1684         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_ZQ0CR0) = value_temp;\r
1685 \r
1686         if (ZQ_CALIBRE_DPSLEEP)\r
1687         {\r
1688                 value_temp = 0x1 | (0x1 << 3);\r
1689                 REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PIR) = value_temp;\r
1690                 for(i = 0; i < 100; i++) {}\r
1691                 do value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PGSR);\r
1692                 while((value_temp & 0x1) == 0);\r
1693         }\r
1694 \r
1695         value_temp = 0x1 | (0x1 << 18); //Controller DRAM Initialization\r
1696         REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PIR) = value_temp;\r
1697         for(i = 0; i < 100; i++) {}\r
1698         do value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PGSR);\r
1699         while((value_temp & 0x1) == 0);\r
1700 \r
1701         //first move upctl to low power state before issuing wakeup command\r
1702         if (power_off)\r
1703         {\r
1704                 move_upctl_state_to_low_power();\r
1705         }\r
1706         move_upctl_state_to_access();\r
1707         move_upctl_state_to_config();\r
1708         if (power_off)\r
1709                 emc_publ_do_gate_training();\r
1710 \r
1711         //disable emc auto self-refresh\r
1712         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_SCFG) = 0x00000421;\r
1713         move_upctl_state_to_access();\r
1714 }\r
1715 \r
1716 static void precharge_all_bank(void)\r
1717 {\r
1718         //all cs be precharged\r
1719         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD) = 0x85f00001;\r
1720 }\r
1721 \r
1722 static void load_mode(MEM_TYPE_ENUM mem_type_enum, uint32 bl, MEM_BT_ENUM bt)\r
1723 {\r
1724         uint32  mode_ba, mode_a;\r
1725         uint32  value_temp;\r
1726         switch(mem_type_enum)\r
1727         {\r
1728                 case LPDDR1:\r
1729                 {\r
1730                         if(bl == 8 & bt == SEQ)\r
1731                         {\r
1732                                 while(1);\r
1733                         }\r
1734                         mode_ba = 0x0;\r
1735                         mode_a = (bl == 2 ? 0x1 :\r
1736                                 bl == 4 ? 0x2 :\r
1737                                 bl == 8 ? 0x3 :\r
1738                                 bl == 16 ? 0x4 : 0x1);\r
1739                         mode_a |= bt << 3;\r
1740                         mode_a |= (_LPDDR1_CL_ == 2 ? 0x2 :\r
1741                                 _LPDDR1_CL_ == 3 ? 0x3 :\r
1742                                 _LPDDR1_CL_ == 4 ? 0x4 : 0x3) << 4;\r
1743                         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD) = 0x85f00003 | (mode_ba << 17) | (mode_a << 4);\r
1744                         do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1745                         while((value_temp & 0x80000000) != 0x0);\r
1746                         break;\r
1747                 }\r
1748                 case LPDDR2:\r
1749                 {\r
1750                         if(bl == 8 && bt == SEQ)\r
1751                         {\r
1752                                 while(1);\r
1753                         }\r
1754                         //MR01: Device feature 1\r
1755                         value_temp = 0x80f00013;\r
1756                         value_temp = (bl == 4 ? 0x2 :\r
1757                                 bl == 8 ? 0x3 :\r
1758                                 bl == 16 ? 0x4 : 0x3) << 12;\r
1759                         value_temp |= bt << 15;\r
1760                         value_temp |= _LPDDR2_WC_ << 16;\r
1761                         value_temp |= 4 << 17; //nWR=6 for Auto precharge\r
1762                         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD) = value_temp;\r
1763                         do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1764                         while((value_temp & 0x80000000) != 0x0);\r
1765 \r
1766                         //MR02: Device feature 2\r
1767                         REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD) = 0x80f04023;\r
1768                         do  value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD);\r
1769                         while((value_temp & 0x80000000) != 0x0);\r
1770                         break;\r
1771                 }\r
1772                 default:\r
1773                         break;\r
1774         }\r
1775 }\r
1776 \r
1777 static void disable_clk_emc()\r
1778 {\r
1779         modify_reg_field(ADDR_AHBREG_AHB_CTRL0, 28, 1, 0);\r
1780 }\r
1781 \r
1782 static void enable_clk_emc()\r
1783 {\r
1784         modify_reg_field(ADDR_AHBREG_AHB_CTRL0, 28, 1, 1);\r
1785 }\r
1786 \r
1787 static void assert_reset_acdll()\r
1788 {\r
1789         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_ACDLLCR, 30, 1, 0);\r
1790 }\r
1791 \r
1792 static void deassert_reset_acdll()\r
1793 {\r
1794         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_ACDLLCR, 30, 1, 1);\r
1795 }\r
1796 \r
1797 static void assert_reset_dxdll()\r
1798 {\r
1799         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX0DLLCR, 30, 1, 0);\r
1800         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX1DLLCR, 30, 1, 0);\r
1801         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX2DLLCR, 30, 1, 0);\r
1802         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX3DLLCR, 30, 1, 0);\r
1803 }\r
1804 \r
1805 static void deassert_reset_dxdll()\r
1806 {\r
1807         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX0DLLCR, 30, 1, 1);\r
1808         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX1DLLCR, 30, 1, 1);\r
1809         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX2DLLCR, 30, 1, 1);\r
1810         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX3DLLCR, 30, 1, 1);\r
1811 }\r
1812 \r
1813 static void assert_reset_ddrphy_dll()\r
1814 {\r
1815         assert_reset_acdll();\r
1816         assert_reset_dxdll();\r
1817 }\r
1818 \r
1819 static void deassert_reset_ddrphy_dll()\r
1820 {\r
1821         deassert_reset_acdll();\r
1822         deassert_reset_dxdll();\r
1823 }\r
1824 \r
1825 static void modify_dpll_freq(uint32 freq)\r
1826 {\r
1827         uint32 temp;\r
1828         modify_reg_field(GLB_REG_WR_REG_GEN1, 9, 1, 1);\r
1829         temp = (freq >> 2);\r
1830         modify_reg_field(GLB_REG_DPLL_CTRL, 0, 11, temp);\r
1831         modify_reg_field(GLB_REG_WR_REG_GEN1, 9, 1, 0);\r
1832 }\r
1833 \r
1834 \r
1835 static void modify_emc_clk(uint32 freq)\r
1836 {\r
1837         disable_clk_emc();\r
1838         assert_reset_acdll();\r
1839         assert_reset_dxdll();\r
1840         modify_dpll_freq(freq);\r
1841 \r
1842         modify_reg_field(ADDR_AHBREG_ARMCLK, 12, 2, 1);\r
1843         modify_reg_field(ADDR_AHBREG_ARMCLK, 8, 4, 0);  //clk emc div 0\r
1844         modify_reg_field(ADDR_AHBREG_ARMCLK, 3, 1, 1);  //clk emc sync\r
1845         \r
1846         wait_us(150);\r
1847 \r
1848         enable_clk_emc();\r
1849         deassert_reset_acdll();\r
1850         deassert_reset_dxdll();\r
1851         wait_us(10);\r
1852 }\r
1853 \r
1854 static void reset_ddrphy_dll()\r
1855 {\r
1856         disable_clk_emc();\r
1857         assert_reset_acdll();\r
1858         assert_reset_dxdll();\r
1859 \r
1860         enable_clk_emc();\r
1861         deassert_reset_acdll();\r
1862         deassert_reset_dxdll();\r
1863         wait_us(10);\r
1864 }\r
1865 \r
1866 static void modify_dxndll_phase_trim(uint32 dxn, uint32 phase)\r
1867 {\r
1868         uint32 phase_dec;\r
1869         uint32 publ_cfg_dxndllcr_addr, i;\r
1870         publ_cfg_dxndllcr_addr = PUBL_REG_BASE+PUBL_CFG_ADD_DX0DLLCR + (0x10*4*dxn);\r
1871         switch(phase)\r
1872         {\r
1873                 case 36:\r
1874                         phase_dec = 3;\r
1875                         break; \r
1876                 case 54:\r
1877                         phase_dec = 2;\r
1878                         break; \r
1879                 case 72:\r
1880                         phase_dec = 1;\r
1881                         break; \r
1882                 case 90:\r
1883                         phase_dec = 0;\r
1884                         break; \r
1885                 case 108:\r
1886                         phase_dec = 4;\r
1887                         break; \r
1888                 case 126:\r
1889                         phase_dec = 8;\r
1890                         break; \r
1891                 case 144:\r
1892                         phase_dec = 12;\r
1893                         break; \r
1894                 default:\r
1895                         while(1);\r
1896         }\r
1897         modify_reg_field(publ_cfg_dxndllcr_addr, 14, 4, phase_dec);\r
1898         modify_reg_field(publ_cfg_dxndllcr_addr, 30, 1, 0);\r
1899         \r
1900         wait_100ns();\r
1901         modify_reg_field(publ_cfg_dxndllcr_addr, 30, 1, 1);\r
1902         if (0)\r
1903         {\r
1904                 wait_n_pclk_cycle(10*1000/25);\r
1905         }\r
1906         else\r
1907         {\r
1908                 polling_reg_bit_field(PUBL_REG_BASE+PUBL_CFG_ADD_PGSR, 0, 1, 1);\r
1909                 REG32(PUBL_REG_BASE+PUBL_CFG_ADD_PIR) = 0x5;\r
1910                 wait_n_pclk_cycle(5);\r
1911                 polling_reg_bit_field(PUBL_REG_BASE+PUBL_CFG_ADD_PGSR, 2, 1, 1);\r
1912         }\r
1913 }\r
1914 \r
1915 static void modify_dxndqstr_delay_trim(uint32 dxn, uint32 trim_value)\r
1916 {\r
1917         uint32 publ_cfg_dxndllcr_addr, i;\r
1918         publ_cfg_dxndllcr_addr = PUBL_REG_BASE+PUBL_CFG_ADD_DX0DLLCR+(0x10*4*dxn);\r
1919         if (trim_value > 7)\r
1920                 while(1);\r
1921         switch(dxn)\r
1922         {\r
1923                 case 0:\r
1924                         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX0DQSTR, 20, 3, trim_value);\r
1925                         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX0DQSTR, 22, 3, trim_value);\r
1926                         break;\r
1927                 case 1:\r
1928                         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX1DQSTR, 20, 3, trim_value);\r
1929                         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX1DQSTR, 22, 3, trim_value);\r
1930                         break;\r
1931                 case 2:\r
1932                         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX2DQSTR, 20, 3, trim_value);\r
1933                         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX2DQSTR, 22, 3, trim_value);\r
1934                         break;\r
1935                 case 3:\r
1936                         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX3DQSTR, 20, 3, trim_value);\r
1937                         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_DX3DQSTR, 22, 3, trim_value);\r
1938                         break;\r
1939                 default:\r
1940                         while(1);\r
1941         }\r
1942         modify_reg_field(publ_cfg_dxndllcr_addr, 30, 1, 0);\r
1943         wait_100ns();\r
1944         modify_reg_field(publ_cfg_dxndllcr_addr, 30, 1, 1);\r
1945         if (0)\r
1946         {\r
1947                 wait_n_pclk_cycle(10*1000/25);\r
1948         }\r
1949         else\r
1950         {\r
1951                 polling_reg_bit_field(PUBL_REG_BASE+PUBL_CFG_ADD_PGSR, 0, 1, 1);\r
1952                 REG32(PUBL_REG_BASE+PUBL_CFG_ADD_PIR) = 0x5;\r
1953                 wait_n_pclk_cycle(5);\r
1954                 polling_reg_bit_field(PUBL_REG_BASE+PUBL_CFG_ADD_PGSR, 2, 1, 1);\r
1955         }\r
1956 }\r
1957 \r
1958 static void publ_do_itmsrst()\r
1959 {\r
1960         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_PIR, 4, 1, 1);\r
1961         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_PIR, 0, 1, 1);\r
1962         polling_reg_bit_field(PUBL_REG_BASE+PUBL_CFG_ADD_PIR, 0, 1, 0);\r
1963 }\r
1964 \r
1965 static void publ_do_bist_stop()\r
1966 {\r
1967         uint32 i;\r
1968         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR, 0, 3, 2);\r
1969         for (i=0; i<24; i++);\r
1970 }\r
1971 \r
1972 static void publ_do_bist_reset()\r
1973 {\r
1974         uint32 i;\r
1975         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR, 0, 3, 3);\r
1976         for (i=0; i<24; i++);\r
1977 }\r
1978 \r
1979 static void publ_record_bistgsr(uint32 result_addr)\r
1980 {\r
1981         uint32 value_temp, addr;\r
1982         value_temp = 0;\r
1983         addr = result_addr + (1<<10);\r
1984         while ((value_temp & 0x1) == 0)\r
1985                 value_temp = REG32(PUBL_REG_BASE+PUBL_CFG_ADD_BISTGSR);\r
1986         REG32(result_addr) = value_temp;\r
1987 \r
1988         if (value_temp == 0x1)\r
1989                 REG32(addr) = 0x0000ba55;\r
1990         else\r
1991                 REG32(addr) = 0x0000fa11;\r
1992 }\r
1993 \r
1994 static void publ_set_dqs_phase_trim_to_norminal(uint32 dxn)\r
1995 {\r
1996         uint32 publ_dxn_cfg_dxndllcr_addr;\r
1997         uint32 publ_dxn_cfg_dxndqstr_addr;\r
1998         uint32 i;\r
1999         \r
2000         publ_dxn_cfg_dxndllcr_addr = PUBL_REG_BASE+PUBL_CFG_ADD_DX0DLLCR+(0x10*4*dxn);\r
2001         publ_dxn_cfg_dxndqstr_addr = PUBL_REG_BASE+PUBL_CFG_ADD_DX0DQSTR+(0x10*4*dxn);\r
2002         \r
2003         modify_reg_field(PUBL_REG_BASE+publ_dxn_cfg_dxndllcr_addr, 14, 4, 0);\r
2004         \r
2005         modify_reg_field(publ_dxn_cfg_dxndllcr_addr, 30, 1, 0);\r
2006         \r
2007         wait_n_pclk_cycle(100/25);\r
2008         \r
2009         modify_reg_field(publ_dxn_cfg_dxndllcr_addr, 30, 1, 1);\r
2010         if (0)\r
2011         {\r
2012                 wait_n_pclk_cycle(10*1000/25);\r
2013         }\r
2014         else\r
2015         {\r
2016                 polling_reg_bit_field(PUBL_REG_BASE+PUBL_CFG_ADD_PGSR, 0, 1, 1);\r
2017                 REG32(PUBL_REG_BASE+PUBL_CFG_ADD_PIR) = 0x5;\r
2018                 wait_n_pclk_cycle(5);\r
2019                 polling_reg_bit_field(PUBL_REG_BASE+PUBL_CFG_ADD_PGSR, 2, 1, 1);\r
2020         }\r
2021         \r
2022         modify_reg_field(PUBL_REG_BASE+publ_dxn_cfg_dxndqstr_addr, 20, 3, 3);\r
2023         modify_reg_field(PUBL_REG_BASE+publ_dxn_cfg_dxndqstr_addr, 23, 3, 3);\r
2024 }\r
2025 \r
2026 static void publ_dram_bist(uint32 start_col, uint32 start_row, uint32 start_bank, uint32 start_cs,\r
2027                         uint32 end_col, uint32 end_row, uint32 end_bank, uint32 end_cs,\r
2028                         uint32 byte_lane,\r
2029                         uint32 infinite_mode)\r
2030 {\r
2031         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTAR0, 0,  12, start_col);\r
2032         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTAR0, 12, 16, start_row);\r
2033         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTAR0, 28,  4, start_bank);\r
2034 \r
2035         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTAR1, 0,  2, start_cs);\r
2036         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTAR1, 2,  2, end_cs);\r
2037         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTAR1, 4, 12, 4);\r
2038 \r
2039         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTAR2, 0,  12, end_col);\r
2040         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTAR2, 12, 16, end_row);\r
2041         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTAR2, 28,  4, end_bank);\r
2042 \r
2043         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR,  3,  1, 1);\r
2044         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR,  4,  1, infinite_mode);\r
2045         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR,  5,  8, 1);\r
2046         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR, 13,  1, 1);\r
2047         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR, 14,  2, 1);\r
2048         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR, 17,  2, 2);\r
2049         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR, 19,  4, byte_lane);\r
2050 \r
2051         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTWCR, 0, 16, 32764);\r
2052 \r
2053         REG32(PUBL_REG_BASE+PUBL_CFG_ADD_BISTLSR) = 0x1234abcd;\r
2054         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR, 0, 3, 1);\r
2055 }\r
2056 \r
2057 static void publ_phy_lb_bist(uint32 dxn, uint32 lbdqss, uint32 iolb)\r
2058 {\r
2059         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_PGCR, 19, 1, iolb);\r
2060 \r
2061         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_PGCR, 29, 1, lbdqss);\r
2062         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR, 14, 2, 1);\r
2063         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR, 17, 2, 2);\r
2064         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR, 19, 4, dxn);\r
2065         \r
2066         REG32(PUBL_REG_BASE+PUBL_CFG_ADD_BISTLSR) = 0x1234abcd;\r
2067         modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR, 0, 3, 1);\r
2068 }\r
2069 \r
2070 static void publ_disable_dxn(uint32 dxn)\r
2071 {\r
2072         uint32 publ_cfg_add_dxngcr;\r
2073         publ_cfg_add_dxngcr = PUBL_CFG_ADD_DX0GCR+(0x10*4*dxn);\r
2074         modify_reg_field(PUBL_REG_BASE+publ_cfg_add_dxngcr, 0, 1, 0);\r
2075 }\r
2076 \r
2077 static void publ_enable_dxn(uint32 dxn)\r
2078 {\r
2079         uint32 publ_cfg_add_dxngcr;\r
2080         publ_cfg_add_dxngcr = PUBL_CFG_ADD_DX0GCR+(0x10*4*dxn);\r
2081         modify_reg_field(PUBL_REG_BASE+publ_cfg_add_dxngcr, 0, 1, 1);\r
2082 }\r
2083 \r
2084 static void set_ddr_phy_vref(void)\r
2085 {\r
2086         uint32 i;\r
2087         modify_adie_reg_field(ANA_DDR2_BUF_CTRL1_DS, 0, 4, 0xa);\r
2088         for (i=0; i<10; i++);\r
2089 }\r
2090 \r
2091 #if 0\r
2092 uint32 cal_sdll_dly_param(SDLL_PHS_DLY_E sdll_phs_dly)\r
2093 {\r
2094         switch (sdll_phs_dly)\r
2095         {\r
2096                 case SDLL_PHS_DLY_36:  return 3;\r
2097                 case SDLL_PHS_DLY_54:  return 2;\r
2098                 case SDLL_PHS_DLY_72:  return 1;\r
2099                 case SDLL_PHS_DLY_90:  return 0;\r
2100                 case SDLL_PHS_DLY_108: return 4;\r
2101                 case SDLL_PHS_DLY_126: return 8;\r
2102                 case SDLL_PHS_DLY_144: return 12;\r
2103                 default:               return 0;\r
2104         }\r
2105 }\r
2106 \r
2107 void set_dqs_pt_gsl_gps_dly(DXN_E dxn, DQS_PHS_DLY_E dqs_step_dly, SDLL_PHS_DLY_E sdll_phs_dly)\r
2108 {\r
2109         uint32 dxndqstr_addr = PUBL_REG_BASE+PUBL_CFG_ADD_DX0DQSTR + 0x10*4*dxn;\r
2110         uint32 dxndllcr_addr = PUBL_REG_BASE+PUBL_CFG_ADD_DX0DLLCR + 0x10*4*dxn;\r
2111 \r
2112         modify_reg_field(dxndqstr_addr, 20, 3, dqs_step_dly);\r
2113         modify_reg_field(dxndqstr_addr, 22, 3, dqs_step_dly);\r
2114         modify_reg_field(dxndllcr_addr, 14, 4, cal_sdll_dly_param(sdll_phs_dly));\r
2115         modify_reg_field(dxndllcr_addr, 30, 1, 0);\r
2116 \r
2117         //wait some time for DLL reset\r
2118         wait_100ns();\r
2119         modify_reg_field(dxndllcr_addr, 30, 1, 1);\r
2120         wait_us(10);\r
2121 }\r
2122 void DMC_Init(const uint32 drv_strength, const uint32 sdll_phase, const uint32 dqs_step)\r
2123 #else\r
2124 void DMC_Init(uint32 emc_freq, uint32 mem_drv, uint32 sdll_phase, uint32 dqs_step)\r
2125 #endif\r
2126 {\r
2127         uint32 i=0;\r
2128 \r
2129 #if SOFTWARE_ENABLE_VREF\r
2130         set_ddrphy_vref();\r
2131 #endif\r
2132 \r
2133         if (emc_freq>=100 && emc_freq<=400)\r
2134                 modify_emc_clk(emc_freq);\r
2135         else\r
2136                 modify_emc_clk(SC8825_EMC_FREQ);\r
2137 \r
2138         for (i=0; i<1000; i++);\r
2139 #if 0\r
2140         if (drv_strength >= 34 && drv_strength <=80)\r
2141                 __emc_init(mem_drv);\r
2142         else\r
2143 #endif\r
2144                 __emc_init(SC8825_EMC_DRV);\r
2145 #if 0\r
2146         if (drv_strength != 0)\r
2147         {\r
2148                 set_dqs_pt_gsl_gps_dly(0, sdll_phase&0xff,       dqs_step&0xff); \r
2149                 set_dqs_pt_gsl_gps_dly(1, (sdll_phase>>8)&0xff,  (dqs_step>>8)&0xff);\r
2150                 set_dqs_pt_gsl_gps_dly(2, (sdll_phase>>16)&0xff, (dqs_step>>16)&0xff);\r
2151                 set_dqs_pt_gsl_gps_dly(3, (sdll_phase>>24)&0xff, (dqs_step>>24)&0xff);\r
2152         }\r
2153 #endif\r
2154 }\r
2155 \r