1 #include <asm/arch/sci_types.h>
\r
3 #define REG32(x) (*((volatile uint32 *)(x)))
\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
9 #define MEM_CS1_TYPE MEM_CS_0MB //caution: if CS1 is not available, modify it to MEM_CS_0Mb
\r
11 //#define MEMORY_TYPE LPDDR1
\r
12 #define MEMORY_TYPE LPDDR2 //typedef enum int {LPDDR2,LPDDR1,DDR3} MEM_TYPE_ENUM;
\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
21 #if (MEMORY_TYPE == LPDDR1)
\r
22 #define SC8825_EMC_DRV 40
\r
24 #define SC8825_EMC_DRV 48
\r
27 #define ZQ_CALIBRE_DPSLEEP 0x0
\r
28 #define SOFTWARE_ENABLE_VREF 0
\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
35 //=====================================================================================
\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
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
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
60 #define _LPDDR2_WC_ 1 //0: wrap
\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
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
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
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
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
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
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
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
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
278 static void modify_reg_field(uint32 addr, uint32 start_bit, uint32 bit_num, uint32 value)
\r
281 temp = REG32(addr);
\r
282 for (i=0; i<bit_num; i++)
\r
284 temp &= ~(0x1<<(start_bit+i));
\r
286 temp |= value<<start_bit;
\r
287 REG32(addr) = temp;
\r
290 static void modify_adie_reg_field(uint32 addr, uint32 start_bit, uint32 bit_num, uint32 value)
\r
293 temp = ADI_Analogdie_reg_read(addr);
\r
294 for (i=0; i<bit_num; i++)
\r
296 temp &= ~(0x1<<(start_bit+i));
\r
298 temp |= value<<start_bit;
\r
299 REG32(addr) = temp;
\r
302 static uint32 polling_reg_bit_field(uint32 addr, uint32 start_bit, uint32 bit_num, uint32 value)
\r
309 for (i=0; i<bit_num; i++)
\r
311 mask |= 1<<(start_bit+i);
\r
313 exp_value = value << start_bit;
\r
314 do {temp = REG32(addr);} while((temp & mask) != exp_value);
\r
318 static void wait_n_pclk_cycle(uint32 num)
\r
322 for (i=0; i<num; i++)
\r
324 value_temp = REG32(PUBL_REG_BASE+PUBL_CFG_ADD_PGSR);
\r
328 static void wait_100ns()
\r
331 for (i=0; i<100; i++);
\r
334 static void wait_1us()
\r
337 for (i=0; i<1000; i++);
\r
340 static void wait_us(uint32 us)
\r
343 for (i=0; i<us; i++)
\r
349 static void write_upctl_state_cmd(uPCTL_STATE_CMD_ENUM cmd)
\r
351 REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_SCTL) = cmd;
\r
354 static void poll_upctl_state (uPCTL_STATE_ENUM state)
\r
356 uPCTL_STATE_ENUM state_poll;
\r
360 value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);
\r
361 state_poll = value_temp & 0x7;
\r
363 while(state_poll != state);
\r
367 static void move_upctl_state_to_initmem(void)
\r
369 uPCTL_STATE_ENUM upctl_state;
\r
370 uPCTL_STATE_CMD_ENUM upctl_state_cmd;
\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
377 switch((tmp_val & 0x7))
\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
389 write_upctl_state_cmd(CFG);
\r
390 poll_upctl_state(Config);
\r
391 upctl_state = Config;
\r
392 tmp_val = upctl_state ;
\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
403 default: //transitional state
\r
405 tmp_val = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);
\r
412 static void move_upctl_state_to_config(void)
\r
414 uPCTL_STATE_ENUM upctl_state;
\r
415 //uPCTL_STATE_CMD_ENUM upctl_state_cmd;
\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
422 switch(upctl_state)
\r
426 write_upctl_state_cmd(WAKEUP);
\r
427 poll_upctl_state(Access);
\r
428 upctl_state = Access;
\r
433 write_upctl_state_cmd(CFG);
\r
434 poll_upctl_state(Config);
\r
435 upctl_state = Config;
\r
440 write_upctl_state_cmd(CFG);
\r
441 poll_upctl_state(Config);
\r
442 upctl_state = Config;
\r
445 default: //transitional state
\r
447 tmp_val = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);
\r
448 upctl_state = tmp_val & 0x7;
\r
454 static void move_upctl_state_to_low_power(void)
\r
456 uPCTL_STATE_ENUM upctl_state;
\r
457 //uPCTL_STATE_CMD_ENUM upctl_state_cmd;
\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
463 switch(upctl_state)
\r
467 write_upctl_state_cmd(SLEEP);
\r
468 poll_upctl_state(Low_power);
\r
469 upctl_state = Low_power;
\r
474 write_upctl_state_cmd(GO);
\r
475 poll_upctl_state(Access);
\r
476 upctl_state = Access;
\r
481 write_upctl_state_cmd(CFG);
\r
482 poll_upctl_state(Config);
\r
483 upctl_state = Config;
\r
486 default: //transitional state
\r
488 tmp_val = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);
\r
489 upctl_state = tmp_val & 0x7;
\r
496 static void move_upctl_state_to_access(void)
\r
498 uPCTL_STATE_ENUM upctl_state;
\r
500 tmp_val = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);
\r
501 upctl_state = tmp_val & 0x7;
\r
503 while(upctl_state != Access)
\r
505 switch(upctl_state)
\r
513 write_upctl_state_cmd(GO);
\r
514 poll_upctl_state(Access);
\r
515 upctl_state = Access;
\r
520 write_upctl_state_cmd(CFG);
\r
521 poll_upctl_state(Config);
\r
522 upctl_state = Config;
\r
527 write_upctl_state_cmd(WAKEUP);
\r
528 poll_upctl_state(Access);
\r
529 upctl_state = Access;
\r
532 default: //transitional state
\r
534 tmp_val = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_STAT);
\r
535 upctl_state = tmp_val & 0x7;
\r
541 //return 1 if OK, 0 if fail
\r
542 static uint32 ddr_rw_chk_single(uint32 offset, uint32 data)
\r
545 *(volatile uint32 *)(EMC_MEM_BASE_ADDR + offset) = data;
\r
546 rd = *(volatile uint32 *)(EMC_MEM_BASE_ADDR + offset);
\r
552 //return 1 if OK, 0 if fail
\r
553 static uint32 ddr_rw_chk(uint32 offset)
\r
557 for(i = 0; i < 6; i++)
\r
583 if(ddr_rw_chk_single(offset, data) == 0)
\r
585 if(ddr_rw_chk_single(offset + 0x4, data) == 0)
\r
587 if(ddr_rw_chk_single(offset + 0x8, data) == 0)
\r
589 if(ddr_rw_chk_single(offset + 0xc, data) == 0)
\r
594 static uint32 dq_training(uint32 offset)
\r
597 uint32 B0, B1, B2, B3;
\r
598 for(B0 = 0; B0 < 16; B0++)
\r
600 *(volatile uint32 *)(PUBL_REG_BASE + PUBL_CFG_ADD_DX0DQSTR) = B0 | (B0 << 4);
\r
601 for(B1 = 0; B1 < 16; B1++)
\r
603 *(volatile uint32 *)(PUBL_REG_BASE + PUBL_CFG_ADD_DX1DQSTR) = B1 | (B1 << 4);
\r
604 for(B2 = 0; B2 < 16; B2++)
\r
606 *(volatile uint32 *)(PUBL_REG_BASE + PUBL_CFG_ADD_DX2DQSTR) = B2 | (B2 << 4);
\r
607 for(B3 = 0; B3 < 16; B3++)
\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
613 // *(volatile uint32 *)(EMC_MEM_BASE_ADDR+0x1000+i)=(0xBA55<<16)|(B3<<12)|(B2<<8)|(B1<<4)|B0;
\r
618 //*(volatile uint32 *)(EMC_MEM_BASE_ADDR+0x1000+i)=(0xFA11<<16)|(B3<<12)|(B2<<8)|(B1<<4)|B0;
\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
633 static void emc_publ_do_gate_training(void)
\r
635 uint32 value_temp, i;
\r
636 REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PIR) = 0x81;
\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
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
649 if((value_temp & 0x40) != 0)
\r
653 if((value_temp & 0x20) != 0)
\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
664 static void set_value_ddrphy_ret_en(uint32 value)
\r
668 REG32(0x4B001080) = 0x1; //set ret_en to 1
\r
670 else if (value == 0x0)
\r
672 REG32(0x4B002080) = 0x1; //clear set_en to 1
\r
676 static void publ_do_zq_calibration()
\r
678 uint32 value_temp, i;
\r
679 REG32(PUBL_REG_BASE+PUBL_CFG_ADD_ZQ0CR0) = 1<<30;
\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
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
697 uint32 TOGCNT1U, TOGCNT100N;
\r
699 if (mem_type_enum == LPDDR1)
\r
701 value_temp = (1<<31)|(1<<28)|(0xc<<5)|(0xc);
\r
702 REG32(PUBL_REG_BASE+PUBL_CFG_ADD_ZQ0CR0) = value_temp;
\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
714 switch(mem_type_enum)
\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
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
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
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
749 value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_PPCFG);
\r
750 value_temp &= ~0x1;
\r
751 switch(mem_width_enum)
\r
755 value_temp |= 0x1; //enable partial populated memory
\r
762 REG32(UMCTL_REG_BASE+UMCTL_CFG_ADD_PPCFG) = value_temp;
\r
770 switch (SC8825_EMC_FREQ)
\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
793 REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TINIT) = 0x000000C8;
\r
794 REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TRSTH) = 0x00000000;
\r
796 REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TREFI) = 0x00000027;
\r
797 REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TMRD) = 0x00000005;
\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
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
806 value_temp = (mem_type_enum == LPDDR2 ) ? 6 : 3;
\r
807 REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TCL) = value_temp;
\r
809 value_temp = (mem_type_enum == LPDDR2 ) ? 3 : 1;
\r
810 REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_TCWL) = value_temp;
\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
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
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
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
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
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
857 case MEM_CS_8192MB:
\r
858 value_temp |= (0x7 << 2);
\r
860 case MEM_CS_4096MB:
\r
861 value_temp |= (0x6 << 2);
\r
863 case MEM_CS_2048MB:
\r
864 value_temp |= (0x5 << 2);
\r
866 case MEM_CS_1024MB:
\r
867 value_temp |= (0x4 << 2);
\r
870 value_temp |= (0x3 << 2);
\r
873 value_temp |= (0x2 << 2);
\r
876 value_temp |= (0x1 << 2);
\r
879 value_temp |= (0x0 << 2);
\r
882 value_temp |= (0x6 << 2);
\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
889 value_temp &= ~(0xf << 2); //density
\r
891 switch (MEM_CS1_TYPE)
\r
893 case MEM_CS_8192MB:
\r
894 value_temp |= (0x7 << 2);
\r
896 case MEM_CS_4096MB:
\r
897 value_temp |= (0x6 << 2);
\r
899 case MEM_CS_2048MB:
\r
900 value_temp |= (0x5 << 2);
\r
902 case MEM_CS_1024MB:
\r
903 value_temp |= (0x4 << 2);
\r
906 value_temp |= (0x3 << 2);
\r
909 value_temp |= (0x2 << 2);
\r
912 value_temp |= (0x1 << 2);
\r
915 value_temp |= (0x0 << 2);
\r
918 value_temp |= (0x6 << 2);
\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
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
927 switch(mem_type_enum)
\r
933 };//??? RL-2, see PUBL P143
\r
942 REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFITRDDATAEN) = value_temp;
\r
944 REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFITPHYRDLAT) = 0x0000000f;
\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
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
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
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
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
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
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
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
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
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
1048 value_temp = REG32(PUBL_REG_BASE+PUBL_CFG_ADD_ZQ0CR1);
\r
1050 switch (MEMORY_TYPE)
\r
1053 value_temp &= ~(0xf<<4);
\r
1056 value_temp &= ~(0xf<<4);
\r
1061 value_temp &= ~0xf;
\r
1065 value_temp |= 0xD; //output impdence divide select, 7:60ohm 9:48ohm 11:40ohm 13:34ohm
\r
1068 value_temp |= 0xB; //output impdence divide select, 7:60ohm 9:48ohm 11:40ohm 13:34ohm
\r
1071 value_temp |= 0x9; //output impdence divide select, 7:60ohm 9:48ohm 11:40ohm 13:34ohm
\r
1074 value_temp |= 0x7; //output impdence divide select, 7:60ohm 9:48ohm 11:40ohm 13:34ohm
\r
1077 value_temp |= 0x5; //output impdence divide select, 7:60ohm 9:48ohm 11:40ohm 13:34ohm
\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
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
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
1106 value_temp = (11 * 1000 * 10) / (25);
\r
1111 value_temp = (200 * 1000 * 10) / (25);
\r
1117 value_temp |= ((1 * 1000 * 10) / 25) << 17;
\r
1118 REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PTR2 ) = value_temp;
\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
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
1134 value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_MR0);
\r
1135 switch(mem_type_enum)
\r
1139 value_temp = 0x0; //not applicable
\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
1162 REG32(PUBL_REG_BASE + PUBL_CFG_ADD_MR0) = value_temp;
\r
1165 value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_MR1);
\r
1166 switch(mem_type_enum)
\r
1168 case LPDDR1: {break;}
\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
1185 REG32(PUBL_REG_BASE + PUBL_CFG_ADD_MR1) = value_temp;
\r
1188 switch(mem_type_enum)
\r
1192 value_temp = 0x0; //extend mode
\r
1197 value_temp = 0x4; //RL = 6 / WL = 3
\r
1203 REG32(PUBL_REG_BASE + PUBL_CFG_ADD_MR2) = value_temp;
\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
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
1216 value_temp &= ~0xff;
\r
1217 value_temp &= ~(0xff<<16);
\r
1220 value_temp &= ~0xff;
\r
1221 value_temp &= ~(0xff<<16);
\r
1226 REG32(PUBL_REG_BASE+PUBL_CFG_ADD_ODTCR) = value_temp;
\r
1229 value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DTPR0);
\r
1230 switch(mem_type_enum)
\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
1249 value_temp = 0x36916a6d;//??? xiaohui
\r
1252 default:{while(1);}
\r
1254 REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DTPR0) = value_temp;
\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
1264 value_temp |= 0x1; //same with lpddr2 to avoid additional code size
\r
1265 value_temp |= (32 << 16); //tRFC
\r
1270 value_temp = 0x193400a0;//??? xiaohui
\r
1276 REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DTPR1) = value_temp;
\r
1279 value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DTPR2);
\r
1280 switch(mem_type_enum)
\r
1286 value_temp = 0x1001a0c8; //actually is default value
\r
1292 REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DTPR2) = value_temp;
\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
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
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
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
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
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
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
1338 value_temp |= (0x1<<18); //only enable CS0 for data training
\r
1342 value_temp |= (0x3 << 18); //enable CS0/1 for data training
\r
1344 REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PGCR) = value_temp;
\r
1346 value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_DSGCR);
\r
1347 value_temp &= ~0xfff; //only applicable for LPDDR
\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
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
1359 uint32 value_temp, i;
\r
1362 switch(mem_type_enum)
\r
1364 case LPDDR1: //{{{
\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
1370 for(i = 0; i < 2; i++)
\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
1377 if(bl == 8 & bt == SEQ)
\r
1382 mode_a = bl == 2 ? 0x1 :
\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
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
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
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
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
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
1431 if(bl == 8 && bt == SEQ)
\r
1435 //MR01: Device feature 1
\r
1436 value_temp = 0x80f00013;
\r
1437 value_temp |= (bl == 4 ? 0x2 :
\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
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
1452 //MR03: I/O config-1. DS: 40 ohm typical (default)
\r
1453 value_temp = 0x80f02030;
\r
1457 value_temp |= 0x1<<12;
\r
1460 value_temp |= 0x2<<12;
\r
1463 value_temp |= 0x3<<12;
\r
1466 value_temp |= 0x4<<12;
\r
1469 value_temp |= 0x6<<12;
\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
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
1485 default:{while(1);}
\r
1489 static void __emc_init(uint32 mem_drv)
\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
1499 value_temp = REG32(0x4B000080);
\r
1500 value_temp |= (0x1<<1);
\r
1501 REG32(0x4B000080) = value_temp;
\r
1504 //value_temp = REG32(0x2090_0308);
\r
1505 //value_temp[9] = 0x1;
\r
1506 //REG32_WR(0x2090_0308,value_temp);
\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
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
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
1526 if ((value_temp&0x000003e0) == 0x00000000)
\r
1532 #if SOFTWARE_ENABLE_VREF
\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
1544 while(1); //zcal error must be 0
\r
1546 if ((value_temp & 0x000003e0) == 0x00000000)
\r
1548 while(1); //zcal error must be 0
\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
1561 value_temp = (0x1<<18)|0x1; //Controller DRAM Initialization
\r
1562 REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PIR) = value_temp;
\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
1570 //check dfi init complete
\r
1573 value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFISTSTAT0);
\r
1574 } while((value_temp & 0x1) == 0);
\r
1576 //Start the memory power up sequence
\r
1577 REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_POWCTL) = 0x00000001;
\r
1579 //Returns the status of the memory power-up sequence
\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
1588 mem_init(mem_type_enum, _LPDDR1_BL_, _LPDDR1_BT_, mem_drv);
\r
1591 mem_init(mem_type_enum, _LPDDR2_BL_, _LPDDR2_BT_, mem_drv);
\r
1595 move_upctl_state_to_config();
\r
1596 #if GATE_TRAING_ON
\r
1597 emc_publ_do_gate_training();
\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
1604 void emc_init_repowered(uint32 power_off)
\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
1614 //cfg clk emc to 200MHz if lpddr1
\r
1615 //it must use AHB to config
\r
1617 value_temp = REG32(0x4B000080);
\r
1618 value_temp |= 0x1 << 1;
\r
1619 REG32(0x4B000080) = value_temp;
\r
1621 move_upctl_state_to_config();
\r
1623 //value_temp = REG32(0x2090_0308);
\r
1624 //value_temp[9] = 0x1;
\r
1625 //REG32(0x2090_0308) = value_temp;
\r
1628 emc_init_common_reg(mem_type_enum, mem_width_enum, SC8825_EMC_DRV);
\r
1631 do value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PGSR);
\r
1632 while((value_temp & 0x1) == 0);
\r
1635 value_temp |= 1 << 30; //ZCALBYP
\r
1636 value_temp |= 1 << 18; //Controller DRAM Initialization
\r
1638 REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PIR) = value_temp;
\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
1644 do value_temp = REG32(PUBL_REG_BASE + PUBL_CFG_ADD_PGSR);
\r
1645 while((value_temp & 0x1) == 0);
\r
1647 do value_temp = REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_DFISTSTAT0);
\r
1648 while((value_temp & 0x1) == 0);
\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
1658 value_temp = REG32(UMCTL_REG_BASE+UMCTL_CFG_ADD_POWSTAT);
\r
1659 } while((value_temp&1)==0);
\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
1670 if (power_off == 0x0)
\r
1672 move_upctl_state_to_low_power();
\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
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
1686 if (ZQ_CALIBRE_DPSLEEP)
\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
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
1701 //first move upctl to low power state before issuing wakeup command
\r
1704 move_upctl_state_to_low_power();
\r
1706 move_upctl_state_to_access();
\r
1707 move_upctl_state_to_config();
\r
1709 emc_publ_do_gate_training();
\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
1716 static void precharge_all_bank(void)
\r
1718 //all cs be precharged
\r
1719 REG32(UMCTL_REG_BASE + UMCTL_CFG_ADD_MCMD) = 0x85f00001;
\r
1722 static void load_mode(MEM_TYPE_ENUM mem_type_enum, uint32 bl, MEM_BT_ENUM bt)
\r
1724 uint32 mode_ba, mode_a;
\r
1725 uint32 value_temp;
\r
1726 switch(mem_type_enum)
\r
1730 if(bl == 8 & bt == SEQ)
\r
1735 mode_a = (bl == 2 ? 0x1 :
\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
1750 if(bl == 8 && bt == SEQ)
\r
1754 //MR01: Device feature 1
\r
1755 value_temp = 0x80f00013;
\r
1756 value_temp = (bl == 4 ? 0x2 :
\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
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
1777 static void disable_clk_emc()
\r
1779 modify_reg_field(ADDR_AHBREG_AHB_CTRL0, 28, 1, 0);
\r
1782 static void enable_clk_emc()
\r
1784 modify_reg_field(ADDR_AHBREG_AHB_CTRL0, 28, 1, 1);
\r
1787 static void assert_reset_acdll()
\r
1789 modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_ACDLLCR, 30, 1, 0);
\r
1792 static void deassert_reset_acdll()
\r
1794 modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_ACDLLCR, 30, 1, 1);
\r
1797 static void assert_reset_dxdll()
\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
1805 static void deassert_reset_dxdll()
\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
1813 static void assert_reset_ddrphy_dll()
\r
1815 assert_reset_acdll();
\r
1816 assert_reset_dxdll();
\r
1819 static void deassert_reset_ddrphy_dll()
\r
1821 deassert_reset_acdll();
\r
1822 deassert_reset_dxdll();
\r
1825 static void modify_dpll_freq(uint32 freq)
\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
1835 static void modify_emc_clk(uint32 freq)
\r
1837 disable_clk_emc();
\r
1838 assert_reset_acdll();
\r
1839 assert_reset_dxdll();
\r
1840 modify_dpll_freq(freq);
\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
1849 deassert_reset_acdll();
\r
1850 deassert_reset_dxdll();
\r
1854 static void reset_ddrphy_dll()
\r
1856 disable_clk_emc();
\r
1857 assert_reset_acdll();
\r
1858 assert_reset_dxdll();
\r
1861 deassert_reset_acdll();
\r
1862 deassert_reset_dxdll();
\r
1866 static void modify_dxndll_phase_trim(uint32 dxn, uint32 phase)
\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
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
1901 modify_reg_field(publ_cfg_dxndllcr_addr, 30, 1, 1);
\r
1904 wait_n_pclk_cycle(10*1000/25);
\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
1915 static void modify_dxndqstr_delay_trim(uint32 dxn, uint32 trim_value)
\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
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
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
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
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
1942 modify_reg_field(publ_cfg_dxndllcr_addr, 30, 1, 0);
\r
1944 modify_reg_field(publ_cfg_dxndllcr_addr, 30, 1, 1);
\r
1947 wait_n_pclk_cycle(10*1000/25);
\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
1958 static void publ_do_itmsrst()
\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
1965 static void publ_do_bist_stop()
\r
1968 modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR, 0, 3, 2);
\r
1969 for (i=0; i<24; i++);
\r
1972 static void publ_do_bist_reset()
\r
1975 modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTRR, 0, 3, 3);
\r
1976 for (i=0; i<24; i++);
\r
1979 static void publ_record_bistgsr(uint32 result_addr)
\r
1981 uint32 value_temp, addr;
\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
1988 if (value_temp == 0x1)
\r
1989 REG32(addr) = 0x0000ba55;
\r
1991 REG32(addr) = 0x0000fa11;
\r
1994 static void publ_set_dqs_phase_trim_to_norminal(uint32 dxn)
\r
1996 uint32 publ_dxn_cfg_dxndllcr_addr;
\r
1997 uint32 publ_dxn_cfg_dxndqstr_addr;
\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
2003 modify_reg_field(PUBL_REG_BASE+publ_dxn_cfg_dxndllcr_addr, 14, 4, 0);
\r
2005 modify_reg_field(publ_dxn_cfg_dxndllcr_addr, 30, 1, 0);
\r
2007 wait_n_pclk_cycle(100/25);
\r
2009 modify_reg_field(publ_dxn_cfg_dxndllcr_addr, 30, 1, 1);
\r
2012 wait_n_pclk_cycle(10*1000/25);
\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
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
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
2029 uint32 infinite_mode)
\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
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
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
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
2051 modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_BISTWCR, 0, 16, 32764);
\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
2057 static void publ_phy_lb_bist(uint32 dxn, uint32 lbdqss, uint32 iolb)
\r
2059 modify_reg_field(PUBL_REG_BASE+PUBL_CFG_ADD_PGCR, 19, 1, iolb);
\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
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
2070 static void publ_disable_dxn(uint32 dxn)
\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
2077 static void publ_enable_dxn(uint32 dxn)
\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
2084 static void set_ddr_phy_vref(void)
\r
2087 modify_adie_reg_field(ANA_DDR2_BUF_CTRL1_DS, 0, 4, 0xa);
\r
2088 for (i=0; i<10; i++);
\r
2092 uint32 cal_sdll_dly_param(SDLL_PHS_DLY_E sdll_phs_dly)
\r
2094 switch (sdll_phs_dly)
\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
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
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
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
2117 //wait some time for DLL reset
\r
2119 modify_reg_field(dxndllcr_addr, 30, 1, 1);
\r
2122 void DMC_Init(const uint32 drv_strength, const uint32 sdll_phase, const uint32 dqs_step)
\r
2124 void DMC_Init(uint32 emc_freq, uint32 mem_drv, uint32 sdll_phase, uint32 dqs_step)
\r
2129 #if SOFTWARE_ENABLE_VREF
\r
2130 set_ddrphy_vref();
\r
2133 if (emc_freq>=100 && emc_freq<=400)
\r
2134 modify_emc_clk(emc_freq);
\r
2136 modify_emc_clk(SC8825_EMC_FREQ);
\r
2138 for (i=0; i<1000; i++);
\r
2140 if (drv_strength >= 34 && drv_strength <=80)
\r
2141 __emc_init(mem_drv);
\r
2144 __emc_init(SC8825_EMC_DRV);
\r
2146 if (drv_strength != 0)
\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