e72f32ffb5b87bbd4092f0e24e11502929f80aec
[profile/mobile/platform/kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc8825 / mcu.c
1 /******************************************************************************
2     David.Jia   2007.10.29      share_version_union
3
4     TCC -fpu None -O2 -bi -g+ -apcs /interwork -D__RUN_IN_SDRAM sdram_init.c
5 SC6600R    -D_BL_NF_SC6600R_
6 SC6600H    -D_BL_NF_SC6600H_
7 SC6600I    -D_BL_NF_SC6600I_
8 SC6800     -gtp -cpu ARM926EJ-S -D_REF_SC6800_ -D_BL_NF_SC6800_
9 ******************************************************************************/
10
11 #include <common.h>
12 #include <asm/arch/sci_types.h>
13 #include <asm/arch/arm_reg.h>
14 #include <asm/arch/sdram_cfg.h>
15 #include <asm/arch/chng_freq.h>
16 #include <asm/arch/sc_reg.h>
17 #include <asm/arch/sdram.h>
18 #include <asm/arch/chip.h>
19
20 #define REG32(x)   (*((volatile uint32 *)(x)))
21
22
23 typedef enum
24 {
25         LPDDR2_DS_34_OHM = 0xd,
26         LPDDR2_DS_40_OHM = 0xb,
27         LPDDR2_DS_48_OHM = 0x9,
28         LPDDR2_DS_60_OHM = 0x7,
29         LPDDR2_DS_80_OHM = 0x5
30 }LPDDR2_MEM_DS_T_E;
31
32 typedef enum
33 {
34         LPDDR1_DS_33_OHM = 0xa,
35         LPDDR1_DS_31_OHM = 0xb,
36         LPDDR1_DS_48_OHM = 0xc,
37         LPDDR1_DS_43_OHM = 0xd,
38         LPDDR1_DS_39_OHM = 0xe,
39         LPDDR1_DS_55_OHM = 0x5,
40         LPDDR1_DS_64_OHM = 0x4
41 }LPDDR1_MEM_DS_T_E;
42
43 typedef enum
44 {
45         SDLL_PHS_DLY_DEF  = 0x0,
46         SDLL_PHS_DLY_36   = 0x3,
47         SDLL_PHS_DLY_54   = 0x2,
48         SDLL_PHS_DLY_72   = 0x1,
49         SDLL_PHS_DLY_90   = 0x0,
50         SDLL_PHS_DLY_108  = 0x4,
51         SDLL_PHS_DLY_126  = 0x8,
52         SDLL_PHS_DLY_144  = 0x12
53 }SDLL_PHS_DLY_E;
54
55 typedef enum
56 {
57         DQS_STEP_DLY_MIN  = 0,
58         DQS_STEP_DLY_SUB3 = 0,
59         DQS_STEP_DLY_SUB2 = 1,
60         DQS_STEP_DLY_SUB1 = 2,
61         DQS_STEP_DLY_NOM  = 3,
62         DQS_STEP_DLY_DEF  = 3,
63         DQS_STEP_DLY_ADD1 = 4,
64         DQS_STEP_DLY_ADD2 = 5,
65         DQS_STEP_DLY_ADD3 = 6,
66         DQS_STEP_DLY_ADD4 = 7,
67         DQS_STEP_DLY_MAX  = 7
68 }DQS_STEP_DLY_E;
69
70
71 #if 1
72 extern uint32 LPDDR1_MEM_DS; //lpddr1 driver strength,refer to multiPHY p155
73 extern uint32 LPDDR2_MEM_DS; //lpddr1 driver strength,
74
75 extern uint32 B0_SDLL_PHS_DLY; //byte0 sll dll phase delay 
76 extern uint32 B1_SDLL_PHS_DLY; //byte1 sll dll phase delay 
77 extern uint32 B2_SDLL_PHS_DLY; //byte2 sll dll phase delay 
78 extern uint32 B3_SDLL_PHS_DLY; //byte3 sll dll phase delay 
79
80 extern uint32 B0_DQS_STEP_DLY; //byte0 dqs step delay
81 extern uint32 B1_DQS_STEP_DLY; //byte1 dqs step delay
82 extern uint32 B2_DQS_STEP_DLY; //byte2 dqs step delay
83 extern uint32 B3_DQS_STEP_DLY; //byte3 dqs step delay
84 #endif
85
86 typedef enum MCU_CLK_TYPE_TAG
87 {
88     ARM100_EMC50_AHB100,
89     ARM200_EMC100_AHB100,
90     ARM400_EMC200_AHB100,
91     ARM400_EMC200_AHB200,
92     ARM800_EMC100_AHB200,
93     ARM870_EMC100_AHB200,
94     ARM800_EMC200_AHB200,
95     ARM800_EMC400_AHB200,
96     ARM1000_EMC50_AHB200,
97     ARM1000_EMC100_AHB200,
98     ARM1000_EMC200_AHB200,
99     ARM1000_EMC400_AHB200,
100     ARM1200_EMC100_AHB200,
101     ARM1200_EMC200_AHB200,
102     ARM1200_EMC400_AHB200,
103     MCU_CLK_TYPE_MAX
104 } MCU_CLK_TYPE_E;
105
106 typedef struct ARM_EMC_AHB_CLK_TAG
107 {
108     uint32         mcu_clk;
109     uint32         arm_clk;
110     uint32         emc_clk;
111     uint32         ahb_clk;
112     MCU_CLK_TYPE_E clk_type;
113 } ARM_EMC_AHB_CLK_T;
114 #if 0
115 static const ARM_EMC_AHB_CLK_T s_arm_emc_ahb_clk[] =
116 {
117 //   mcu_clk       arm_clk       emc_clk       ahb_clk
118     {ARM_CLK_800M, ARM_CLK_800M, ARM_CLK_100M, ARM_CLK_200M, ARM800_EMC100_AHB200},
119     {ARM_CLK_800M, ARM_CLK_800M, ARM_CLK_200M, ARM_CLK_200M, ARM800_EMC200_AHB200},
120     {ARM_CLK_800M, ARM_CLK_800M, ARM_CLK_400M, ARM_CLK_200M, ARM800_EMC400_AHB200},
121     {ARM_CLK_1000M,ARM_CLK_1000M,ARM_CLK_100M, ARM_CLK_200M, ARM1000_EMC100_AHB200},
122     {ARM_CLK_1000M,ARM_CLK_1000M,ARM_CLK_200M, ARM_CLK_200M, ARM1000_EMC200_AHB200},
123     {ARM_CLK_1000M,ARM_CLK_1000M,ARM_CLK_400M, ARM_CLK_200M, ARM1000_EMC400_AHB200},
124     {ARM_CLK_1200M,ARM_CLK_1200M,ARM_CLK_200M, ARM_CLK_200M, ARM1200_EMC200_AHB200},
125     {ARM_CLK_1200M,ARM_CLK_1200M,ARM_CLK_400M, ARM_CLK_200M, ARM1200_EMC400_AHB200},
126 };
127
128 static uint32 GetClockCfg(MCU_CLK_TYPE_E clk_type, uint32 *mcu_clk, uint32 *arm_clk, uint32 *emc_clk, uint32 *ahb_clk)
129 {
130     uint32 i;
131     for (i=0; i<(sizeof(s_arm_emc_ahb_clk)/sizeof(s_arm_emc_ahb_clk[0])); i++)
132     {
133         if (s_arm_emc_ahb_clk[i].clk_type == clk_type)
134         {
135             *mcu_clk = s_arm_emc_ahb_clk[i].mcu_clk;
136             *arm_clk = s_arm_emc_ahb_clk[i].arm_clk;
137             *emc_clk = s_arm_emc_ahb_clk[i].emc_clk;
138             *ahb_clk = s_arm_emc_ahb_clk[i].ahb_clk;
139             return 0;
140         }
141     }
142     return -1;
143 }
144 #endif
145 static void delay()
146 {
147     uint32 i;
148     for (i=0; i<0x100; i++);
149 }
150
151 static uint32 GET_MPLL_N()
152 {       
153     return REG32(GR_MPLL_MN)&0x07FF;
154 }
155
156 static uint32 GET_MPLL_M()
157 {
158     uint32 M;
159     switch ((REG32(GR_MPLL_MN)>>16)&0x3)
160     {
161         case 0x0: M=2; break;
162         case 0x3: M=13;break;
163         default:  M=4; break;   
164     }
165     return M;
166 }
167
168 static void SET_MPLL_N(uint32 N)
169 {
170     uint32 mpll;
171     mpll =REG32(GR_MPLL_MN);
172     mpll &= ~0x07FF;
173     mpll |= N & 0x07FF;
174     REG32(GR_MPLL_MN) = mpll;
175         delay();
176 }
177 static int SET_MPLL_M(uint32 M)
178 {
179     uint32 mpll;
180     switch(M)
181     {
182         case 2: M=0; break;
183         case 4: M=1; break;
184         case 13:M=3; break;
185         default:     return -1;
186     }
187
188     mpll = REG32(GR_MPLL_MN);
189     mpll &= ~(0x3<<16);
190     mpll |= (M<<16);
191     REG32(GR_MPLL_MN) = mpll;
192     delay();
193     return 0;
194 }
195
196 static uint32 GetMPllClk (void)
197 {
198     return GET_MPLL_M()*GET_MPLL_N()*1000000;
199 }
200
201 static uint32 SetMPllClk (uint32 clk)
202 {
203     uint32 M, N, ret=1;
204     clk /= 1000000;
205     M = 4;
206     N = clk/M;
207     
208     REG32(GR_GEN1) |= BIT_9;        // MPLL Write En
209     
210     if (!SET_MPLL_M(M))
211     {       
212         SET_MPLL_N(N);
213         ret = 0;
214     }
215     REG32(GR_GEN1) &= ~BIT_9;       // MPLL Write Dis
216     return ret;
217 }
218
219 static uint32 GET_DPLL_N()
220 {       
221     return REG32(GR_DPLL_MN)&0x07FF;
222 }
223
224 static uint32 GET_DPLL_M()
225 {
226     uint32 M;
227     switch ((REG32(GR_DPLL_MN)>>16)&0x3)
228     {
229         case 0x0: M=2; break;
230         case 0x3: M=13;break;
231         default:  M=4; break;   
232     }
233     return M;
234 }
235
236 static uint32 GetDPllClk(void)
237 {
238     return GET_DPLL_M()*GET_DPLL_N()*1000000;
239 }
240 #if 0
241 static uint32 EmcClkConfig(uint32 emc_clk)
242 {
243     uint32 src_clk, div, ahb_arm_clk;
244
245     ahb_arm_clk = REG32(AHB_ARM_CLK);
246     
247     ahb_arm_clk &= ~(0x3f<<14);
248     ahb_arm_clk |= 0xf<<14;
249     REG32(AHB_ARM_CLK) = ahb_arm_clk;
250     delay();
251
252     ahb_arm_clk &= ~(0x0f<<8);       //emc clock div = 0
253     src_clk = GetDPllClk();
254     div = src_clk / emc_clk;
255     ahb_arm_clk &= ~(0x0f<<8);
256     ahb_arm_clk |= ((div-1)&0x0f)<<8;
257     REG32(AHB_ARM_CLK) = ahb_arm_clk;
258     delay();
259
260     ahb_arm_clk &= ~BIT_3;           //emc lcokc async
261     ahb_arm_clk &= ~(0x03<<12);      //emc clock src= MPLL/2
262     ahb_arm_clk |= (1<<12);          //emc clock src=DPLL
263     
264     REG32(AHB_ARM_CLK) = ahb_arm_clk;
265     delay();
266     return 0;
267 }
268 #endif
269 static uint32 AhbClkConfig(uint32 ahb_clk)
270 {
271     uint32 ahb_arm_clk, div, mcu_clk;
272     
273     mcu_clk = GetMPllClk();
274
275     ahb_arm_clk = REG32(AHB_ARM_CLK);
276     div = mcu_clk/ahb_clk;
277     if (div*ahb_clk != mcu_clk)
278         div++;
279     ahb_arm_clk &= ~(0x07<<4);
280     ahb_arm_clk |= ((div-1)&0x7)<<4; //ahb clock
281     REG32(AHB_ARM_CLK) = ahb_arm_clk;
282     delay();
283     
284     ahb_arm_clk &= ~(0x03<<23);      //MCU clock = MPLL
285     REG32(AHB_ARM_CLK) = ahb_arm_clk;
286     delay();
287     return 0;
288 }
289
290 static uint32 AxiClkConfig()
291 {
292     uint32 ca5_cfg;
293     ca5_cfg = REG32(AHB_CA5_CFG);
294     ca5_cfg &= ~(3<<11);
295     if (sci_efuse_overclocking_get())
296         ca5_cfg |= (2 << 11);
297     else
298         ca5_cfg |= (1<<11);
299     REG32(AHB_CA5_CFG) = ca5_cfg;
300     delay();
301     return 0;
302 }
303
304 static uint32 ArmClkPeriSet()
305 {
306     uint32 ahb_arm_clk;
307     ahb_arm_clk  = REG32(AHB_ARM_CLK);
308     ahb_arm_clk &= ~(7<<20);
309     if (sci_efuse_overclocking_get())
310         ahb_arm_clk |= 2 << 20;
311     else
312         ahb_arm_clk |= 1<<20;
313     REG32(AHB_ARM_CLK) = ahb_arm_clk;
314     return 0;
315 }
316
317 static uint32 DbgClkConfig()
318 {
319     uint32 ahb_arm_clk, dbg_div;
320     ahb_arm_clk  = REG32(AHB_ARM_CLK);
321     dbg_div = (ahb_arm_clk>>14)&0x3f;
322     if (sci_efuse_overclocking_get())
323         dbg_div += 2;
324     else
325         dbg_div++;
326     ahb_arm_clk |= dbg_div<<14;
327     REG32(AHB_ARM_CLK) = ahb_arm_clk;
328     return 0;
329 }
330
331 static uint32 McuClkConfig(uint32 mcu_clk)
332 {
333     if (SetMPllClk(mcu_clk))
334         return -1;
335     if (mcu_clk > ARM_CLK_800M)
336     {
337         ArmClkPeriSet();
338         DbgClkConfig();
339     }
340     return 0;
341 }
342
343 static uint32 ClkConfig()
344 {
345     //uint32 mcu_clk, arm_clk, emc_clk, ahb_clk, ahb_arm_clk, div;
346     //if (GetClockCfg(clk_type, &mcu_clk, &arm_clk, &emc_clk, &ahb_clk))
347     //    return -1;
348     uint16 reg_data;
349
350     if (sci_efuse_overclocking_get()) {
351         /* if used dcdc calibration in uboot, dcdc_arm,dcdc_core set in dcdc_cal.c */
352         //DCDC ARM 1.3V
353         reg_data = ADI_Analogdie_reg_read(0x420006AC);
354         reg_data &=  ~(0xff);
355         reg_data |=  7;
356         ADI_Analogdie_reg_write(0x420006AC, reg_data);
357
358 #if 1   // default 1.1V regdata = 0;
359         //DCDC CORE 1.2V
360         reg_data = ADI_Analogdie_reg_read(0x42000640);
361         reg_data &=  ~(0xff);
362         reg_data |=  0x6;
363         reg_data |=  (0x1 << 4);
364         ADI_Analogdie_reg_write(0x42000640, reg_data);
365 #endif
366
367         AxiClkConfig();
368         McuClkConfig(1200000000);
369     }
370     else {
371         AxiClkConfig();
372         McuClkConfig(1000000000);
373     }
374     AhbClkConfig(200000000);
375     //EmcClkConfig(emc_clk);
376
377     return 0;
378 }
379
380 uint32 MCU_Init()
381 {
382     MCU_CLK_TYPE_E clk_type;
383
384     //clk_type = ARM1000_EMC50_AHB200;
385     //clk_type = ARM1000_EMC100_AHB200;
386     clk_type = ARM1000_EMC100_AHB200;
387     //clk_type = ARM1000_EMC400_AHB200;
388     //clk_type = ARM800_EMC100_AHB200;
389     //clk_type = ARM800_EMC200_AHB200;
390     //clk_type = ARM800_EMC400_AHB200;
391
392     if (ClkConfig())
393         while(1);
394     return 0;
395 }
396
397 #define USE_SPL_DATA
398 #if defined USE_SPL_DATA
399
400 #define SPL_DATA_ADR (CONFIG_SYS_TEXT_BASE + (23*1024))
401
402 #define SPL_DATA_DBG
403
404 typedef struct
405 {
406     uint32  tag;
407     uint32  len;
408     uint32  data[];
409 }spl_priv_data;
410
411 typedef struct
412 {
413     uint32  flag;
414     uint32  mem_drv;
415     uint32  sdll_phase;
416     uint32  dqs_step;
417     uint32  check_sum; 
418 }emc_priv_data;
419
420 #define EMC_PRIV_DATA  0x10
421 #define EMC_MAGIC_DATA 0xabcd1234
422
423 #if defined SPL_DATA_DBG
424 #define SPL_DATA_DBG_ADR (SPL_DATA_ADR + 0x100)
425 #endif
426
427 static spl_priv_data* spl_data = NULL;
428 static emc_priv_data* emc_data = NULL; 
429
430 static uint32 GET_SPL_Data()
431 {
432     uint32 ret = 1;
433
434     spl_data = (spl_priv_data *)SPL_DATA_ADR;
435     if (spl_data->tag == EMC_PRIV_DATA)
436     {
437         emc_data = (emc_priv_data *)(spl_data->data);
438         if (emc_data->flag == EMC_MAGIC_DATA)
439         {
440             uint32 check_sum = 0;
441             check_sum ^= emc_data->flag;
442             check_sum ^= emc_data->mem_drv;
443             check_sum ^= emc_data->sdll_phase;
444             check_sum ^= emc_data->dqs_step;
445             if (check_sum == emc_data->check_sum)
446                 ret = 0;
447         }
448     }
449     return ret;
450 }
451 #endif
452
453 void Chip_Init (void) /*lint !e765 "Chip_Init" is used by init.s entry.s*/
454 {
455     uint32 ret;
456
457 #ifdef CONFIG_NAND_SPL          
458     MCU_Init();
459
460     ret = GET_SPL_Data();
461 #endif
462
463 #if 0    
464 #if defined USE_SPL_DATA
465
466     if (ret != 0)
467     {
468         DMC_Init(0, 0, 0, 0);
469     }
470     else
471     {
472 #if defined SPL_DATA_DBG
473         *((volatile unsigned int *)(SPL_DATA_DBG_ADR + 0x00)) = emc_data->mem_drv;
474         *((volatile unsigned int *)(SPL_DATA_DBG_ADR + 0x04)) = emc_data->sdll_phase;
475         *((volatile unsigned int *)(SPL_DATA_DBG_ADR + 0x08)) = emc_data->dqs_step;
476         *((volatile unsigned int *)(SPL_DATA_DBG_ADR + 0x0C)) = emc_data->check_sum;
477 #endif
478         DMC_Init(0, emc_data->mem_drv, emc_data->sdll_phase, emc_data->dqs_step);
479     }
480 #else
481     DMC_Init(0, 0, 0, 0);
482 #endif
483 #else
484
485     if(CONFIG_DDR_TIMING_CUSTOM == TRUE)
486     {
487         LPDDR1_MEM_DS = CONFIG_LPDDR1_DS;
488         LPDDR2_MEM_DS = CONFIG_LPDDR2_DS;
489
490         B0_SDLL_PHS_DLY = CONFIG_BYTE0_PHS_DLY;
491         B1_SDLL_PHS_DLY = CONFIG_BYTE1_PHS_DLY;
492         B2_SDLL_PHS_DLY = CONFIG_BYTE2_PHS_DLY;
493         B3_SDLL_PHS_DLY = CONFIG_BYTE3_PHS_DLY;
494
495         B0_DQS_STEP_DLY = CONFIG_BYTE0_STEP_DLY;
496         B1_DQS_STEP_DLY = CONFIG_BYTE1_STEP_DLY;
497         B2_DQS_STEP_DLY = CONFIG_BYTE2_STEP_DLY;
498         B3_DQS_STEP_DLY = CONFIG_BYTE3_STEP_DLY;
499     }
500         
501         #ifdef CONFIG_NAND_SPL    
502     if (ret == 0) //chesum is pass       
503     {
504         LPDDR1_MEM_DS = emc_data->mem_drv;
505         LPDDR2_MEM_DS = emc_data->mem_drv;
506         
507         B0_SDLL_PHS_DLY = (emc_data->sdll_phase&0xff000000)>>24;
508         B1_SDLL_PHS_DLY = (emc_data->sdll_phase&0xff0000)>>16;
509         B2_SDLL_PHS_DLY = (emc_data->sdll_phase&0xff00)>>8;
510         B3_SDLL_PHS_DLY = emc_data->sdll_phase&0xff;
511         
512         B0_DQS_STEP_DLY = (emc_data->dqs_step&0xff000000)>>24;        
513         B1_DQS_STEP_DLY = (emc_data->dqs_step&0xff0000)>>16;
514         B2_DQS_STEP_DLY = (emc_data->dqs_step&0xff00)>>8;
515         B3_DQS_STEP_DLY = emc_data->dqs_step&0xff;
516     }
517         #endif
518
519     DMC_Dev_Init(400000000);
520
521 #endif
522 }
523