1 /******************************************************************************
2 David.Jia 2007.10.29 share_version_union
4 ******************************************************************************/
8 #include <asm/arch/sci_types.h>
9 #include <asm/arch/chip_drv_common_io.h>
10 #include <asm/arch/adi_hal_internal.h>
11 #include <asm/arch/sprd_reg.h>
12 #include <asm/arch/chip_drvapi.h>
15 #if defined(CONFIG_SPX30G)
18 #define NINT(FREQ,REFIN) (FREQ/REFIN)
19 #define KINT(FREQ,REFIN) ((FREQ-(FREQ/REFIN)*REFIN)*1048576/REFIN)
23 #if defined(CONFIG_CLK_PARA)
24 #include <asm/arch/clk_para_config.h>
25 const MCU_CLK_PARA_T mcu_clk_para=
27 .magic_header = MAGIC_HEADER,
28 .version = CONFIG_PARA_VERSION,
29 .core_freq = CLK_CA7_CORE,
31 .axi_freq = CLK_CA7_AXI,
32 .dgb_freq = CLK_CA7_DGB,
33 .ahb_freq = CLK_CA7_AHB,
34 .apb_freq = CLK_CA7_APB,
35 .pub_ahb_freq = CLK_PUB_AHB,
36 .aon_apb_freq = CLK_AON_APB,
38 .dcdc_core = DCDC_CORE,
45 .debug_flags[0] = 0x1FFF07F1, //0x1FFF07FF
46 .magic_end = MAGIC_END
53 for (i=0; i<0x100; i++);
56 static uint32 SetMPllClk (uint32 clk)
58 uint32 mpll_cfg, pll_sft_cnt;
60 REG32(REG_AON_APB_PLL_SOFT_CNT_DONE) &= ~1;
62 #if defined(CONFIG_SPX30G)
64 mpll_cfg = REG32(REG_AON_APB_MPLL_CFG1);
65 mpll_cfg |= 1<<10; // fractional divider
66 mpll_cfg &=~(0xfffff<<12 | 0x3f);
67 mpll_cfg |= (KINT(clk, MPLL_REFIN)&0xfffff)<<12;
68 mpll_cfg |= (NINT(clk,MPLL_REFIN))&0x3f;
69 REG32(REG_AON_APB_MPLL_CFG1)= mpll_cfg;
71 mpll_cfg = REG32(REG_AON_APB_MPLL_CFG); //MPLL reference clock 0-2M 1-4M 2-13M 3-26M
74 REG32(REG_AON_APB_MPLL_CFG)=mpll_cfg ;
76 mpll_cfg = REG32(REG_AON_APB_MPLL_CFG);
81 mpll_cfg |= clk&0x7ff;
82 REG32(REG_AON_APB_MPLL_CFG) = mpll_cfg;
90 REG32(REG_AON_APB_PLL_SOFT_CNT_DONE) |= 1;
94 static uint32 AhbClkConfig()
96 #if defined(CONFIG_CLK_PARA)
98 ahb_cfg = REG32(REG_AP_CLK_AP_AHB_CFG);
100 ahb_cfg |= mcu_clk_para.ahb_freq; //ahb select 192M 0:26M 1:76M 2:128M 3:192M
101 REG32(REG_AP_CLK_AP_AHB_CFG) = ahb_cfg;
103 ahb_cfg = REG32(REG_AON_CLK_PUB_AHB_CFG);
105 ahb_cfg |= mcu_clk_para.pub_ahb_freq; //pub ahb select 153M 0:26M 1:76M 2:128M 3:153M
106 REG32(REG_AON_CLK_PUB_AHB_CFG) = ahb_cfg;
109 ahb_cfg = REG32(REG_AP_CLK_AP_AHB_CFG);
111 ahb_cfg |= 3; //ahb select 192M 0:26M 1:76M 2:128M 3:192M
112 REG32(REG_AP_CLK_AP_AHB_CFG) = ahb_cfg;
114 ahb_cfg = REG32(REG_AON_CLK_PUB_AHB_CFG);
116 ahb_cfg |= 3; //pub ahb select 153M 0:26M 1:76M 2:128M 3:153M
117 REG32(REG_AON_CLK_PUB_AHB_CFG) = ahb_cfg;
123 static uint32 ApbClkConfig()
125 #if defined(CONFIG_CLK_PARA)
127 apb_cfg = REG32(REG_AP_CLK_AP_APB_CFG);
129 apb_cfg |= mcu_clk_para.apb_freq; //apb select 64M 0:26M 1:64M 2:96M 3:128M
130 REG32(REG_AP_CLK_AP_APB_CFG) = apb_cfg;
132 apb_cfg = REG32(REG_AON_CLK_AON_APB_CFG);
134 apb_cfg |= mcu_clk_para.aon_apb_freq; //aon apb select 128M 0:26M 1:76M 2:96M 3:128M
135 REG32(REG_AON_CLK_AON_APB_CFG) = apb_cfg;
138 apb_cfg = REG32(REG_AP_CLK_AP_APB_CFG);
140 apb_cfg |= 1; //apb select 64M 0:26M 1:64M 2:96M 3:128M
141 REG32(REG_AP_CLK_AP_APB_CFG) = apb_cfg;
143 apb_cfg = REG32(REG_AON_CLK_AON_APB_CFG);
145 apb_cfg |= 3; //aon apb select 128M 0:26M 1:76M 2:96M 3:128M
146 REG32(REG_AON_CLK_AON_APB_CFG) = apb_cfg;
152 static uint32 AxiClkConfig(uint32 arm_clk)
154 #if defined(CONFIG_CLK_PARA)
156 ca7_ckg_cfg = REG32(REG_AP_AHB_CA7_CKG_CFG);
157 ca7_ckg_cfg &= ~(7<<8);
158 ca7_ckg_cfg |= ((arm_clk/(mcu_clk_para.axi_freq+1))&0x7)<<8;
159 REG32(REG_AP_AHB_CA7_CKG_CFG) = ca7_ckg_cfg;
162 ca7_ckg_cfg = REG32(REG_AP_AHB_CA7_CKG_CFG);
163 ca7_ckg_cfg &= ~(7<<8);
164 ca7_ckg_cfg |= ((arm_clk/(ARM_CLK_500M+1))&0x7)<<8;
165 REG32(REG_AP_AHB_CA7_CKG_CFG) = ca7_ckg_cfg;
171 static uint32 DbgClkConfig(uint32 arm_clk)
173 #if defined(CONFIG_CLK_PARA)
175 ca7_ckg_cfg = REG32(REG_AP_AHB_CA7_CKG_CFG);
176 ca7_ckg_cfg &= ~(7<<16);
177 ca7_ckg_cfg |= ((arm_clk/(mcu_clk_para.dgb_freq+1))&0x7)<<16;
178 REG32(REG_AP_AHB_CA7_CKG_CFG) = ca7_ckg_cfg;
181 ca7_ckg_cfg = REG32(REG_AP_AHB_CA7_CKG_CFG);
182 ca7_ckg_cfg &= ~(7<<16);
183 ca7_ckg_cfg |= ((arm_clk/(ARM_CLK_200M+1))&0x7)<<16;
184 REG32(REG_AP_AHB_CA7_CKG_CFG) = ca7_ckg_cfg;
190 static uint32 McuClkConfig(uint32 arm_clk)
194 ca7_ckg_cfg = REG32(REG_AP_AHB_CA7_CKG_CFG);
195 ca7_ckg_cfg &= ~7; //a7 core select 26M
196 REG32(REG_AP_AHB_CA7_CKG_CFG) = ca7_ckg_cfg;
201 ca7_ckg_cfg = REG32(REG_AP_AHB_CA7_CKG_CFG);
202 ca7_ckg_cfg &= ~(7<<4); //ap clk div = 0;
204 ca7_ckg_cfg |= 6; //a7 core select mcu MPLL 0:26M 1:(DPLL)533M 2:(CPLL)624M 3:(TDPLL)768M 4:(WIFIPLL)880M 5:(WPLL)921M 6:(MPLL)1200M
205 REG32(REG_AP_AHB_CA7_CKG_CFG) = ca7_ckg_cfg;
212 #if defined(CONFIG_VOL_PARA)
213 static const int dcdc_ctl_vol[][2] = {
214 {5,650},{1,700},{2,800},{3,900},{4,1000},{0,1100},{6,1200},{7,1300}
216 void dcdc_calibrate(int chan, int to_vol)
219 uint32 cal_vol, ctl_vol = to_vol;
221 uint32 length = ARRAY_SIZE(dcdc_ctl_vol);
222 for (i = 0; i < length; i++) {
223 if (ctl_vol < dcdc_ctl_vol[i][1])
230 if (chan == 10) { // dcdc arm
231 ANA_REG_MSK_OR(ANA_REG_GLB_MP_MISC_CTRL,((dcdc_ctl_vol[i][0] & 0x7) << 6), BIT(6)|BIT(7)|BIT(8));
233 else if (chan == 11) {//dcdc core
234 ANA_REG_MSK_OR(ANA_REG_GLB_MP_MISC_CTRL,((dcdc_ctl_vol[i][0] & 0x7) << 3), BIT(3)|BIT(4)|BIT(5));
239 cal_vol = ((ctl_vol - dcdc_ctl_vol[i-1][1]) * 32 / 100) & 0x1f;
240 if (chan == 10) { // dcdc arm
241 ANA_REG_SET(ANA_REG_GLB_DCDC_ARM_ADI, cal_vol);
242 ANA_REG_MSK_OR(ANA_REG_GLB_MP_MISC_CTRL, ((dcdc_ctl_vol[i-1][0] & 0x7) << 6), BIT(6)|BIT(7)|BIT(8));
244 else if (chan == 11) {//dcdc core
245 ANA_REG_SET(ANA_REG_GLB_DCDC_CORE_ADI, cal_vol);
246 ANA_REG_MSK_OR(ANA_REG_GLB_MP_MISC_CTRL, ((dcdc_ctl_vol[i-1][0] & 0x7) << 3), BIT(3)|BIT(4)|BIT(5));
252 if (chan == 10) { // dcdc arm
253 ANA_REG_SET(ANA_REG_GLB_DCDC_ARM_ADI,((dcdc_ctl_vol[i][0]&0x7)<<5));
255 else if (chan == 11) {//dcdc core
256 ANA_REG_SET(ANA_REG_GLB_DCDC_CORE_ADI,((dcdc_ctl_vol[i][0]&0x7)<<5));
261 cal_vol = ((ctl_vol - dcdc_ctl_vol[i-1][1]) * 32 / 100) & 0x1f;
262 if (chan == 10) { // dcdc arm
263 ANA_REG_SET(ANA_REG_GLB_DCDC_ARM_ADI, cal_vol |((dcdc_ctl_vol[i-1][0]&0x7)<<5));
265 else if (chan == 11) {//dcdc core
266 ANA_REG_SET(ANA_REG_GLB_DCDC_CORE_ADI, cal_vol |((dcdc_ctl_vol[i-1][0]&0x7)<<5));
271 for(i = 0; i < 0x1000; ++i){};
275 /* DCDC MEM output select:
276 * [BONDOPT2 BONDOPT1]
277 * 00: DDR2 application (1.2v)
278 * 01: DDR3L application (1.35v)
279 * 10: DDR3 application (1.5v)
280 * 11: DDR1 application (1.8v)
281 * DCDC MEM converter control bits with two bonding options as [bpt2 bpt1 xxx], list below:
290 * DCDC MEM calibration control bits with small adjust step is 200/32mv.
297 /* FIXME: manual sort dcdc control voltage
299 const struct dcdc_ctl_t dcdc_mem_vols[] = {
300 {.idx = 0, .vol = 1200,}, //chip default
301 {.idx = 1, .vol = 1250,},
302 {.idx = 3, .vol = 1300,},
303 {.idx = 2, .vol = 1350,},
304 {.idx = 5, .vol = 1400,},
305 {.idx = 4, .vol = 1500,},
306 {.idx = 6, .vol = 1800,},
307 {.idx = 7, .vol = 1900,},
310 const struct dcdc_ctl_t dcdc_gen_vols[] = {
311 {.idx = 1, .vol = 1800,},
312 {.idx = 2, .vol = 1900,},
313 {.idx = 3, .vol = 2000,},
314 {.idx = 4, .vol = 2100,},
315 {.idx = 0, .vol = 2200,},
316 {.idx = 5, .vol = 2300,},
317 {.idx = 6, .vol = 2400,}, //chip default
318 {.idx = 7, .vol = 2500,},
321 void dcdc_mem_calibrate(int to_vol)
324 for (i = ARRAY_SIZE(dcdc_mem_vols) - 1; i >= 0; i--) {
325 if (to_vol >= dcdc_mem_vols[i].vol) break;
328 int cal = (to_vol - dcdc_mem_vols[i].vol) * 32 / 200; /* FIXME: non roundup*/
330 if (cal <= BITS_DCDC_MEM_CAL_ADI(~0)) {
331 ANA_REG_SET(ANA_REG_GLB_DCDC_MEM_ADI, (dcdc_mem_vols[i].idx << 5) | (cal << 0));
335 //TODO: downward adjustment
339 void dcdc_gen_calibrate(int to_vol)
342 for (i = ARRAY_SIZE(dcdc_gen_vols) - 1; i >= 0; i--) {
343 if (to_vol >= dcdc_gen_vols[i].vol) break;
346 int cal = (to_vol - dcdc_gen_vols[i].vol) * 32 / 100; /* FIXME: non roundup*/
347 if (cal <= BITS_DCDC_GEN_CAL_ADI(~0)) {
348 ANA_REG_SET(ANA_REG_GLB_DCDC_MEM_ADI, (dcdc_gen_vols[i].idx << 5) | (cal << 0));
355 static uint32 ArmCoreConfig(uint32 arm_clk)
359 #if defined(CONFIG_VOL_PARA)
360 dcdc_calibrate(10,mcu_clk_para.dcdc_arm); //dcdc arm
361 dcdc_calibrate(11,mcu_clk_para.dcdc_core); //dcdc core
362 dcdc_mem_calibrate(mcu_clk_para.dcdc_mem); //dcdc mem
363 //dcdc_gen_calibrate(mcu_clk_para.dcdc_gen); //dcdc gen for LDOs
365 REG32(REG_AP_APB_APB_EB) |= BIT_AP_CKG_EB;
367 dcdc_arm = ANA_REG_GET(ANA_REG_GLB_DCDC_ARM_ADI);
372 #if (defined(CONFIG_SP8830EB)||defined(CONFIG_SP8830EC) || defined(CONFIG_SP8835EB) || defined(CONFIG_SP7730EC) || defined(CONFIG_SP5735) || defined(CONFIG_SP5735C1) || defined(CONFIG_SPX15) || defined(CONFIG_SP7730ECTRISIM) || defined(CONFIG_SC9620OPENPHONE) || defined(CONFIG_SC9620FPGA) || defined(CONFIG_SP7730GA) || defined(CONFIG_SP8730SEA) || defined(CONFIG_SP8830GA) || defined(CONFIG_SP8830GEA) || defined(CONFIG_SP7730GGA) || defined(CONFIG_SP7731GGA_LC) || defined(CONFIG_SP7730GGA_LC) || defined(CONFIG_SP7731GEA) || defined(CONFIG_SP7731GEA_HD) || defined(CONFIG_SP8730SEEA_QHD) || defined(CONFIG_SP8730SEEA_JIG) || defined(CONFIG_SP7731GEA_HD2) || defined(CONFIG_SP7731GEA_HD) || defined(CONFIG_SP7731GEA_HDR) || defined(CONFIG_SP7731GEA_QHD) || defined(CONFIG_SP7731GEA_FWVGA) || defined(CONFIG_SP7731GEAOPENPHONE) || defined(CONFIG_SP7731GEA_LC) || defined(CONFIG_SP7730GGAOPENPHONE) || defined(CONFIG_TSHARKWSAMSUNG) || defined(CONFIG_PIKEAYOUNG2DTV) || defined(CONFIG_CORE3) || defined(CONFIG_TSHARK2TABE) || defined(CONFIG_GRANDPRIME3G_VE) || defined(CONFIG_SP7720) || defined(CONFIG_COREPRIME3G_VE) || defined(CONFIG_TSHARK2J2_3G) || defined(CONFIG_TIZENZ3_3G) || defined(CONFIG_GRANDPRIME_DTV))
373 if (arm_clk <= ARM_CLK_900M)
375 dcdc_arm |= (6<<5); //set dcdcarmcore voltage 1.1V->1.2V
379 //dcdc_arm |= (6<<5); //set dcdcarmcore voltage 1.1V->1.2V
380 //dcdc_arm = 1.1V + 0.5V
381 dcdc_arm |= (16); //1000/32 mv=3.125mv, 16*3.125mv = 50mv
384 if (arm_clk < ARM_CLK_1000M)
386 dcdc_arm |= (4<<5); //set dcdcarmcore voltage 1.1V->1.0V
388 else if (arm_clk >= ARM_CLK_1200M)
390 dcdc_arm |= (6<<5); //set dcdcarmcore voltage 1.1V->1.2V
394 ANA_REG_SET(ANA_REG_GLB_DCDC_ARM_ADI, dcdc_arm);
395 REG32(REG_AP_APB_APB_EB) |= BIT_AP_CKG_EB; // CKG enable
404 REG32(REG_AON_APB_APB_EB1) |= BIT_AVS1_EB | BIT_AVS0_EB;
405 REG32(0x4003003C) |= 0xF<<5; //enable channel5-8
406 REG32(0x40300020) = 2;
407 REG32(0x4030001C) = 1;
410 static uint32 ClkConfig(uint32 arm_clk)
412 ArmCoreConfig(arm_clk);
414 AxiClkConfig(arm_clk);
415 DbgClkConfig(arm_clk);
416 McuClkConfig(arm_clk);
425 #if defined(CONFIG_CLK_PARA)
426 if (ClkConfig(mcu_clk_para.core_freq))
428 #if (defined(CONFIG_SP8830EB)||defined(CONFIG_SP8830EC)||defined(CONFIG_SP8835EB)||defined(CONFIG_SP7730EC)||defined(CONFIG_SP5735)||defined(CONFIG_SP5735C1)||defined(CONFIG_SPX15) || defined(CONFIG_SP7730ECTRISIM)||defined(CONFIG_SC9620OPENPHONE)||defined(CONFIG_SC9620FPGA)||defined(CONFIG_SP7730GA)||defined(CONFIG_SP8830GA)||defined(CONFIG_SP8830GEA)||defined(CONFIG_SP8730SEA)||defined(CONFIG_SP7730GGA)||defined(CONFIG_SP7730GGAOPENPHONE) || defined(CONFIG_SP7731GGA_LC) || defined(CONFIG_SP7730GGA_LC) || defined(CONFIG_SP7731GEA) || defined(CONFIG_SP7731GEA_HD) || defined(CONFIG_SP8730SEEA_QHD) || defined(CONFIG_SP8730SEEA_JIG) || defined(CONFIG_SP7731GEA_HD2) || defined(CONFIG_SP7731GEA_HD) || defined(CONFIG_SP7731GEA_HDR) || defined(CONFIG_SP7731GEA_QHD) || defined(CONFIG_SP7731GEA_FWVGA) || defined(CONFIG_SP7731GEAOPENPHONE) || defined(CONFIG_SP7731GEA_LC) || defined(CONFIG_TSHARKWSAMSUNG) || defined(CONFIG_CORE3) || defined(CONFIG_PIKEAYOUNG2DTV) || defined(CONFIG_TSHARK2TABE) || defined(CONFIG_GRANDPRIME3G_VE) || defined(CONFIG_COREPRIME3G_VE) || defined(CONFIG_TSHARK2J2_3G) || defined(CONFIG_TIZENZ3_3G) || defined(CONFIG_GRANDPRIME_DTV)|| defined(CONFIG_SP7720))
429 if (ClkConfig(ARM_CLK_1000M))
431 if (ClkConfig(ARM_CLK_800M))
438 #if defined(CONFIG_CLK_PARA)
439 void set_ddr_clk(uint32 ddr_clk)
441 volatile uint32 reg_val;
442 #if defined(CONFIG_SPX30G)
443 ddr_clk = ddr_clk/1000000;
444 reg_val = REG32(REG_AON_APB_DPLL_CFG1);
445 reg_val |= 1<<10; // fractional divider
446 reg_val &=~(0xfffff<<12 | 0x3f);
447 reg_val |= (KINT(ddr_clk, DPLL_REFIN)&0xfffff)<<12;
448 reg_val |= (NINT(ddr_clk,DPLL_REFIN))&0x3f;
449 REG32(REG_AON_APB_DPLL_CFG1)= reg_val;
451 reg_val = REG32(REG_AON_APB_DPLL_CFG); //DPLL reference clock 0-2M 1-4M 2-13M 3-26M
454 REG32(REG_AON_APB_DPLL_CFG)=reg_val;
456 reg_val = REG32(REG_AON_APB_DPLL_CFG);
458 reg_val |= (ddr_clk/4);
459 REG32(REG_AON_APB_DPLL_CFG)= reg_val;
461 //select DPLL 533MHZ source clock
462 reg_val = REG32(REG_AON_CLK_EMC_CFG);
464 // reg_val |= 0; //default:XTL_26M
465 // reg_val |= 1; //TDPLL_256M
466 // reg_val |= 2; //TDPLL_384M
467 reg_val |= 3; //DPLL_533M
468 REG32(REG_AON_CLK_EMC_CFG)= reg_val;
474 #if defined(CONFIG_VOL_PARA)
480 vol_para_t vol_para[7 + 1] __align(16) = {
481 [0] = { /* Begin Array, DO NOT remove it! */
482 .ideal_vol = 0xfaed, .name = "volpara_begin",
485 .ideal_vol = 1200, .name = "vddarm",
488 .ideal_vol = 1100, .name = "vddcore",
491 .ideal_vol = 0, .name = "dcdcmem",
493 #ifdef CONFIG_SS_FUNCTION
495 .ideal_vol = 2100, .name = "dcdcgen",
499 .ideal_vol = 2400, .name = "dcdcgen",
502 //TODO: add your ideal ldo here like the following example
504 .ideal_vol = 1800, .name = "vddsim2",
507 [6] = { /* End Array, DO NOT remove it! */
508 .ideal_vol = 0xdeaf, .name = "volpara_end",
511 /* Note: 16bytes debug datas at the end! */
513 /****************************************
515 //byte 5~16: reserved
519 //byte 3~4: dcdc ctrl calibration flag
521 * bit[13] ~ bit[15] : reserved
527 * bit[7] : vddemmccore
537 //byte 1~2: ldo ctrl calibration flag
539 * bit[12] ~ bit[15] : reserved
552 ******************************************/
558 * FIXME: Update LDOs voltage in u-boot
560 BUG_ON(sizeof(vol_para_t) != 16);
561 (mcu_clk_para.dcdc_arm)?vol_para[1].ideal_vol = mcu_clk_para.dcdc_arm:0;
562 (mcu_clk_para.dcdc_core)?vol_para[2].ideal_vol = mcu_clk_para.dcdc_core:0;
563 (mcu_clk_para.dcdc_mem)?vol_para[3].ideal_vol = mcu_clk_para.dcdc_mem:0;
564 (mcu_clk_para.dcdc_gen)?vol_para[4].ideal_vol = mcu_clk_para.dcdc_gen:0;
566 if(mcu_clk_para.debug_flags[0]) {
567 int num = sizeof(vol_para)/sizeof(vol_para[0]);
568 volatile uint32* p_flag = (volatile uint32*)(&vol_para[num-1]);
569 *p_flag = mcu_clk_para.debug_flags[0];
572 return (sizeof(vol_para) << 16) + sizeof(vol_para_t);
577 void Chip_Init (void) /*lint !e765 "Chip_Init" is used by init.s entry.s*/
581 #if defined(CONFIG_SPX15)
582 if(0x2711A000 == ANA_GET_CHIP_ID()) {
583 value = ANA_REG_GET(0x4003883c);
586 ANA_REG_SET(0x4003883c,value);
588 value = ANA_REG_GET(0x40038820);
591 ANA_REG_SET(0x40038820,value);
596 #if defined(CONFIG_VOL_PARA)