2 * Copyright (C) 2011 MediaTek, Inc.
4 * Author: Holmes Chiou <holmes.chiou@mediatek.com>
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/sched.h>
20 #include <linux/kthread.h>
21 #include <linux/delay.h>
22 #include <linux/proc_fs.h>
23 #include <linux/uaccess.h>
25 #include <linux/platform_device.h>
26 #include <linux/miscdevice.h>
27 #include <linux/sched_clock.h>
28 #include <linux/vmalloc.h>
29 #include <linux/dma-mapping.h>
30 #include <board-custom.h>
31 #include <linux/seq_file.h>
33 #include "mach/mt_freqhopping.h"
34 #include "mach/mt_fhreg.h"
35 #include "mach/mt_clkmgr.h"
36 #include "mach/mt_typedefs.h"
37 #include "mach/mt_gpio.h"
38 #include "mach/mt_gpufreq.h"
39 #include "mach/mt_cpufreq.h"
40 #include "mach/emi_bwl.h"
41 #include "mach/sync_write.h"
42 #include "mach/mt_sleep.h"
44 #include <mach/mt_freqhopping_drv.h>
46 //#define FH_MSG printk //TODO
47 //#define FH_BUG_ON(x) printk("BUGON %s:%d %s:%d",__FUNCTION__,__LINE__,current->comm,current->pid)//TODO
48 //#define FH_BUG_ON(...) //TODO
50 #define MT_FH_CLK_GEN 0
52 #define USER_DEFINE_SETTING_ID 1
54 static DEFINE_SPINLOCK(freqhopping_lock
);
57 //current DRAMC@mempll
58 static unsigned int g_curr_dramc
=266; //default @266MHz ==> LPDDR2/DDR3 data rate 1066
61 static unsigned int g_pll_mode
;
63 #define PERCENT_TO_DDSLMT(dDS, pERCENT_M10) ((dDS * pERCENT_M10 >> 5) / 100)
65 static unsigned int g_curr_clkgen
=MT658X_FH_PLL_TOTAL_NUM
+1; //default clkgen ==> no clkgen output
68 static unsigned char g_mempll_fh_table
[8];
70 static unsigned int g_initialize
=0;
72 static unsigned int g_clk_en
=0;
74 #ifndef PER_PROJECT_FH_SETTING
76 #define LOW_DRAMC_DDS 0x000E55EC
77 #define LOW_DRAMC_INT 57 //200
78 #define LOW_DRAMC_FRACTION 5612 //200
79 #define LOW_DRAMC 200//233.5
80 #define LOW_DRAMC_FREQ 200000
82 //TODO: fill in the default freq & corresponding setting_id
83 static fh_pll_t g_fh_pll
[MT658X_FH_PLL_TOTAL_NUM
] = { //keep track the status of each PLL
84 {FH_FH_DISABLE
, FH_PLL_ENABLE
, 0, 0 , 0}, //ARMPLL default SSC disable
86 {FH_FH_ENABLE_SSC
, FH_PLL_ENABLE
, 0, 1612000 , 0}, //MAINPLL default SSC disable
88 {FH_FH_DISABLE
, FH_PLL_ENABLE
, 0, 1612000 , 0}, //MAINPLL default SSC disable
91 {FH_FH_ENABLE_SSC
, FH_PLL_ENABLE
, 0, 266000 , 0}, //MEMPLL default SSC enable
93 {FH_FH_DISABLE
, FH_PLL_ENABLE
, 0, 266000 , 0}, //MEMPLL default SSC enable
95 {FH_FH_ENABLE_SSC
, FH_PLL_ENABLE
, 0, 1599000 , 0}, //MSDCPLL default SSC enable
96 {FH_FH_ENABLE_SSC
, FH_PLL_ENABLE
, 0, 1188000 , 0}, //MMPLL default SSC enable
97 {FH_FH_ENABLE_SSC
, FH_PLL_ENABLE
, 0, 1200000 , 0}, //VENCPLL default SSC enable
99 {FH_FH_DISABLE
, FH_PLL_ENABLE
, 0, 1485000 , 0}, //TVDPLL default SSC disable
100 {FH_FH_DISABLE
, FH_PLL_ENABLE
, 0, 1500000 , 0}, //LVDSPLL default SSC disable
107 static const struct freqhopping_ssc mt_ssc_armpll_setting
[MT_SSC_NR_PREDEFINE_SETTING
]= {
108 {0,0,0,0,0,0},//Means disable
109 {0,0xFF,0xFF,0xFF,0xFF,0xFF},//Means User-Define
113 static const struct freqhopping_ssc mt_ssc_mainpll_setting
[MT_SSC_NR_PREDEFINE_SETTING
]= {
114 {0,0,0,0,0,0},//Means disable
115 {0,0xFF,0xFF,0xFF,0xFF,0xFF},//Means User-Define
117 {1612000 ,2 ,7 ,0, 4, 0xA8000},// 0~-4%
119 {1612000 ,0 ,9 ,0, 8, 0xA8000},// 0~-8%
124 static const struct freqhopping_ssc mt_ssc_mempll_setting
[MT_SSC_NR_PREDEFINE_SETTING
]= {
125 {0,0,0,0,0,0},//Means disable
126 {0,0xFF,0xFF,0xFF,0xFF,0xFF},//Means User-Define
127 {266000 ,2 ,7 ,0, 4, 0x0014030c},//266MHz , 0.27us, 0.007812500 , 0 ~ -8% range:0x00131A2D ~ 0x1256AD(0x00131A2D-(0x061C x 32))
128 {200000 ,2 ,7 ,0, 4, 0x000f04b0},//200MHz , 0.27us, 0.007812500, 0 ~ -8%
132 static const struct freqhopping_ssc mt_ssc_msdcpll_setting
[MT_SSC_NR_PREDEFINE_SETTING
]= {
133 {0,0,0,0,0,0},//Means disable
134 {0,0xFF,0xFF,0xFF,0xFF,0xFF},//Means User-Define
135 {1599000, 0, 9, 0, 8, 0xF6275}, //0~-8% range:0xF6275 ~ 0xE2795(0xF6275-(0x09d7 x 32))
139 static const struct freqhopping_ssc mt_ssc_mmpll_setting
[MT_SSC_NR_PREDEFINE_SETTING
]= {
140 {0,0,0,0,0,0},//Means disable
141 {0,0xFF,0xFF,0xFF,0xFF,0xFF},//Means User-Define
142 {1188000 ,0 ,9 ,0, 8, 0x134000}, //0~-8% range:0x134000 ~ 0x11B5C0 (0x134000-(0x0c52 x 32))
145 static const struct freqhopping_ssc mt_ssc_vencpll_setting
[MT_SSC_NR_PREDEFINE_SETTING
]= {
146 {0,0,0,0,0,0},//Means disable
147 {0,0xFF,0xFF,0xFF,0xFF,0xFF},//Means User-Define
148 {1200000, 0, 9, 0, 4, 0xB6000}, //0~-4% range:0xB6000 ~ 0xAEBA0 (0xB6000-(0x03a3 x 32))
153 static const struct freqhopping_ssc mt_ssc_tvdpll_setting
[MT_SSC_NR_PREDEFINE_SETTING
]= {
154 {0,0,0,0,0,0},//Means disable
155 {0,0xFF,0xFF,0xFF,0xFF,0xFF},//Means User-Define
156 {148500, 0, 9, 0, 4, 0xB6C4F}, //0~-4%
159 static const struct freqhopping_ssc mt_ssc_lvdspll_setting
[MT_SSC_NR_PREDEFINE_SETTING
]= {
160 {0,0,0,0,0,0},//Means disable
161 {0,0xFF,0xFF,0xFF,0xFF,0xFF},//Means User-Define
162 {150000, 0, 9, 0, 4, 0xB89D9}, //0~-4%
168 static struct freqhopping_ssc mt_ssc_fhpll_userdefined
[MT_FHPLL_MAX
]= {
169 {0,1,1,2,2,0}, //ARMPLL
170 {0,1,1,2,2,0}, //MAINPLL
171 {0,1,1,2,2,0}, //MEMPLL
172 {0,1,1,2,2,0}, //MSDCPLL
173 {0,1,1,2,2,0}, //MMPLL
174 {0,1,1,2,2,0} //VENCPLL
177 #else //PER_PROJECT_FH_SETTING
179 PER_PROJECT_FH_SETTING
181 #endif //PER_PROJECT_FH_SETTING
183 unsigned int mt_get_emi_freq(void);
185 #define PLL_STATUS_ENABLE 1
186 #define PLL_STATUS_DISABLE 0
188 static void mt_fh_hal_default_conf(void)
190 FH_MSG("EN: %s",__func__
);
192 freqhopping_config(MT658X_FH_MEM_PLL
, 266000, true); //Enable MEMPLL SSC
194 freqhopping_config(MT658X_FH_MM_PLL
, 1188000, true); //TODO: test only
195 freqhopping_config(MT658X_FH_VENC_PLL
, 1200000, true); //TODO: test only
197 freqhopping_config(MT658X_FH_MAIN_PLL
, 1612000, true); //TODO: test only
199 freqhopping_config(MT658X_FH_MSDC_PLL
, 1599000, true); //TODO: test only
203 static void mt_fh_hal_switch_register_to_FHCTL_control(enum FH_PLL_ID pll_id
, int i_control
)
205 if (pll_id
==MT658X_FH_ARM_PLL
) //FHCTL0
207 fh_set_field(PLL_HP_CON0
, (0x1U
<<0), i_control
);
209 else if (pll_id
==MT658X_FH_MAIN_PLL
) //FHCTL1
211 fh_set_field(PLL_HP_CON0
, (0x1U
<<1), i_control
);
213 else if (pll_id
==MT658X_FH_MEM_PLL
) //FHCTL2
215 fh_set_field(PLL_HP_CON0
, (0x1U
<<3), i_control
);
217 else if (pll_id
==MT658X_FH_MSDC_PLL
) //FHCTL3
219 fh_set_field(PLL_HP_CON0
, (0x1U
<<4), i_control
);
221 else if (pll_id
==MT658X_FH_MM_PLL
) //FHCTL4
223 fh_set_field(PLL_HP_CON0
, (0x1U
<<2), i_control
);
225 else if (pll_id
==MT658X_FH_VENC_PLL
) //FHCTL5
227 fh_set_field(PLL_HP_CON0
, (0x1U
<<5), i_control
);
230 else if (pll_id
==MT658X_FH_TVD_PLL
) //FHCTL6
232 fh_set_field(PLL_HP_CON0
, (0x1U
<<6), i_control
);
234 else if (pll_id
==MT658X_FH_LVDS_PLL
) //FHCTL7
236 fh_set_field(PLL_HP_CON0
, (0x1U
<<7), i_control
);
240 static int mt_fh_hal_sync_ncpo_to_FHCTL_DDS(enum FH_PLL_ID pll_id
)
242 if (pll_id
==MT658X_FH_ARM_PLL
) //FHCTL0
244 fh_write32(REG_FHCTL0_DDS
, (fh_read32(ARMPLL_CON1
)&0x1FFFFF)|(1U<<31));
246 else if (pll_id
==MT658X_FH_MAIN_PLL
) //FHCTL1
248 fh_write32(REG_FHCTL1_DDS
, (fh_read32(MAINPLL_CON1
)&0x1FFFFF)|(1U<<31));
250 else if (pll_id
==MT658X_FH_MEM_PLL
) //FHCTL2
252 fh_write32(REG_FHCTL2_DDS
, ((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )&0x1FFFFF)|(1U<<31));
254 else if (pll_id
==MT658X_FH_MSDC_PLL
) //FHCTL3
256 fh_write32(REG_FHCTL3_DDS
, (fh_read32(MSDCPLL_CON1
)&0x1FFFFF)|(1U<<31));
258 else if (pll_id
==MT658X_FH_MM_PLL
) //FHCTL4
260 fh_write32(REG_FHCTL4_DDS
, (fh_read32(MMPLL_CON1
)&0x1FFFFF)|(1U<<31));
262 else if (pll_id
==MT658X_FH_VENC_PLL
) //FHCTL5
264 fh_write32(REG_FHCTL5_DDS
, (fh_read32(VENCPLL_CON1
)&0x1FFFFF)|(1U<<31));
267 else if (pll_id
==MT658X_FH_TVD_PLL
) //FHCTL6
269 fh_write32(REG_FHCTL6_DDS
, (fh_read32(TVDPLL_CON1
)&0x1FFFFF)|(1U<<31));
271 else if (pll_id
==MT658X_FH_LVDS_PLL
) //FHCTL7
273 fh_write32(REG_FHCTL7_DDS
, (fh_read32(LVDSPLL_CON1
)&0x1FFFFF)|(1U<<31));
278 FH_MSG("Incorrect PLL");
283 static void update_fhctl_status(const int pll_id
, const int enable
)
286 int enabled_num
= 0 ;
287 static unsigned int pll_status
[] = {
288 PLL_STATUS_DISABLE
, //ARMPLL
289 PLL_STATUS_DISABLE
, //MAINPLL
290 PLL_STATUS_DISABLE
, //MEMPLL
291 PLL_STATUS_DISABLE
, //MSDCPLL
292 PLL_STATUS_DISABLE
, //TVDPLL
293 PLL_STATUS_DISABLE
//LVDSPLL
296 //FH_MSG("PLL#%d ori status is %d, you hope to change to %d\n", pll_id, pll_status[pll_id], enable) ;
297 //FH_MSG("PL%d:%d->%d", pll_id, pll_status[pll_id], enable) ;
298 if(pll_status
[pll_id
] == enable
) {
299 //FH_MSG("no ch") ;//no change
303 pll_status
[pll_id
] = enable
;
305 for(i
= MT658X_FH_MINIMUMM_PLL
; i
<= MT658X_FH_MAXIMUMM_PLL
; i
++) {
307 if(pll_status
[i
] == PLL_STATUS_ENABLE
) {
308 //FH_MSG("PLL#%d is enabled", i) ;
312 FH_MSG("PLL#%d is disabled", i) ;
316 //FH_MSG("PLen#=%d",enabled_num) ;
318 if((g_clk_en
== 0)&&(enabled_num
>= 1)) {
319 //wait_for_sophie enable_clock_ext_locked(MT_CG_PERI1_FHCTL, "FREQHOP") ;
320 //register change. enable_clock(MT_CG_PERI1_FHCTL, "FREQHOP") ;
323 else if((g_clk_en
== 1)&&(enabled_num
== 0)) {
324 //wait_for_sophie disable_clock_ext_locked(MT_CG_PERI1_FHCTL, "FREQHOP") ;
325 //register change. disable_clock(MT_CG_PERI1_FHCTL, "FREQHOP") ;
332 static int __mt_enable_freqhopping(unsigned int pll_id
,const struct freqhopping_ssc
* ssc_setting
)
334 //unsigned int pll_hp=0;
335 unsigned long flags
=0;
337 //FH_MSG("EN: en_fh");
338 FH_MSG("EN: %s:: %x u: %x df: %d dt: %d dds:%x",__func__
,ssc_setting
->lowbnd
344 update_fhctl_status(pll_id
, PLL_STATUS_ENABLE
) ;
348 //lock @ __freqhopping_ctrl_lock()
349 //spin_lock_irqsave(&freqhopping_lock, flags);
351 g_fh_pll
[pll_id
].fh_status
= FH_FH_ENABLE_SSC
;
354 //TODO: should we check the following here ??
355 //if(unlikely(FH_PLL_STATUS_ENABLE == g_fh_pll[pll_id].fh_status)){
356 //Do nothing due to this not allowable flow
357 //We shall DISABLE and then re-ENABLE for the new setting or another round
358 //FH_MSG("ENABLE the same FH",pll_id);
360 //spin_unlock_irqrestore(&freqhopping_lock, flags);
364 local_irq_save(flags
);
366 //Set the relative parameter registers (dt/df/upbnd/downbnd)
368 fh_set_field(REG_FHCTL0_CFG
+(0x14*pll_id
),FH_SFSTRX_DYS
,ssc_setting
->df
);
369 fh_set_field(REG_FHCTL0_CFG
+(0x14*pll_id
),FH_SFSTRX_DTS
,ssc_setting
->dt
);
371 //fh_write32(REG_FHCTL0_UPDNLMT+(0x14*pll_id), (((ssc_setting->lowbnd) << 16) | (ssc_setting->upbnd)));
372 //FH_MSG("REG_FHCTL%d_UPDNLMT: 0x%08x", pll_id, fh_read32(REG_FHCTL2_UPDNLMT));
375 //fh_write32(REG_FHCTL0_DDS+(0x14*pll_id), (ssc_setting->dds)|(1U<<31));
376 //FH_MSG("FHCTL%d_DDS: 0x%08x", pll_id, (fh_read32(REG_FHCTL0_DDS+(pll_id*0x14))&0x1FFFFF));
378 mt_fh_hal_sync_ncpo_to_FHCTL_DDS(pll_id
);
379 //FH_MSG("FHCTL%d_DDS: 0x%08x", pll_id, (fh_read32(REG_FHCTL0_DDS+(pll_id*0x14))&0x1FFFFF));
381 fh_write32(REG_FHCTL0_UPDNLMT
+(pll_id
*0x14), (PERCENT_TO_DDSLMT((fh_read32(REG_FHCTL0_DDS
+(pll_id
*0x14))&0x1FFFFF),ssc_setting
->lowbnd
) << 16));
382 //FH_MSG("REG_FHCTL%d_UPDNLMT: 0x%08x", pll_id, fh_read32(REG_FHCTL2_UPDNLMT));
383 //FH_MSG("ssc_setting->lowbnd: 0x%x ssc_setting->upbnd: 0x%x", ssc_setting->lowbnd, ssc_setting->upbnd);
385 mt_fh_hal_switch_register_to_FHCTL_control(pll_id
, 1);
386 //pll_hp = fh_read32(PLL_HP_CON0) | (1 << pll_id);
387 //fh_write32( PLL_HP_CON0, pll_hp );
391 fh_set_field(REG_FHCTL0_CFG
+(0x14*pll_id
),FH_FRDDSX_EN
,1);
392 fh_set_field(REG_FHCTL0_CFG
+(0x14*pll_id
),FH_FHCTLX_EN
,1);
393 //lock @ __freqhopping_ctrl_lock()
394 //spin_unlock_irqrestore(&freqhopping_lock, flags);
396 local_irq_restore(flags
);
402 static int __mt_disable_freqhopping(unsigned int pll_id
,const struct freqhopping_ssc
* ssc_setting
)
404 unsigned long flags
=0;
405 // unsigned int pll_hp=0;
406 unsigned int fh_dds
=0;
407 unsigned int pll_dds
=0;
410 //FH_MSG("EN: _dis_fh");
412 //lock @ __freqhopping_ctrl_lock()
413 //spin_lock_irqsave(&freqhopping_lock, flags);
415 local_irq_save(flags
);
416 //Set the relative registers
417 fh_set_field(REG_FHCTL0_CFG
+(0x14*pll_id
),FH_FRDDSX_EN
,0);
418 fh_set_field(REG_FHCTL0_CFG
+(0x14*pll_id
),FH_FHCTLX_EN
,0);
420 local_irq_restore(flags
);
423 if(pll_id
== MT658X_FH_MEM_PLL
){ //for mempll
426 pll_dds
= (DRV_Reg32(DDRPHY_BASE
+0x624)) >> 11 ;
427 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
429 FH_MSG(">p:f< %x:%x",pll_dds
,fh_dds
);
431 while((pll_dds
!= fh_dds
) && ( i
< 100)){
433 if(unlikely(i
> 100)){
439 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
443 FH_MSG("<p:f:i> %x:%x:%d",pll_dds
,fh_dds
,i
);
446 //TODO: sync&wait DDS back to PLLCON1@other PLLs
447 //FH_MSG("n-mempll");
451 local_irq_save(flags
);
452 mt_fh_hal_switch_register_to_FHCTL_control(pll_id
, 0);
453 //pll_hp = fh_read32(PLL_HP_CON0) & ~(1 << pll_id);
454 //fh_write32( (PLL_HP_CON0), pll_hp );
456 g_fh_pll
[pll_id
].fh_status
= FH_FH_DISABLE
;
457 local_irq_restore(flags
);
459 //lock @ __freqhopping_ctrl_lock()
460 //spin_unlock_irqrestore(&freqhopping_lock, flags);
463 update_fhctl_status(pll_id
, PLL_STATUS_DISABLE
) ;
472 //freq is in KHz, return at which number of entry in mt_ssc_xxx_setting[]
473 static noinline
int __freq_to_index(enum FH_PLL_ID pll_id
,int freq
)
475 unsigned int retVal
= 0;
476 unsigned int i
=2; //0 is disable, 1 is user defines, so start from 2
478 //FH_MSG("EN: %s , pll_id: %d, freq: %d",__func__,pll_id,freq);
479 //FH_MSG("EN: , id: %d, f: %d",pll_id,freq);
483 //TODO: use Marco or something to make the code less redudant
484 case MT658X_FH_ARM_PLL
:
485 while(i
< MT_SSC_NR_PREDEFINE_SETTING
){
486 if(freq
== mt_ssc_armpll_setting
[i
].freq
){
495 case MT658X_FH_MAIN_PLL
:
496 while(i
< MT_SSC_NR_PREDEFINE_SETTING
){
497 if(freq
== mt_ssc_mainpll_setting
[i
].freq
){
505 case MT658X_FH_MEM_PLL
:
506 while(i
< MT_SSC_NR_PREDEFINE_SETTING
){
507 if(freq
== mt_ssc_mempll_setting
[i
].freq
){
515 case MT658X_FH_MSDC_PLL
:
516 while(i
< MT_SSC_NR_PREDEFINE_SETTING
){
517 if(freq
== mt_ssc_msdcpll_setting
[i
].freq
){
525 case MT658X_FH_MM_PLL
:
526 while(i
< MT_SSC_NR_PREDEFINE_SETTING
){
527 if(freq
== mt_ssc_mmpll_setting
[i
].freq
){
535 case MT658X_FH_VENC_PLL
:
536 while(i
< MT_SSC_NR_PREDEFINE_SETTING
){
537 if(freq
== mt_ssc_vencpll_setting
[i
].freq
){
546 case MT658X_FH_TVD_PLL
:
547 while(i
< MT_SSC_NR_PREDEFINE_SETTING
){
548 if(freq
== mt_ssc_tvdpll_setting
[i
].freq
){
555 case MT658X_FH_LVDS_PLL
:
556 while(i
< MT_SSC_NR_PREDEFINE_SETTING
){
557 if(freq
== mt_ssc_lvdspll_setting
[i
].freq
){
565 case MT658X_FH_PLL_TOTAL_NUM
:
566 FH_MSG("Error MT658X_FH_PLL_TOTAL_NUM!");
575 static int __freqhopping_ctrl(struct freqhopping_ioctl
* fh_ctl
,bool enable
)
577 const struct freqhopping_ssc
* pSSC_setting
=NULL
;
578 unsigned int ssc_setting_id
=0;
581 //FH_MSG("EN: _fh_ctrl %d:%d",fh_ctl->pll_id,enable);
582 //FH_MSG("%s fhpll_id: %d, enable: %d",(enable)?"enable":"disable",fh_ctl->pll_id,enable);
584 //Check the out of range of frequency hopping PLL ID
585 FH_BUG_ON(fh_ctl
->pll_id
>MT658X_FH_MAXIMUMM_PLL
);
586 FH_BUG_ON(fh_ctl
->pll_id
<MT658X_FH_MINIMUMM_PLL
);
588 if (fh_ctl
->pll_id
==MT658X_FH_MAIN_PLL
)
590 g_fh_pll
[fh_ctl
->pll_id
].curr_freq
= 1612000;
592 else if (fh_ctl
->pll_id
==MT658X_FH_MEM_PLL
)
594 g_fh_pll
[fh_ctl
->pll_id
].curr_freq
= 266000;
596 else if (fh_ctl
->pll_id
==MT658X_FH_MSDC_PLL
)
598 g_fh_pll
[fh_ctl
->pll_id
].curr_freq
= 1599000;
600 else if (fh_ctl
->pll_id
==MT658X_FH_MM_PLL
)
602 g_fh_pll
[fh_ctl
->pll_id
].curr_freq
= 1188000;
604 else if (fh_ctl
->pll_id
==MT658X_FH_VENC_PLL
)
606 g_fh_pll
[fh_ctl
->pll_id
].curr_freq
= 1200000;
608 else if (fh_ctl
->pll_id
==MT658X_FH_ARM_PLL
)
610 g_fh_pll
[fh_ctl
->pll_id
].curr_freq
= 0;
613 else if (fh_ctl
->pll_id
==MT658X_FH_TVD_PLL
)
615 g_fh_pll
[fh_ctl
->pll_id
].curr_freq
= 148500;
617 else if (fh_ctl
->pll_id
==MT658X_FH_LVDS_PLL
)
619 g_fh_pll
[fh_ctl
->pll_id
].curr_freq
= 150000;
624 FH_BUG_ON("Incorrect pll_id.");
627 if((enable
== true) && (g_fh_pll
[fh_ctl
->pll_id
].fh_status
== FH_FH_ENABLE_SSC
) ){
629 //The FH already enabled @ this PLL
631 //FH_MSG("re-en FH");
633 //disable FH first, will be enable later
634 __mt_disable_freqhopping(fh_ctl
->pll_id
,pSSC_setting
);
636 else if((enable
== false) && (g_fh_pll
[fh_ctl
->pll_id
].fh_status
== FH_FH_DISABLE
)){
638 //The FH already been disabled @ this PLL, do nothing & return
640 //FH_MSG("re-dis FH");
646 //ccyeh fh_status set @ __mt_enable_freqhopping() __mt_disable_freqhopping()
647 //g_fh_pll[fh_ctl->pll_id].fh_status = enable?FH_FH_ENABLE_SSC:FH_FH_DISABLE;
649 if( enable
== true) { //enable freq. hopping @ fh_ctl->pll_id
651 if(g_fh_pll
[fh_ctl
->pll_id
].pll_status
== FH_PLL_DISABLE
) {
652 //FH_MSG("pll is dis");
654 //update the fh_status & don't really enable the SSC
655 g_fh_pll
[fh_ctl
->pll_id
].fh_status
= FH_FH_ENABLE_SSC
;
660 //FH_MSG("pll is en");
661 if(g_fh_pll
[fh_ctl
->pll_id
].user_defined
== true){
664 pSSC_setting
= &mt_ssc_fhpll_userdefined
[fh_ctl
->pll_id
];
665 g_fh_pll
[fh_ctl
->pll_id
].setting_id
= USER_DEFINE_SETTING_ID
;
668 //FH_MSG("n-user def");
670 if( g_fh_pll
[fh_ctl
->pll_id
].curr_freq
!= 0 ){
671 ssc_setting_id
= g_fh_pll
[fh_ctl
->pll_id
].setting_id
= __freq_to_index(fh_ctl
->pll_id
, g_fh_pll
[fh_ctl
->pll_id
].curr_freq
);
678 //FH_MSG("sid %d",ssc_setting_id);
679 if(ssc_setting_id
== 0){
680 FH_MSG("!!! No corresponding setting found !!!");
682 //just disable FH & exit
683 __mt_disable_freqhopping(fh_ctl
->pll_id
,pSSC_setting
);
687 switch(fh_ctl
->pll_id
) {
688 case MT658X_FH_MAIN_PLL
:
689 FH_BUG_ON(ssc_setting_id
> (sizeof(mt_ssc_mainpll_setting
)/sizeof(struct freqhopping_ssc
)) );
690 pSSC_setting
= &mt_ssc_mainpll_setting
[ssc_setting_id
];
692 case MT658X_FH_ARM_PLL
:
693 FH_BUG_ON(ssc_setting_id
> (sizeof(mt_ssc_armpll_setting
)/sizeof(struct freqhopping_ssc
)));
694 pSSC_setting
= &mt_ssc_armpll_setting
[ssc_setting_id
];
696 case MT658X_FH_MSDC_PLL
:
697 FH_BUG_ON(ssc_setting_id
> (sizeof(mt_ssc_msdcpll_setting
)/sizeof(struct freqhopping_ssc
)));
698 pSSC_setting
= &mt_ssc_msdcpll_setting
[ssc_setting_id
];
700 case MT658X_FH_MM_PLL
:
701 FH_BUG_ON(ssc_setting_id
> (sizeof(mt_ssc_mmpll_setting
)/sizeof(struct freqhopping_ssc
)));
702 pSSC_setting
= &mt_ssc_mmpll_setting
[ssc_setting_id
];
704 case MT658X_FH_VENC_PLL
:
705 FH_BUG_ON(ssc_setting_id
> (sizeof(mt_ssc_vencpll_setting
)/sizeof(struct freqhopping_ssc
)));
706 pSSC_setting
= &mt_ssc_vencpll_setting
[ssc_setting_id
];
708 case MT658X_FH_MEM_PLL
:
709 FH_BUG_ON(ssc_setting_id
> (sizeof(mt_ssc_mempll_setting
)/sizeof(struct freqhopping_ssc
)));
710 pSSC_setting
= &mt_ssc_mempll_setting
[ssc_setting_id
];
713 case MT658X_FH_TVD_PLL
:
714 FH_BUG_ON(ssc_setting_id
> (sizeof(mt_ssc_tvdpll_setting
)/sizeof(struct freqhopping_ssc
)));
715 pSSC_setting
= &mt_ssc_tvdpll_setting
[ssc_setting_id
];
717 case MT658X_FH_LVDS_PLL
:
718 FH_BUG_ON(ssc_setting_id
> (sizeof(mt_ssc_lvdspll_setting
)/sizeof(struct freqhopping_ssc
)));
719 pSSC_setting
= &mt_ssc_lvdspll_setting
[ssc_setting_id
];
725 if(pSSC_setting
== NULL
){
726 FH_MSG("!!! pSSC_setting is NULL !!!");
727 //just disable FH & exit
728 __mt_disable_freqhopping(fh_ctl
->pll_id
,pSSC_setting
);
732 if( 0 == __mt_enable_freqhopping(fh_ctl
->pll_id
,pSSC_setting
)) {
737 FH_MSG("__mt_enable_freqhopping fail.");
742 else{ //disable req. hopping @ fh_ctl->pll_id
743 if( 0 == __mt_disable_freqhopping(fh_ctl
->pll_id
,pSSC_setting
)) {
748 FH_MSG("__mt_disable_freqhopping fail.");
762 //mempll 266->293MHz using FHCTL
763 static int mt_h2oc_mempll(void)
766 unsigned int fh_dds
=0;
767 unsigned int pll_dds
=0;
770 FH_MSG("EN: %s:%d",__func__
,g_curr_dramc
);
772 /*Please note that the DFS can¡¦t be applied in systems with DDR3 DRAM!
773 It¡¦s only for the mobile DRAM (LPDDR*)! */
775 if( (get_ddr_type() != LPDDR2
) && (get_ddr_type() != LPDDR3
) ) {
776 FH_MSG("Not LPDDR*");
780 if(g_curr_dramc
!= 266){
781 FH_MSG("g_curr_dramc != 266)");
785 FH_MSG("dds: %x",(DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ));
787 if((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ) != 0x131a2d){
788 FH_BUG_ON((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ) != 0x131a2d);
789 FH_MSG("DDS != 0x131a2d");
793 //TODO: provelock issue spin_lock(&freqhopping_lock);
794 spin_lock_irqsave(&freqhopping_lock
, flags
);
796 //disable SSC when OC
797 __mt_disable_freqhopping(2, NULL
);
799 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
){//only when SSC is enable
801 //Turn off MEMPLL hopping
802 fh_write32(REG_FHCTL2_CFG
, 0x70700000);
806 pll_dds
= (DRV_Reg32(DDRPHY_BASE
+0x624)) >> 11 ;
807 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
809 FH_MSG(">p:f< %x:%x",pll_dds
,fh_dds
);
811 while((pll_dds
!= fh_dds
) && ( i
< 100)){
813 if(unlikely(i
> 100)){
819 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
823 FH_MSG("<p:f:i> %x:%x:%d",pll_dds
,fh_dds
,i
);
826 FH_MSG("=> 0x%x",DRV_Reg32(REG_FHCTL2_MON
));
828 //TODO: provelock issue local_irq_save(flags);
830 //---------------------------------------------
831 //Overwrite MEMPLL NCPO setting in hopping SRAM
832 //---------------------------------------------
833 //Turn on SRAM CE, point to SRAM address of MEMPLL NCPO value 0
834 fh_write32(REG_FHSRAM_CON
, (0x1 << 9 | 0x80) );
836 //Target Freq. : NCPO INT : 84.165 (26MHz*84.165 = 2188.29 MHz, DRAMC = 293MHz)
837 //INT : 84 => 0x54 << 14
838 //FRACTION : 0.165 => 0x0A8F
839 fh_write32(REG_FHSRAM_WR
, ((0x54 << 14) | 0x0A8F) );
841 //-------------------------------------------------
842 // Turn on MEMPLL hopping and set slope < 2.5MHz/us
843 //-------------------------------------------------
844 //Only turn on 2G1 hopping
845 fh_write32(REG_FHCTL_CFG
, (1 << 8));
847 //Use 2G1 hopping table to DFS
848 //SW need fill 64¡¦b1 in 2G1 DRAM address (channel number = 0)
849 fh_write32(REG_FHDMA_2G1BASE
, __pa(g_mempll_fh_table
));
852 fh_write32(REG_FHCTL2_DDS
, (DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )|(1U<<31));
854 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL
, 1);
855 //fh_write32( PLL_HP_CON0, (fh_read32(PLL_HP_CON0) | (1 << 2)) );
859 //Configure hopping slope
860 //sfstr_dts[3:0] = 4¡¦d0(0.27us)
861 //sfstr_dys[3:0] = 4¡¦d9(0.023437500)
862 //slope = 26MHz * 0.007812500 / 0.27us = 0.75MHz/us < 2.5MHz/us
863 fh_write32(REG_FHCTL2_CFG
, ( (0 << 24) | (7 << 28) | 5));
865 //-------------------------------------------------
866 // Trigger 2G1 Hopping on channel number 0
867 //-------------------------------------------------
868 fh_write32(REG_FHCTL_2G1_CH
, 0);
872 //TODO: provelock issue local_irq_restore(flags);
874 FH_MSG("-MON- 0x%x",DRV_Reg32(REG_FHCTL2_MON
));
876 //TODO: provelock issue local_irq_save(flags);
878 fh_write32( DDRPHY_BASE
+0x624, (fh_read32(DDRPHY_BASE
+0x624) & 0x7FF) ); //clear NCPO
879 fh_write32( DDRPHY_BASE
+0x624, ( fh_read32(DDRPHY_BASE
+0x624) |(((0x54 << 14) | 0x0A8F ) << 11 )) ); //set NCPO
882 fh_write32(REG_FHCTL2_DDS
, (DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )|(1U<<31));
884 //Turn off MEMPLL hopping
885 fh_write32(REG_FHCTL2_CFG
, 0x70700000);
887 //TODO: provelock issue local_irq_restore(flags);
889 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
){
894 //switch back to APMIXED
896 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL
, 0);
897 //fh_write32( PLL_HP_CON0, (fh_read32(PLL_HP_CON0) & ~(1 << 2)) );
900 FH_MSG("+MON+ 0x%x",DRV_Reg32(REG_FHCTL2_MON
));
902 g_fh_pll
[MT658X_FH_MEM_PLL
].curr_freq
= 293000;
903 g_fh_pll
[MT658X_FH_MEM_PLL
].pll_status
= FH_PLL_ENABLE
;
905 //TODO: provelock issue spin_unlock(&freqhopping_lock);
906 spin_unlock_irqrestore(&freqhopping_lock
, flags
);
908 freqhopping_config(MT658X_FH_MEM_PLL
, 293000, true); //update freq.
913 //mempll 293->266MHz using FHCTL
914 static int mt_oc2h_mempll(void)
917 unsigned int fh_dds
=0;
918 unsigned int pll_dds
=0;
921 FH_MSG("EN: %s:%d",__func__
,g_curr_dramc
);
923 /*Please note that the DFS can¡¦t be applied in systems with DDR3 DRAM!
924 It¡¦s only for the mobile DRAM (LPDDR*)! */
926 if( (get_ddr_type() != LPDDR2
) && (get_ddr_type() != LPDDR3
) ) {
927 FH_MSG("Not LPDDR*");
931 if(g_curr_dramc
!= 293){
932 FH_MSG("g_curr_dramc != 293)");
936 FH_MSG("dds: %x",(DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ));
938 if((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ) != 0x150A8F){
939 FH_BUG_ON((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ) != 0x150A8F);
940 FH_MSG("DDS != 0x150A8F");
944 //TODO: provelock issue spin_lock(&freqhopping_lock);
945 spin_lock_irqsave(&freqhopping_lock
, flags
);
947 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
){//only when SSC is enable
949 //Turn off MEMPLL hopping
950 fh_write32(REG_FHCTL2_CFG
, 0x70700000);
954 pll_dds
= (DRV_Reg32(DDRPHY_BASE
+0x624)) >> 11 ;
955 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
957 FH_MSG(">p:f< %x:%x",pll_dds
,fh_dds
);
959 while((pll_dds
!= fh_dds
) && ( i
< 100)){
961 if(unlikely(i
> 100)){
967 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
971 FH_MSG("<p:f:i> %x:%x:%d",pll_dds
,fh_dds
,i
);
975 FH_MSG("=> 0x%x",DRV_Reg32(REG_FHCTL2_MON
));
977 //TODO: provelock issue local_irq_save(flags);
979 //---------------------------------------------
980 //Overwrite MEMPLL NCPO setting in hopping SRAM
981 //---------------------------------------------
982 //Turn on SRAM CE, point to SRAM address of MEMPLL NCPO value 0
983 fh_write32(REG_FHSRAM_CON
, (0x1 << 9 | 0x80) );
985 //Target Freq. : NCPO INT : 76.409 (26MHz*76.409 = 1986.63MHz, DRAMC = 266MHz)
986 //INT : 76 => 0x4C << 14
987 //FRACTION : 0.409 => 0x1A2D
988 fh_write32(REG_FHSRAM_WR
, ((0x4C << 14) | 0x1A2D) );
991 //-------------------------------------------------
992 // Turn on MEMPLL hopping and set slope < 2.5MHz/us
993 //-------------------------------------------------
994 //Only turn on 2G1 hopping
995 fh_write32(REG_FHCTL_CFG
, (1 << 8));
997 //Use 2G1 hopping table to DFS
998 //SW need fill 64¡¦b1 in 2G1 DRAM address (channel number = 0)
999 fh_write32(REG_FHDMA_2G1BASE
, __pa(g_mempll_fh_table
));
1002 fh_write32(REG_FHCTL2_DDS
, (DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )|(1U<<31));
1004 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL
, 1);
1005 //fh_write32( PLL_HP_CON0, (fh_read32(PLL_HP_CON0) | (1 << 2)) );
1009 //Configure hopping slope
1010 //sfstr_dts[3:0] = 4¡¦d0(0.27us)
1011 //sfstr_dys[3:0] = 4¡¦d9(0.023437500)
1012 //slope = 26MHz * 0.007812500 / 0.27us = 0.75MHz/us < 2.5MHz/us
1013 fh_write32(REG_FHCTL2_CFG
, ( (0 << 24) | (7 << 28) | 5));
1015 //-------------------------------------------------
1016 // Trigger 2G1 Hopping on channel number 0
1017 //-------------------------------------------------
1018 fh_write32(REG_FHCTL_2G1_CH
, 0);
1022 //TODO: provelock issue local_irq_restore(flags);
1024 FH_MSG("-MON- 0x%x",DRV_Reg32(REG_FHCTL2_MON
));
1026 //TODO: provelock issue local_irq_save(flags);
1027 fh_write32( DDRPHY_BASE
+0x624, (fh_read32(DDRPHY_BASE
+0x624) & 0x7FF) ); //clear NCPO
1028 fh_write32( DDRPHY_BASE
+0x624, ( fh_read32(DDRPHY_BASE
+0x624) |(((0x4C << 14) | 0x1A2D ) << 11 )) ); //set NCPO
1031 fh_write32(REG_FHCTL2_DDS
, (DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )|(1U<<31));
1033 //Turn off MEMPLL hopping
1034 fh_write32(REG_FHCTL2_CFG
, 0x70700000);
1035 //TODO: provelock issue local_irq_restore(flags);
1037 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
){
1042 //switch back to APMIXED
1044 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL
, 0);
1045 //fh_write32( PLL_HP_CON0, (fh_read32(PLL_HP_CON0) & ~(1 << 2)) );
1048 FH_MSG("+MON+ 0x%x",DRV_Reg32(REG_FHCTL2_MON
));
1049 g_fh_pll
[MT658X_FH_MEM_PLL
].curr_freq
= 266000;
1050 g_fh_pll
[MT658X_FH_MEM_PLL
].pll_status
= FH_PLL_ENABLE
;
1052 //TODO: provelock issue spin_unlock(&freqhopping_lock);
1053 spin_unlock_irqrestore(&freqhopping_lock
, flags
);
1055 freqhopping_config(MT658X_FH_MEM_PLL
, 266000, true); //update freq.
1060 //mempll 200->266MHz using FHCTL
1061 static int mt_fh_hal_l2h_mempll(void) //mempll low to high (200->266MHz)
1063 unsigned long flags
;
1064 unsigned int fh_dds
=0;
1065 unsigned int pll_dds
=0;
1068 FH_MSG("EN: %s:%d",__func__
,g_curr_dramc
);
1070 /*Please note that the DFS can¡¦t be applied in systems with DDR3 DRAM!
1071 It¡¦s only for the mobile DRAM (LPDDR*)! */
1073 if( (get_ddr_type() != LPDDR2
) && (get_ddr_type() != LPDDR3
) ) {
1074 FH_MSG("Not LPDDR*");
1078 if(g_curr_dramc
== 266){
1082 FH_MSG("dds: %x",(DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ));
1084 if((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ) != LOW_DRAMC_DDS
){
1085 FH_BUG_ON((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ) != LOW_DRAMC_DDS
);
1086 FH_MSG("DDS != 0x%X",LOW_DRAMC_DDS
);
1090 //TODO: provelock issue spin_lock(&freqhopping_lock);
1091 spin_lock_irqsave(&freqhopping_lock
, flags
);
1093 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
){//only when SSC is enable
1095 //Turn off MEMPLL hopping
1096 fh_write32(REG_FHCTL2_CFG
, 0x70700000);
1100 pll_dds
= (DRV_Reg32(DDRPHY_BASE
+0x624)) >> 11 ;
1101 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
1103 FH_MSG(">p:f< %x:%x",pll_dds
,fh_dds
);
1105 while((pll_dds
!= fh_dds
) && ( i
< 100)){
1107 if(unlikely(i
> 100)){
1113 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
1117 FH_MSG("<p:f:i> %x:%x:%d",pll_dds
,fh_dds
,i
);
1121 FH_MSG("=> 0x%x",DRV_Reg32(REG_FHCTL2_MON
));
1123 //TODO: provelock issue local_irq_save(flags);
1125 //---------------------------------------------
1126 //Overwrite MEMPLL NCPO setting in hopping SRAM
1127 //---------------------------------------------
1128 //Turn on SRAM CE, point to SRAM address of MEMPLL NCPO value 0
1129 fh_write32(REG_FHSRAM_CON
, (0x1 << 9 | 0x80) );
1131 //Target Freq. : NCPO INT : 76.409 (26MHz*76.409 = 1986.63MHz, DRAMC = 266MHz)
1132 //INT : 76 => 0x4C << 14
1133 //FRACTION : 0.409 => 0x1A2D
1134 fh_write32(REG_FHSRAM_WR
, ((0x4C << 14) | 0x1A2D) );
1137 //-------------------------------------------------
1138 // Turn on MEMPLL hopping and set slope < 2.5MHz/us
1139 //-------------------------------------------------
1140 //Only turn on 2G1 hopping
1141 fh_write32(REG_FHCTL_CFG
, (1 << 8));
1143 //Use 2G1 hopping table to DFS
1144 //SW need fill 64¡¦b1 in 2G1 DRAM address (channel number = 0)
1145 fh_write32(REG_FHDMA_2G1BASE
, __pa(g_mempll_fh_table
));
1148 fh_write32(REG_FHCTL2_DDS
, (DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )|(1U<<31));
1149 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL
, 1);
1150 //fh_write32( PLL_HP_CON0, (fh_read32(PLL_HP_CON0) | (1 << 2)) );
1154 //Configure hopping slope
1155 //sfstr_dts[3:0] = 4¡¦d0(0.27us)
1156 //sfstr_dys[3:0] = 4¡¦d9(0.023437500)
1157 //slope = 26MHz * 0.007812500 / 0.27us = 0.75MHz/us < 2.5MHz/us
1158 fh_write32(REG_FHCTL2_CFG
, ( (0 << 24) | (7 << 28) | 5));
1160 //-------------------------------------------------
1161 // Trigger 2G1 Hopping on channel number 0
1162 //-------------------------------------------------
1163 fh_write32(REG_FHCTL_2G1_CH
, 0);
1167 //TODO: provelock issue local_irq_restore(flags);
1169 FH_MSG("-MON- 0x%x",DRV_Reg32(REG_FHCTL2_MON
));
1171 //TODO: provelock issue local_irq_save(flags);
1172 fh_write32( DDRPHY_BASE
+0x624, (fh_read32(DDRPHY_BASE
+0x624) & 0x7FF) ); //clear NCPO
1173 fh_write32( DDRPHY_BASE
+0x624, ( fh_read32(DDRPHY_BASE
+0x624) |(((0x4C << 14) | 0x1A2D ) << 11 )) ); //set NCPO
1176 fh_write32(REG_FHCTL2_DDS
, (DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )|(1U<<31));
1178 //Turn off MEMPLL hopping
1179 fh_write32(REG_FHCTL2_CFG
, 0x70700000);
1180 //TODO: provelock issue local_irq_restore(flags);
1182 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
){
1187 //switch back to APMIXED
1189 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL
, 0);
1190 //fh_write32( PLL_HP_CON0, (fh_read32(PLL_HP_CON0) & ~(1 << 2)) );
1193 FH_MSG("+MON+ 0x%x",DRV_Reg32(REG_FHCTL2_MON
));
1194 g_fh_pll
[MT658X_FH_MEM_PLL
].curr_freq
= 266000;
1195 g_fh_pll
[MT658X_FH_MEM_PLL
].pll_status
= FH_PLL_ENABLE
;
1197 //TODO: provelock issue spin_unlock(&freqhopping_lock);
1198 spin_unlock_irqrestore(&freqhopping_lock
, flags
);
1200 freqhopping_config(MT658X_FH_MEM_PLL
, 266000, true); //update freq.
1205 //mempll 266->200MHz using FHCTL
1206 static int mt_fh_hal_h2l_mempll(void) //mempll low to high (200->266MHz)
1208 unsigned long flags
;
1209 unsigned int fh_dds
=0;
1210 unsigned int pll_dds
=0;
1213 FH_MSG("EN: %s:%d",__func__
,g_curr_dramc
);
1215 /*Please note that the DFS can¡¦t be applied in systems with DDR3 DRAM!
1216 It¡¦s only for the mobile DRAM (LPDDR*)! */
1218 if( (get_ddr_type() != LPDDR2
) && (get_ddr_type() != LPDDR3
) ) {
1219 FH_MSG("Not LPDDR*");
1223 if(g_curr_dramc
== LOW_DRAMC
){
1227 FH_MSG("dds: %x",(DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ));
1229 if((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ) != 0x131a2d){
1230 FH_BUG_ON((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ) != 0x131a2d);
1231 FH_MSG("DDS != 0x131a2d");
1235 //TODO: provelock issue spin_lock(&freqhopping_lock);
1236 spin_lock_irqsave(&freqhopping_lock
, flags
);
1238 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
){//only when SSC is enable
1240 //Turn off MEMPLL hopping
1241 fh_write32(REG_FHCTL2_CFG
, 0x70700000);
1245 pll_dds
= (DRV_Reg32(DDRPHY_BASE
+0x624)) >> 11 ;
1246 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
1248 FH_MSG(">p:f< %x:%x",pll_dds
,fh_dds
);
1250 while((pll_dds
!= fh_dds
) && ( i
< 100)){
1252 if(unlikely(i
> 100)){
1258 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
1262 FH_MSG("<p:f:i> %x:%x:%d",pll_dds
,fh_dds
,i
);
1265 FH_MSG("=> 0x%x",DRV_Reg32(REG_FHCTL2_MON
));
1267 //TODO: provelock issue local_irq_save(flags);
1269 //---------------------------------------------
1270 //Overwrite MEMPLL NCPO setting in hopping SRAM
1271 //---------------------------------------------
1272 //Turn on SRAM CE, point to SRAM address of MEMPLL NCPO value 0
1273 fh_write32(REG_FHSRAM_CON
, (0x1 << 9 | 0x80) );
1276 //Target Freq. : NCPO INT : 59.89 (26MHz*59.89 = 1557.14 MHz, DRAMC = 208.5MHz)
1277 //INT : 59 => 0x3B << 14
1278 //FRACTION : 0.89 => 0x38F5
1279 fh_write32(REG_FHSRAM_WR
, LOW_DRAMC_DDS
);
1282 //-------------------------------------------------
1283 // Turn on MEMPLL hopping and set slope < 2.5MHz/us
1284 //-------------------------------------------------
1285 //Only turn on 2G1 hopping
1286 fh_write32(REG_FHCTL_CFG
, (1 << 8));
1288 //Use 2G1 hopping table to DFS
1289 //SW need fill 64¡¦b1 in 2G1 DRAM address (channel number = 0)
1290 fh_write32(REG_FHDMA_2G1BASE
, __pa(g_mempll_fh_table
));
1293 fh_write32(REG_FHCTL2_DDS
, (DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )|(1U<<31));
1294 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL
, 1);
1295 //fh_write32( PLL_HP_CON0, (fh_read32(PLL_HP_CON0) | (1 << 2)) );
1299 //Configure hopping slope
1300 //sfstr_dts[3:0] = 4¡¦d0(0.27us)
1301 //sfstr_dys[3:0] = 4¡¦d9(0.023437500)
1302 //slope = 26MHz * 0.007812500 / 0.27us = 0.75MHz/us < 2.5MHz/us
1303 fh_write32(REG_FHCTL2_CFG
, ( (0 << 24) | (7 << 28) | 5));
1305 //-------------------------------------------------
1306 // Trigger 2G1 Hopping on channel number 0
1307 //-------------------------------------------------
1308 fh_write32(REG_FHCTL_2G1_CH
, 0);
1310 g_curr_dramc
= LOW_DRAMC
;
1312 //TODO: provelock issue local_irq_restore(flags);
1314 FH_MSG("-MON- 0x%x",DRV_Reg32(REG_FHCTL2_MON
));
1316 //TODO: provelock issue local_irq_save(flags);
1318 fh_write32( DDRPHY_BASE
+0x624, (fh_read32(DDRPHY_BASE
+0x624) & 0x7FF) ); //clear NCPO
1319 fh_write32( DDRPHY_BASE
+0x624, ( fh_read32(DDRPHY_BASE
+0x624) |(((LOW_DRAMC_INT
<< 14) | LOW_DRAMC_FRACTION
) << 11 )) ); //set NCPO
1322 fh_write32(REG_FHCTL2_DDS
, (DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )|(1U<<31));
1324 //Turn off MEMPLL hopping
1325 fh_write32(REG_FHCTL2_CFG
, 0x70700000);
1327 //TODO: provelock issue local_irq_restore(flags);
1329 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
){
1334 //switch back to APMIXED
1336 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL
, 0);
1337 //fh_write32( PLL_HP_CON0, (fh_read32(PLL_HP_CON0) & ~(1 << 2)) );
1340 FH_MSG("+MON+ 0x%x",DRV_Reg32(REG_FHCTL2_MON
));
1342 g_fh_pll
[MT658X_FH_MEM_PLL
].curr_freq
= LOW_DRAMC_FREQ
;
1343 g_fh_pll
[MT658X_FH_MEM_PLL
].pll_status
= FH_PLL_ENABLE
;
1345 //TODO: provelock issue spin_unlock(&freqhopping_lock);
1346 spin_unlock_irqrestore(&freqhopping_lock
, flags
);
1348 freqhopping_config(MT658X_FH_MEM_PLL
, LOW_DRAMC_FREQ
, true); //update freq.
1353 static int mt_fh_hal_dvfs(enum FH_PLL_ID pll_id
, unsigned int dds_value
)
1355 unsigned int fh_dds
=0;
1357 unsigned long flags
=0;
1358 unsigned int ilog
=1;
1359 FH_MSG("EN: %s:",__func__
);
1361 local_irq_save(flags
);
1363 //1. sync ncpo to DDS of FHCTL
1364 if (!(mt_fh_hal_sync_ncpo_to_FHCTL_DDS(pll_id
)))
1368 FH_MSG("1. sync ncpo to DDS of FHCTL");
1369 FH_MSG("FHCTL%d_DDS: 0x%08x", pll_id
, (fh_read32(REG_FHCTL0_DDS
+(pll_id
*0x14))&0x1FFFFF));
1372 //2. enable DVFS and Hopping control
1373 fh_set_field((REG_FHCTL0_CFG
+(pll_id
*0x14)), FH_SFSTRX_EN
, 1); //enable dvfs mode
1374 fh_set_field((REG_FHCTL0_CFG
+(pll_id
*0x14)), FH_FHCTLX_EN
, 1); //enable hopping control
1378 FH_MSG("2. enable DVFS and Hopping control");
1380 //3. switch to hopping control
1381 mt_fh_hal_switch_register_to_FHCTL_control(pll_id
,1);
1386 FH_MSG("3. switch to hopping control");
1387 FH_MSG("PLL_HP_CON0: 0x%08x",(fh_read32(PLL_HP_CON0
)&0x3F));
1391 fh_write32((REG_FHCTL0_DVFS
+(pll_id
*0x14)), (dds_value
)|(1U<<31)); //set dds
1395 FH_MSG("4. set DFS DDS");
1396 FH_MSG("FHCTL%d_DDS: 0x%08x", pll_id
, (fh_read32(REG_FHCTL0_DDS
+(pll_id
*0x14))&0x1FFFFF));
1397 FH_MSG("FHCTL%d_DVFS: 0x%08x", pll_id
, (fh_read32(REG_FHCTL0_DVFS
+(pll_id
*0x14))&0x1FFFFF));
1399 //4.1 ensure jump to target DDS
1400 fh_dds
= (DRV_Reg32(REG_FHCTL0_MON
+(pll_id
*0x14))) & 0x1FFFFF;
1401 while((dds_value
!= fh_dds
) && ( i
< 100)){
1403 if(unlikely(i
> 100)){
1409 fh_dds
= (DRV_Reg32(REG_FHCTL0_MON
+(pll_id
*0x14))) & 0x1FFFFF;
1415 FH_MSG("4.1 ensure jump to target DDS");
1419 //5. write back to ncpo
1423 FH_MSG("5. write back to ncpo");
1425 if (pll_id
==MT658X_FH_ARM_PLL
) //FHCTL0
1427 fh_write32(ARMPLL_CON1
, (fh_read32(REG_FHCTL0_DVFS
)&0x1FFFFF)|(fh_read32(ARMPLL_CON1
)&0xFFE00000)|(1U<<31));
1431 FH_MSG("ARMPLL_CON1: 0x%08x",(fh_read32(ARMPLL_CON1
)&0x1FFFFF));
1434 else if (pll_id
==MT658X_FH_MAIN_PLL
) //FHCTL1
1436 fh_write32(MAINPLL_CON1
, (fh_read32(REG_FHCTL1_DVFS
)&0x1FFFFF)|(fh_read32(MAINPLL_CON1
)&0xFFE00000)|(1U<<31));
1440 FH_MSG("MAINPLL_CON1: 0x%08x",(fh_read32(MAINPLL_CON1
)&0x1FFFFF));
1443 else if (pll_id
==MT658X_FH_MEM_PLL
) //FHCTL2
1445 fh_write32((DDRPHY_BASE
+0x624), ((fh_read32(REG_FHCTL2_DVFS
)&0x1FFFFF)<<11)|((DRV_Reg32(DDRPHY_BASE
+0x624))&0x7FF));
1449 FH_MSG("(DDRPHY_BASE+0x624): 0x%08x >>11: 0x%08x",(fh_read32(DDRPHY_BASE
+0x624)),(fh_read32(DDRPHY_BASE
+0x624)>>11));
1451 if ((fh_read32(DDRPHY_BASE
+0x624))&0x1)
1452 fh_write32((DDRPHY_BASE
+0x624),((fh_read32(DDRPHY_BASE
+0x624))&0xFFFFFFFE));
1454 fh_write32((DDRPHY_BASE
+0x624),((fh_read32(DDRPHY_BASE
+0x624))|0x1));
1458 FH_MSG("(DDRPHY_BASE+0x624): 0x%08x >>11: 0x%08x",(fh_read32(DDRPHY_BASE
+0x624)),(fh_read32(DDRPHY_BASE
+0x624)>>11));
1461 else if (pll_id
==MT658X_FH_MSDC_PLL
) //FHCTL3
1463 fh_write32(MSDCPLL_CON1
, (fh_read32(REG_FHCTL3_DVFS
)&0x1FFFFF)|(fh_read32(MSDCPLL_CON1
)&0xFFE00000)|(1U<<31));
1467 FH_MSG("MSDCPLL_CON1: 0x%08x",(fh_read32(MSDCPLL_CON1
)&0x1FFFFF));
1470 else if (pll_id
==MT658X_FH_MM_PLL
) //FHCTL4
1472 fh_write32(MMPLL_CON1
, (fh_read32(REG_FHCTL4_DVFS
)&0x1FFFFF)|(fh_read32(MMPLL_CON1
)&0xFFE00000)|(1U<<31));
1476 FH_MSG("MMPLL_CON1: 0x%08x",(fh_read32(MMPLL_CON1
)&0x1FFFFF));
1479 else if (pll_id
==MT658X_FH_VENC_PLL
) //FHCTL5
1481 fh_write32(VENCPLL_CON1
, (fh_read32(REG_FHCTL5_DVFS
)&0x1FFFFF)|(fh_read32(VENCPLL_CON1
)&0xFFE00000)|(1U<<31));
1485 FH_MSG("VENCPLL_CON1: 0x%08x",(fh_read32(VENCPLL_CON1
)&0x1FFFFF));
1489 else if (pll_id
==MT658X_FH_TVD_PLL
) //FHCTL3
1491 fh_write32(TVDPLL_CON1
, (fh_read32(REG_FHCTL3_DVFS
)&0x1FFFFF)|(fh_read32(TVDPLL_CON1
)&0xFFE00000)|(1U<<31));
1495 FH_MSG("TVDPLL_CON1: 0x%08x",(fh_read32(TVDPLL_CON1
)&0x1FFFFF));
1498 else if (pll_id
==MT658X_FH_LVDS_PLL
) //FHCTL3
1500 fh_write32(LVDSPLL_CON1
, (fh_read32(REG_FHCTL3_DVFS
)&0x1FFFFF)|(fh_read32(LVDSPLL_CON1
)&0xFFE00000)|(1U<<31));
1504 FH_MSG("LVDSPLL_CON1: 0x%08x",(fh_read32(LVDSPLL_CON1
)&0x1FFFFF));
1509 //6. switch to register control
1510 mt_fh_hal_switch_register_to_FHCTL_control(pll_id
,0);
1515 FH_MSG("6. switch to register control");
1516 FH_MSG("PLL_HP_CON0: 0x%08x",(fh_read32(PLL_HP_CON0
)&0x3F));
1519 local_irq_restore(flags
);
1523 static int mt_fh_hal_dfs_armpll(unsigned int current_freq
, unsigned int target_freq
) //armpll dfs mdoe
1525 unsigned long flags
;
1526 unsigned int target_dds
=0;
1528 FH_MSG("EN: %s:",__func__
);
1529 FH_MSG("current freq:%d target freq:%d", current_freq
, target_freq
);
1530 FH_MSG("current dds(ARMPLL_CON1): 0x%x",(fh_read32(ARMPLL_CON1
)&0x1FFFFF));
1532 //TODO: provelock issue spin_lock(&freqhopping_lock);
1533 spin_lock_irqsave(&freqhopping_lock
, flags
);
1535 fh_set_field(REG_FHCTL0_CFG
, FH_FRDDSX_EN
, 0); //disable SSC mode
1536 fh_set_field(REG_FHCTL0_CFG
, FH_SFSTRX_EN
, 0); //disable dvfs mode
1537 fh_set_field(REG_FHCTL0_CFG
, FH_FHCTLX_EN
, 0); //disable hopping control
1538 target_dds
= (((target_freq
/100) * (((fh_read32(ARMPLL_CON1
)&0x1FFFFF)*1000)/(current_freq
/100)))/1000);
1539 FH_MSG("target dds: 0x%x",target_dds
);
1541 mt_fh_hal_dvfs(MT658X_FH_ARM_PLL
, target_dds
);
1543 fh_set_field(REG_FHCTL0_CFG
, FH_FRDDSX_EN
, 0); //disable SSC mode
1544 fh_set_field(REG_FHCTL0_CFG
, FH_SFSTRX_EN
, 0); //disable dvfs mode
1545 fh_set_field(REG_FHCTL0_CFG
, FH_FHCTLX_EN
, 0); //disable hopping control
1546 spin_unlock_irqrestore(&freqhopping_lock
, flags
);
1550 static int mt_fh_hal_l2h_dvfs_mempll(void) //mempll low to high (200->266MHz)
1552 unsigned long flags
;
1553 unsigned int fh_dds
=0;
1554 unsigned int pll_dds
=0;
1557 FH_MSG("EN: %s:",__func__
);
1558 /*Please note that the DFS can¡¦t be applied in systems with DDR3 DRAM!
1559 It¡¦s only for the mobile DRAM (LPDDR*)! */
1561 if( (get_ddr_type() != LPDDR2
) && (get_ddr_type() != LPDDR3
) ) {
1562 FH_MSG("Not LPDDR*");
1566 FH_MSG("dds: 0x%x",(DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ));
1568 g_pll_mode
= (DRV_Reg32(DDRPHY_BASE
+0x60C) & 0x200);
1569 FH_MSG("g_pll_mode(0:1pll, 1:3pll): %x",g_pll_mode
);
1571 if (g_pll_mode
==0) // 1pll mode
1573 if ((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )==0x14030C)
1575 FH_MSG("Already @533MHz");
1579 FH_MSG("Jump to 533MHz");
1581 else if (g_pll_mode
==0x200) // 3pll mode
1583 if ((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )==0x131A2E)
1585 FH_MSG("Already @533MHz");
1589 FH_MSG("Jump to 533MHz");
1592 //TODO: provelock issue spin_lock(&freqhopping_lock);
1593 spin_lock_irqsave(&freqhopping_lock
, flags
);
1595 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
)
1596 {//only when SSC is enable
1597 //Turn off MEMPLL hopping
1598 fh_set_field(REG_FHCTL2_CFG
, FH_FRDDSX_EN
, 0); //disable SSC mode
1599 fh_set_field(REG_FHCTL2_CFG
, FH_SFSTRX_EN
, 0); //disable dvfs mode
1600 fh_set_field(REG_FHCTL2_CFG
, FH_FHCTLX_EN
, 0); //disable hopping control
1604 pll_dds
= (DRV_Reg32(REG_FHCTL2_DDS
)) & 0x1FFFFF;
1605 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
1607 FH_MSG(">p:f< %x:%x",pll_dds
,fh_dds
);
1609 while((pll_dds
!= fh_dds
) && ( i
< 100)){
1611 if(unlikely(i
> 100)){
1617 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
1621 FH_MSG("<p:f:i> %x:%x:%d",pll_dds
,fh_dds
,i
);
1625 if (g_pll_mode
==0) // 1pll mode
1626 mt_fh_hal_dvfs(MT658X_FH_MEM_PLL
, 0x14030C); //dfs 266.5MHz
1627 else if (g_pll_mode
==0x200) // 3pll mode
1628 mt_fh_hal_dvfs(MT658X_FH_MEM_PLL
, 0x131A2E); //dfs 266.5MHz
1632 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
)
1634 fh_set_field(REG_FHCTL2_CFG
, FH_FRDDSX_EN
, 0); //disable SSC mode
1635 fh_set_field(REG_FHCTL2_CFG
, FH_SFSTRX_EN
, 0); //disable dvfs mode
1636 fh_set_field(REG_FHCTL2_CFG
, FH_FHCTLX_EN
, 0); //disable hopping control
1638 if (!(mt_fh_hal_sync_ncpo_to_FHCTL_DDS(MT658X_FH_MEM_PLL
)))
1640 FH_MSG("1. sync ncpo to DDS of FHCTL");
1641 FH_MSG("FHCTL2_DDS: 0x%08x", (fh_read32(REG_FHCTL2_DDS
)&0x1FFFFF));
1643 fh_set_field(REG_FHCTL2_CFG
,FH_SFSTRX_DYS
,mt_ssc_mempll_setting
[2].df
);
1644 fh_set_field(REG_FHCTL2_CFG
,FH_SFSTRX_DTS
,mt_ssc_mempll_setting
[2].dt
);
1646 fh_write32(REG_FHCTL2_UPDNLMT
, (PERCENT_TO_DDSLMT((fh_read32(REG_FHCTL2_DDS
)&0x1FFFFF),mt_ssc_mempll_setting
[2].lowbnd
) << 16));
1647 FH_MSG("REG_FHCTL2_UPDNLMT: 0x%08x", fh_read32(REG_FHCTL2_UPDNLMT
));
1649 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL
,1);
1651 fh_set_field(REG_FHCTL2_CFG
, FH_FRDDSX_EN
, 1); //enable SSC mode
1652 fh_set_field(REG_FHCTL2_CFG
, FH_FHCTLX_EN
, 1); //enable hopping control
1653 FH_MSG("REG_FHCTL2_CFG: 0x%08x", fh_read32(REG_FHCTL2_CFG
));
1656 //TODO: provelock issue spin_unlock(&freqhopping_lock);
1657 spin_unlock_irqrestore(&freqhopping_lock
, flags
);
1662 static int mt_fh_hal_h2l_dvfs_mempll(void) //mempll high to low(266->200MHz)
1664 unsigned long flags
;
1665 unsigned int fh_dds
=0;
1666 unsigned int pll_dds
=0;
1669 FH_MSG("EN: %s:",__func__
);
1670 /*Please note that the DFS can¡¦t be applied in systems with DDR3 DRAM!
1671 It¡¦s only for the mobile DRAM (LPDDR*)! */
1673 if( (get_ddr_type() != LPDDR2
) && (get_ddr_type() != LPDDR3
) ) {
1674 FH_MSG("Not LPDDR*");
1678 FH_MSG("dds: 0x%x",(DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ));
1680 g_pll_mode
= (DRV_Reg32(DDRPHY_BASE
+0x60C) & 0x200);
1681 FH_MSG("g_pll_mode(0:1pll, 1:3pll): %x",g_pll_mode
);
1683 if (g_pll_mode
==0) // 1pll mode
1685 if ((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )==0x0F04B0)
1687 FH_MSG("Already @400MHz");
1691 FH_MSG("Jump to 400MHz");
1693 else if (g_pll_mode
==0x200) // 3pll mode
1695 if ((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )==0x0E55EE)
1697 FH_MSG("Already @400MHz");
1701 FH_MSG("Jump to 400MHz");
1704 //TODO: provelock issue spin_lock(&freqhopping_lock);
1705 spin_lock_irqsave(&freqhopping_lock
, flags
);
1707 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
)
1708 {//only when SSC is enable
1709 //Turn off MEMPLL hopping
1710 fh_set_field(REG_FHCTL2_CFG
, FH_FRDDSX_EN
, 0); //disable SSC mode
1711 fh_set_field(REG_FHCTL2_CFG
, FH_SFSTRX_EN
, 0); //disable dvfs mode
1712 fh_set_field(REG_FHCTL2_CFG
, FH_FHCTLX_EN
, 0); //disable hopping control
1716 pll_dds
= (DRV_Reg32(REG_FHCTL2_DDS
)) & 0x1FFFFF;
1717 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
1719 FH_MSG(">p:f< %x:%x",pll_dds
,fh_dds
);
1721 while((pll_dds
!= fh_dds
) && ( i
< 100)){
1723 if(unlikely(i
> 100)){
1729 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
1733 FH_MSG("<p:f:i> %x:%x:%d",pll_dds
,fh_dds
,i
);
1736 if (g_pll_mode
==0) // 1pll mode
1737 mt_fh_hal_dvfs(MT658X_FH_MEM_PLL
, 0x0F04B0); //dfs 200MHz
1738 else if (g_pll_mode
==0x200) // 3pll mode
1739 mt_fh_hal_dvfs(MT658X_FH_MEM_PLL
, 0x0E55EE); //dfs 200MHz
1743 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
)
1745 fh_set_field(REG_FHCTL2_CFG
, FH_FRDDSX_EN
, 0); //disable SSC mode
1746 fh_set_field(REG_FHCTL2_CFG
, FH_SFSTRX_EN
, 0); //disable dvfs mode
1747 fh_set_field(REG_FHCTL2_CFG
, FH_FHCTLX_EN
, 0); //disable hopping control
1749 if (!(mt_fh_hal_sync_ncpo_to_FHCTL_DDS(MT658X_FH_MEM_PLL
)))
1751 FH_MSG("Enable mempll SSC mode");
1752 FH_MSG("1. sync ncpo to DDS of FHCTL");
1753 FH_MSG("FHCTL2_DDS: 0x%08x", (fh_read32(REG_FHCTL2_DDS
)&0x1FFFFF));
1755 fh_set_field(REG_FHCTL2_CFG
,FH_SFSTRX_DYS
,mt_ssc_mempll_setting
[3].df
);
1756 fh_set_field(REG_FHCTL2_CFG
,FH_SFSTRX_DTS
,mt_ssc_mempll_setting
[3].dt
);
1758 fh_write32(REG_FHCTL2_UPDNLMT
, (PERCENT_TO_DDSLMT((fh_read32(REG_FHCTL2_DDS
)&0x1FFFFF),mt_ssc_mempll_setting
[3].lowbnd
) << 16));
1759 FH_MSG("REG_FHCTL2_UPDNLMT: 0x%08x", fh_read32(REG_FHCTL2_UPDNLMT
));
1761 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL
,1);
1763 fh_set_field(REG_FHCTL2_CFG
, FH_FRDDSX_EN
, 1); //enable SSC mode
1764 fh_set_field(REG_FHCTL2_CFG
, FH_FHCTLX_EN
, 1); //enable hopping control
1766 FH_MSG("REG_FHCTL2_CFG: 0x%08x", fh_read32(REG_FHCTL2_CFG
));
1769 //TODO: provelock issue spin_unlock(&freqhopping_lock);
1770 spin_unlock_irqrestore(&freqhopping_lock
, flags
);
1775 static int mt_h2oc_dfs_mempll(void)
1777 unsigned long flags
;
1778 unsigned int fh_dds
=0;
1779 unsigned int pll_dds
=0;
1782 FH_MSG("EN: %s:",__func__
);
1783 /*Please note that the DFS can¡¦t be applied in systems with DDR3 DRAM!
1784 It¡¦s only for the mobile DRAM (LPDDR*)! */
1786 if( (get_ddr_type() != LPDDR2
) && (get_ddr_type() != LPDDR3
) ) {
1787 FH_MSG("Not LPDDR*");
1791 FH_MSG("dds: 0x%x",(DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 ));
1793 g_pll_mode
= (DRV_Reg32(DDRPHY_BASE
+0x60C) & 0x200);
1794 FH_MSG("g_pll_mode(0:1pll, 1:3pll): %x",g_pll_mode
);
1796 if (g_pll_mode
==0) // 1pll mode
1798 if ((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )==0x160077)
1800 FH_MSG("Already @1172MHz");
1804 FH_MSG("Jump to 1172MHz");
1806 else if (g_pll_mode
==0x200) // 3pll mode
1808 if ((DRV_Reg32(DDRPHY_BASE
+0x624) >> 11 )==0x150071)
1810 FH_MSG("Already @1172MHz");
1814 FH_MSG("Jump to 1172MHz");
1817 //TODO: provelock issue spin_lock(&freqhopping_lock);
1818 spin_lock_irqsave(&freqhopping_lock
, flags
);
1820 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
)
1821 {//only when SSC is enable
1822 //Turn off MEMPLL hopping
1823 fh_set_field(REG_FHCTL2_CFG
, FH_FRDDSX_EN
, 0); //disable SSC mode
1824 fh_set_field(REG_FHCTL2_CFG
, FH_SFSTRX_EN
, 0); //disable dvfs mode
1825 fh_set_field(REG_FHCTL2_CFG
, FH_FHCTLX_EN
, 0); //disable hopping control
1829 pll_dds
= (DRV_Reg32(REG_FHCTL2_DDS
)) & 0x1FFFFF;
1830 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
1832 FH_MSG(">p:f< %x:%x",pll_dds
,fh_dds
);
1834 while((pll_dds
!= fh_dds
) && ( i
< 100)){
1836 if(unlikely(i
> 100)){
1842 fh_dds
= (DRV_Reg32(REG_FHCTL2_MON
)) & 0x1FFFFF;
1846 FH_MSG("<p:f:i> %x:%x:%d",pll_dds
,fh_dds
,i
);
1850 if (g_pll_mode
==0) // 1pll mode
1851 mt_fh_hal_dvfs(MT658X_FH_MEM_PLL
, 0x160077); //dfs293MHz
1852 else if (g_pll_mode
==0x200) // 3pll mode
1853 mt_fh_hal_dvfs(MT658X_FH_MEM_PLL
, 0x150071); //dfs 293MHz
1855 if(g_fh_pll
[MT658X_FH_MEM_PLL
].fh_status
== FH_FH_ENABLE_SSC
)
1857 fh_set_field(REG_FHCTL2_CFG
, FH_FRDDSX_EN
, 0); //disable SSC mode
1858 fh_set_field(REG_FHCTL2_CFG
, FH_SFSTRX_EN
, 0); //disable dvfs mode
1859 fh_set_field(REG_FHCTL2_CFG
, FH_FHCTLX_EN
, 0); //disable hopping control
1861 if (!(mt_fh_hal_sync_ncpo_to_FHCTL_DDS(MT658X_FH_MEM_PLL
)))
1863 FH_MSG("1. sync ncpo to DDS of FHCTL");
1864 FH_MSG("FHCTL2_DDS: 0x%08x", (fh_read32(REG_FHCTL2_DDS
)&0x1FFFFF));
1866 fh_set_field(REG_FHCTL2_CFG
,FH_SFSTRX_DYS
,mt_ssc_mempll_setting
[2].df
);
1867 fh_set_field(REG_FHCTL2_CFG
,FH_SFSTRX_DTS
,mt_ssc_mempll_setting
[2].dt
);
1869 fh_write32(REG_FHCTL2_UPDNLMT
, (PERCENT_TO_DDSLMT((fh_read32(REG_FHCTL2_DDS
)&0x1FFFFF),mt_ssc_mempll_setting
[2].lowbnd
) << 16));
1870 FH_MSG("REG_FHCTL2_UPDNLMT: 0x%08x", fh_read32(REG_FHCTL2_UPDNLMT
));
1872 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL
,1);
1874 fh_set_field(REG_FHCTL2_CFG
, FH_FRDDSX_EN
, 1); //enable SSC mode
1875 fh_set_field(REG_FHCTL2_CFG
, FH_FHCTLX_EN
, 1); //enable hopping control
1876 FH_MSG("REG_FHCTL2_CFG: 0x%08x", fh_read32(REG_FHCTL2_CFG
));
1879 //TODO: provelock issue spin_unlock(&freqhopping_lock);
1880 spin_unlock_irqrestore(&freqhopping_lock
, flags
);
1885 static int mt_fh_hal_dram_overclock(int clk
)
1887 FH_MSG("EN: %s clk:%d",__func__
,clk
);
1893 return(mt_fh_hal_h2l_dvfs_mempll());
1899 return(mt_fh_hal_l2h_dvfs_mempll());
1905 return(mt_h2oc_dfs_mempll());
1910 if( clk
== LOW_DRAMC
){ //target freq: 208.5MHz
1911 if( g_curr_dramc
!= 266 ){ //266 -> 208.5 only
1915 else{ //let's move from 266 to 208.5
1916 return(mt_fh_hal_h2l_mempll());
1920 if( clk
== 293){ //target freq: 293MHz
1921 if( g_curr_dramc
!= 266 ){ //266 -> 293 only
1925 else{ //let's move from 266 to 293
1926 return(mt_h2oc_mempll());
1930 if( clk
== 266){ ////target freq: 293MHz
1931 if( g_curr_dramc
== 266 ){ //cannot be 266 -> 266
1935 else if( g_curr_dramc
== LOW_DRAMC
){ //208 -> 266
1936 return(mt_fh_hal_l2h_mempll());
1938 else if( g_curr_dramc
== 293 ){ //293 -> 266
1939 return(mt_oc2h_mempll());
1947 static int mt_fh_hal_get_dramc(void)
1949 return(g_curr_dramc
);
1952 static void mt_fh_hal_popod_save(void)
1954 unsigned int fh_dds
=0;
1955 unsigned int pll_dds
=0;
1958 FH_MSG("EN: %s",__func__
);
1960 //disable maipll SSC mode
1961 if(g_fh_pll
[MT658X_FH_MAIN_PLL
].fh_status
== FH_FH_ENABLE_SSC
)//only when SSC is enable
1963 //Turn off MAINPLL hopping
1964 fh_set_field(REG_FHCTL1_CFG
, FH_FRDDSX_EN
, 0); //disable SSC mode
1965 fh_set_field(REG_FHCTL1_CFG
, FH_SFSTRX_EN
, 0); //disable dvfs mode
1966 fh_set_field(REG_FHCTL1_CFG
, FH_FHCTLX_EN
, 0); //disable hopping control
1970 pll_dds
= (DRV_Reg32(REG_FHCTL1_DDS
)) & 0x1FFFFF;
1971 fh_dds
= (DRV_Reg32(REG_FHCTL1_MON
)) & 0x1FFFFF;
1973 FH_MSG("Org pll_dds:%x fh_dds:%x",pll_dds
,fh_dds
);
1975 while((pll_dds
!= fh_dds
) && ( i
< 100))
1978 if(unlikely(i
> 100)){
1984 fh_dds
= (DRV_Reg32(REG_FHCTL1_MON
)) & 0x1FFFFF;
1988 FH_MSG("pll_dds:%x fh_dds:%x i:%d",pll_dds
,fh_dds
,i
);
1990 //write back to ncpo
1991 fh_write32(MAINPLL_CON1
, (fh_read32(REG_FHCTL1_DDS
)&0x1FFFFF)|(fh_read32(MAINPLL_CON1
)&0xFFE00000)|(1U<<31));
1992 FH_MSG("MAINPLL_CON1: 0x%08x",(fh_read32(MAINPLL_CON1
)&0x1FFFFF));
1994 // switch to register control
1995 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MAIN_PLL
,0);
1997 FH_MSG("switch to register control PLL_HP_CON0: 0x%08x",(fh_read32(PLL_HP_CON0
)&0x3F));
2003 static void mt_fh_hal_popod_restore(void)
2006 FH_MSG("EN: %s",__func__
);
2008 //enable maipll SSC mode
2009 if(g_fh_pll
[MT658X_FH_MAIN_PLL
].fh_status
== FH_FH_ENABLE_SSC
)
2011 fh_set_field(REG_FHCTL1_CFG
, FH_FRDDSX_EN
, 0); //disable SSC mode
2012 fh_set_field(REG_FHCTL1_CFG
, FH_SFSTRX_EN
, 0); //disable dvfs mode
2013 fh_set_field(REG_FHCTL1_CFG
, FH_FHCTLX_EN
, 0); //disable hopping control
2015 if (!(mt_fh_hal_sync_ncpo_to_FHCTL_DDS(MT658X_FH_MAIN_PLL
)))
2017 FH_MSG("Enable mainpll SSC mode");
2018 FH_MSG("sync ncpo to DDS of FHCTL");
2019 FH_MSG("FHCTL1_DDS: 0x%08x", (fh_read32(REG_FHCTL1_DDS
)&0x1FFFFF));
2021 fh_set_field(REG_FHCTL1_CFG
,FH_SFSTRX_DYS
,mt_ssc_mainpll_setting
[2].df
);
2022 fh_set_field(REG_FHCTL1_CFG
,FH_SFSTRX_DTS
,mt_ssc_mainpll_setting
[2].dt
);
2024 fh_write32(REG_FHCTL1_UPDNLMT
, (PERCENT_TO_DDSLMT((fh_read32(REG_FHCTL1_DDS
)&0x1FFFFF),mt_ssc_mainpll_setting
[2].lowbnd
) << 16));
2025 FH_MSG("REG_FHCTL1_UPDNLMT: 0x%08x", fh_read32(REG_FHCTL1_UPDNLMT
));
2027 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MAIN_PLL
,1);
2029 fh_set_field(REG_FHCTL1_CFG
, FH_FRDDSX_EN
, 1); //enable SSC mode
2030 fh_set_field(REG_FHCTL1_CFG
, FH_FHCTLX_EN
, 1); //enable hopping control
2032 FH_MSG("REG_FHCTL1_CFG: 0x%08x", fh_read32(REG_FHCTL1_CFG
));
2038 //static int freqhopping_dramc_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
2039 static int freqhopping_dramc_proc_read(struct seq_file
* m
, void* v
)
2044 FH_MSG("EN: %s",__func__
);
2046 seq_printf(m
, "DRAMC: %dMHz\r\n",g_curr_dramc
);
2047 seq_printf(m
, "mt_get_emi_freq(): %dHz\r\n",mt_get_emi_freq());
2048 seq_printf(m
, "get_ddr_type(): %d\r\n",get_ddr_type());
2049 seq_printf(m
, "rank: 0x%x\r\n",(DRV_Reg32(EMI_CONA
) & 0x20000));
2052 *start
= page
+ off
;
2061 return len
< count
? len
: count
;
2067 static int freqhopping_dramc_proc_write(struct file
*file
, const char *buffer
, unsigned long count
, void *data
)
2069 int len
= 0, freq
= 0;
2074 len
= (count
< (sizeof(dramc
) - 1)) ? count
: (sizeof(dramc
) - 1);
2076 if (copy_from_user(dramc
, buffer
, len
))
2078 FH_MSG("copy_from_user fail!");
2084 if (sscanf(dramc
, "%d", &freq
) == 1)
2086 if( (freq
== 266) || (freq
== 200)){
2087 FH_MSG("dramc:%d ", freq
);
2088 (freq
==266) ? mt_fh_hal_l2h_mempll() : mt_fh_hal_h2l_mempll();
2090 else if(freq
== 293){
2091 mt_fh_hal_dram_overclock(293);
2094 FH_MSG("must be 200/266/293!");
2099 FH_MSG("==> %d",mt_fh_hal_dram_overclock(266));
2101 else if(freq
== 293){
2102 FH_MSG("==> %d",mt_fh_hal_dram_overclock(293));
2104 else if(freq
== LOW_DRAMC
){
2105 FH_MSG("==> %d",mt_fh_hal_dram_overclock(208));
2113 FH_MSG(" bad argument!!");
2119 //static int freqhopping_dvfs_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
2120 static int freqhopping_dvfs_proc_read(struct seq_file
* m
, void* v
)
2126 FH_MSG("EN: %s",__func__
);
2128 seq_printf(m
, "DVFS:\r\n");
2129 seq_printf(m
, "CFG: 0x3 is SSC mode; 0x5 is DVFS mode \r\n");
2130 for(i
=0;i
<MT_FHPLL_MAX
;i
++) {
2131 seq_printf(m
, "FHCTL%d: CFG:0x%08x DVFS:0x%08x\r\n",i
, DRV_Reg32(REG_FHCTL0_CFG
+(i
*0x14)), DRV_Reg32(REG_FHCTL0_DVFS
+(i
*0x14)));
2135 *start
= page
+ off
;
2144 return len
< count
? len
: count
;
2150 static int freqhopping_dvfs_proc_write(struct file
*file
, const char *buffer
, unsigned long count
, void *data
)
2154 unsigned long len
= 0;
2155 unsigned int p1
,p2
,p3
,p4
,p5
;
2156 // struct freqhopping_ioctl fh_ctl;
2164 FH_MSG("EN: %s",__func__
);
2166 len
= min(count
, (unsigned long)(sizeof(kbuf
)-1));
2168 if (count
== 0)return -1;
2169 if(count
> 255)count
= 255;
2171 ret
= copy_from_user(kbuf
, buffer
, count
);
2172 if (ret
< 0)return -1;
2176 sscanf(kbuf
, "%d %d %d %d %d", &p1
, &p2
, &p3
, &p4
, &p5
);
2178 FH_MSG("EN: p1=%d p2=%d p3=%d", p1
, p2
, p3
);
2180 if (p1
==MT658X_FH_MEM_PLL
)
2183 mt_fh_hal_l2h_dvfs_mempll();
2185 mt_fh_hal_h2l_dvfs_mempll();
2187 mt_h2oc_dfs_mempll();
2189 FH_MSG("not define %d freq @mempll",p2
);
2191 else if (p1
==MT658X_FH_ARM_PLL
)
2193 mt_fh_hal_dfs_armpll(p2
, p3
);
2197 FH_MSG("EN: pllid=%d dt=%d df=%d lowbnd=%d", p2
, p3
, p4
, p5
);
2198 fh_set_field(REG_FHCTL0_CFG
+(p2
*0x14), FH_FRDDSX_EN
, 0); //disable SSC mode
2199 fh_set_field(REG_FHCTL0_CFG
+(p2
*0x14), FH_SFSTRX_EN
, 0); //disable dvfs mode
2200 fh_set_field(REG_FHCTL0_CFG
+(p2
*0x14), FH_FHCTLX_EN
, 0); //disable hopping control
2202 if (!(mt_fh_hal_sync_ncpo_to_FHCTL_DDS(p2
)))
2204 FH_MSG("Enable FHCTL%d SSC mode",p2
);
2205 FH_MSG("1. sync ncpo to DDS of FHCTL");
2206 FH_MSG("FHCTL%d_DDS: 0x%08x",p2
,(fh_read32(REG_FHCTL0_DDS
+(p2
*0x14))&0x1FFFFF));
2208 fh_set_field(REG_FHCTL0_CFG
+(p2
*0x14),FH_SFSTRX_DYS
,p4
);
2209 fh_set_field(REG_FHCTL0_CFG
+(p2
*0x14),FH_SFSTRX_DTS
,p3
);
2211 fh_write32(REG_FHCTL0_UPDNLMT
+(p2
*0x14), (PERCENT_TO_DDSLMT((fh_read32(REG_FHCTL0_DDS
+(p2
*0x14))&0x1FFFFF),p5
) << 16));
2212 FH_MSG("REG_FHCTL%d_UPDNLMT: 0x%08x",p2
, fh_read32(REG_FHCTL0_UPDNLMT
+(p2
*0x14)));
2214 mt_fh_hal_switch_register_to_FHCTL_control(p2
,1);
2216 fh_set_field(REG_FHCTL0_CFG
+(p2
*0x14), FH_FRDDSX_EN
, 1); //enable SSC mode
2217 fh_set_field(REG_FHCTL0_CFG
+(p2
*0x14), FH_FHCTLX_EN
, 1); //enable hopping control
2219 FH_MSG("REG_FHCTL%d_CFG: 0x%08x",p2
, fh_read32(REG_FHCTL0_CFG
+(p2
*0x14)));
2223 if (p2
==0) //disable
2224 mt_fh_hal_popod_save();
2225 else if (p2
==1) //enable
2226 mt_fh_hal_popod_restore();
2229 mt_fh_hal_dvfs(p1
, p2
);
2236 //static int freqhopping_dumpregs_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
2237 static int freqhopping_dumpregs_proc_read(struct seq_file
* m
, void* v
)
2243 FH_MSG("EN: %s",__func__
);
2245 seq_printf(m
, "FHDMA_CFG:\r\n");
2247 seq_printf(m
, "REG_FHDMA_CFG: 0x%08x 0x%08x 0x%08x 0x%08x\r\n",
2248 DRV_Reg32(REG_FHDMA_CFG
),
2249 DRV_Reg32(REG_FHDMA_2G1BASE
),
2250 DRV_Reg32(REG_FHDMA_2G2BASE
),
2251 DRV_Reg32(REG_FHDMA_INTMDBASE
));
2253 seq_printf(m
, "REG_FHDMA_EXTMDBASE: 0x%08x 0x%08x 0x%08x 0x%08x\r\n",
2254 DRV_Reg32(REG_FHDMA_EXTMDBASE
),
2255 DRV_Reg32(REG_FHDMA_BTBASE
),
2256 DRV_Reg32(REG_FHDMA_WFBASE
),
2257 DRV_Reg32(REG_FHDMA_FMBASE
));
2259 seq_printf(m
, "REG_FHSRAM_CON: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\r\n",
2260 DRV_Reg32(REG_FHSRAM_CON
),
2261 DRV_Reg32(REG_FHSRAM_WR
),
2262 DRV_Reg32(REG_FHSRAM_RD
),
2263 DRV_Reg32(REG_FHCTL_CFG
),
2264 DRV_Reg32(REG_FHCTL_CON
));
2266 seq_printf(m
, "REG_FHCTL_2G1_CH: 0x%08x 0x%08x 0x%08x 0x%08x\r\n",
2267 DRV_Reg32(REG_FHCTL_2G1_CH
),
2268 DRV_Reg32(REG_FHCTL_2G2_CH
),
2269 DRV_Reg32(REG_FHCTL_INTMD_CH
),
2270 DRV_Reg32(REG_FHCTL_EXTMD_CH
));
2272 seq_printf(m
, "REG_FHCTL_BT_CH: 0x%08x 0x%08x 0x%08x \r\n\r\n",
2273 DRV_Reg32(REG_FHCTL_BT_CH
),
2274 DRV_Reg32(REG_FHCTL_WF_CH
),
2275 DRV_Reg32(REG_FHCTL_FM_CH
));
2278 for(i
=0;i
<MT_FHPLL_MAX
;i
++) {
2280 seq_printf(m
, "FHCTL%d_CFG:\r\n",i
);
2281 seq_printf(m
, "0x%08x 0x%08x 0x%08x 0x%08x\r\n",
2282 DRV_Reg32(REG_FHCTL0_CFG
+(i
*0x14)),
2283 DRV_Reg32(REG_FHCTL0_UPDNLMT
+(i
*0x14)),
2284 DRV_Reg32(REG_FHCTL0_DDS
+(i
*0x14)),
2285 DRV_Reg32(REG_FHCTL0_MON
+(i
*0x14)));
2289 seq_printf(m
, "\r\nPLL_HP_CON0:\r\n0x%08x\r\n",
2290 DRV_Reg32(PLL_HP_CON0
));
2292 seq_printf(m
, "\r\nPLL_CON0 :\r\nARM:0x%08x MAIN:0x%08x MSDC:0x%08x MM:0x%08x VENC:0x%08x\r\n",
2293 DRV_Reg32(ARMPLL_CON0
),
2294 DRV_Reg32(MAINPLL_CON0
),
2295 DRV_Reg32(MSDCPLL_CON0
),
2296 DRV_Reg32(MMPLL_CON0
),
2297 DRV_Reg32(VENCPLL_CON0
));
2299 seq_printf(m
, "\r\nPLL_CON1 :\r\nARM:0x%08x MAIN:0x%08x MSDC:0x%08x MM:0x%08x VENC:0x%08x\r\n",
2300 DRV_Reg32(ARMPLL_CON1
),
2301 DRV_Reg32(MAINPLL_CON1
),
2302 DRV_Reg32(MSDCPLL_CON1
),
2303 DRV_Reg32(MMPLL_CON1
),
2304 DRV_Reg32(VENCPLL_CON1
));
2307 seq_printf(m
, "\r\nMEMPLL :\r\nMEMPLL9: 0x%08x MEMPLL10: 0x%08x MEMPLL11: 0x%08x MEMPLL12: 0x%08x\r\n",
2308 DRV_Reg32(DDRPHY_BASE
+0x624),
2309 DRV_Reg32(DDRPHY_BASE
+0x628),
2310 DRV_Reg32(DDRPHY_BASE
+0x62C),
2311 DRV_Reg32(DDRPHY_BASE
+0x630)); //TODO: Hard code for now...
2312 seq_printf(m
, "\r\nMEMPLL :\r\nMEMPLL13: 0x%08x MEMPLL14: 0x%08x MEMPLL15: 0x%08x MEMPLL16: 0x%08x\r\n",
2313 DRV_Reg32(DDRPHY_BASE
+0x634),
2314 DRV_Reg32(DDRPHY_BASE
+0x638),
2315 DRV_Reg32(DDRPHY_BASE
+0x63C),
2316 DRV_Reg32(DDRPHY_BASE
+0x640)); //TODO: Hard code for now...
2319 *start
= page
+ off
;
2328 return len
< count
? len
: count
;
2339 //static int freqhopping_clkgen_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
2340 static int freqhopping_clkgen_proc_read(struct seq_file
* m
, void* v
)
2345 FH_MSG("EN: %s",__func__
);
2347 if(g_curr_clkgen
> MT658X_FH_PLL_TOTAL_NUM
){
2348 seq_printf(m
, "no clkgen output.\r\n");
2351 seq_printf(m
, "clkgen:%d\r\n",g_curr_clkgen
);
2354 seq_printf(m
, "\r\nMBIST :\r\nMBIST_CFG_2: 0x%08x MBIST_CFG_6: 0x%08x MBIST_CFG_7: 0x%08x\r\n",
2355 DRV_Reg32(MBIST_CFG_2
),
2356 DRV_Reg32(MBIST_CFG_6
),
2357 DRV_Reg32(MBIST_CFG_7
));
2359 seq_printf(m
, "\r\nCLK_CFG_3: 0x%08x\r\n",
2360 DRV_Reg32(CLK_CFG_3
));
2362 seq_printf(m
, "\r\nTOP_CKMUXSEL: 0x%08x\r\n",
2363 DRV_Reg32(TOP_CKMUXSEL
));
2365 seq_printf(m
, "\r\nGPIO: 0x%08x 0x%08x 0x%08x 0x%08x\r\n",
2366 DRV_Reg32(GPIO_BASE
+0xC60),
2367 DRV_Reg32(GPIO_BASE
+0xC70),
2368 DRV_Reg32(GPIO_BASE
+0xCD0),
2369 DRV_Reg32(GPIO_BASE
+0xD90));
2372 seq_printf(m
, "\r\nDDRPHY_BASE :\r\n0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\r\n",
2373 DRV_Reg32(DDRPHY_BASE
+0x600),
2374 DRV_Reg32(DDRPHY_BASE
+0x604),
2375 DRV_Reg32(DDRPHY_BASE
+0x608),
2376 DRV_Reg32(DDRPHY_BASE
+0x60C),
2377 DRV_Reg32(DDRPHY_BASE
+0x614),
2378 DRV_Reg32(DDRPHY_BASE
+0x61C));
2380 *start
= page
+ off
;
2389 return len
< count
? len
: count
;
2395 static int freqhopping_clkgen_proc_write(struct file
*file
, const char *buffer
, unsigned long count
, void *data
)
2397 int len
= 0, pll_id
= 0;
2400 FH_MSG("EN: %s",__func__
);
2402 len
= (count
< (sizeof(clkgen
) - 1)) ? count
: (sizeof(clkgen
) - 1);
2404 //if you want to measue the clk by evb, you should turn on GPIO34.
2405 //mt_set_gpio_mode(GPIO34, GPIO_MODE_03);
2407 if (copy_from_user(clkgen
, buffer
, len
))
2409 FH_MSG("copy_from_user fail!");
2415 if (sscanf(clkgen
, "%d", &pll_id
) == 1)
2417 if(pll_id
== MT658X_FH_ARM_PLL
){
2418 fh_write32(MBIST_CFG_2
, 0x00000009); //divide by 9+1
2419 fh_write32(CLK_CFG_3
, 0x00000001); //enable it
2421 fh_write32(CLK_CFG_3
, 0x00000001); //pll_pre_clk [don't care @ ARMPLL]
2423 fh_write32(CLK_CFG_3
, 0x00000001); //pll_clk_sel [don't care @ ARMPLL]
2425 fh_write32(CLK_CFG_3
, 0x00000401); //abist_clk_sel [0100: armpll_occ_mon]
2429 else if(pll_id
== MT658X_FH_MAIN_PLL
){
2430 fh_write32(MBIST_CFG_2
, 0x00000009); //divide by 9+1
2431 fh_write32(CLK_CFG_3
, 0x00000001); //enable it
2433 fh_write32(CLK_CFG_3
, 0x000F0001); //pll_pre_clk [1111: AD_MAIN_H230P3M]
2435 fh_write32(CLK_CFG_3
, 0x000F0001); //pll_clk_sel [0000: pll_pre_clk]
2437 fh_write32(CLK_CFG_3
, 0x000F0F01); //abist_clk_sel [1111: pll_clk_out]
2441 else if(pll_id
== MT658X_FH_MEM_PLL
){
2443 fh_write32(DDRPHY_BASE
+0x600, ( (DRV_Reg32(DDRPHY_BASE
+0x600)) | 0x1<<5));
2446 fh_write32(DDRPHY_BASE
+0x60C, ( (DRV_Reg32(DDRPHY_BASE
+0x60C)) | 0x1<<21));
2447 fh_write32(DDRPHY_BASE
+0x614, ( (DRV_Reg32(DDRPHY_BASE
+0x614)) | 0x1<<21));
2448 fh_write32(DDRPHY_BASE
+0x61C, ( (DRV_Reg32(DDRPHY_BASE
+0x61C)) | 0x1<<21));
2450 fh_write32(DDRPHY_BASE
+0x60C, ( (DRV_Reg32(DDRPHY_BASE
+0x60C)) & ~0x7));
2451 fh_write32(DDRPHY_BASE
+0x60C, ( (DRV_Reg32(DDRPHY_BASE
+0x60C)) | 0x2 ));
2452 fh_write32(DDRPHY_BASE
+0x614, ( (DRV_Reg32(DDRPHY_BASE
+0x614)) & ~0x7));
2453 fh_write32(DDRPHY_BASE
+0x614, ( (DRV_Reg32(DDRPHY_BASE
+0x614)) | 0x2 ));
2454 fh_write32(DDRPHY_BASE
+0x61C, ( (DRV_Reg32(DDRPHY_BASE
+0x61C)) & ~0x7));
2455 fh_write32(DDRPHY_BASE
+0x61C, ( (DRV_Reg32(DDRPHY_BASE
+0x61C)) | 0x2));
2457 fh_write32(DDRPHY_BASE
+0x604, ( (DRV_Reg32(DDRPHY_BASE
+0x604)) | 0x1<<3));
2458 fh_write32(DDRPHY_BASE
+0x604, ( (DRV_Reg32(DDRPHY_BASE
+0x604)) | 0x1<<7));
2459 fh_write32(DDRPHY_BASE
+0x604, ( (DRV_Reg32(DDRPHY_BASE
+0x604)) | 0x1<<4));
2460 fh_write32(DDRPHY_BASE
+0x604, ( (DRV_Reg32(DDRPHY_BASE
+0x604)) | 0x1<<9));
2463 fh_write32(DDRPHY_BASE
+0x608, ( (DRV_Reg32(DDRPHY_BASE
+0x608)) & ~0x000E0000 ));
2465 fh_write32(DDRPHY_BASE
+0x608, ( (DRV_Reg32(DDRPHY_BASE
+0x608)) | 0x00040000 ));
2467 fh_write32(DDRPHY_BASE
+0x608, ( (DRV_Reg32(DDRPHY_BASE
+0x608)) & ~0xF0000000 ));
2468 fh_write32(DDRPHY_BASE
+0x608, ( (DRV_Reg32(DDRPHY_BASE
+0x608)) | 0x80000000 ));
2470 //fh_write32(MBIST_CFG_2, 0x00000001); //divide by 1+1
2471 fh_write32(CLK_CFG_3
, 0x00000001); //enable it
2473 fh_write32(CLK_CFG_3
, 0x00000001); //pll_pre_clk [don't care @ ARMPLL]
2475 fh_write32(CLK_CFG_3
, 0x00000001); //pll_clk_sel [don't care @ ARMPLL]
2477 fh_write32(CLK_CFG_3
, 0x00000501); //abist_clk_sel [0101: AD_MEMPLL_MONCLK]
2481 else if(pll_id
== MT658X_FH_MSDC_PLL
){
2483 fh_write32(MBIST_CFG_2
, 0x00000009); //divide by 9+1
2485 fh_write32(CLK_CFG_3
, 0x00000001); //enable it
2487 fh_write32(CLK_CFG_3
, 0x00080001); //pll_pre_clk [1000: AD_MSDCPLL_H208M]
2489 fh_write32(CLK_CFG_3
, 0x00080001); //pll_clk_sel [0000: pll_pre_clk]
2491 fh_write32(CLK_CFG_3
, 0x00080F01); //abist_clk_sel [1111: pll_clk_out]
2495 else if(pll_id
== MT658X_FH_MM_PLL
){
2496 fh_write32(MBIST_CFG_2
, 0x00000009); //divide by 9+1
2498 fh_write32(CLK_CFG_3
, 0x00000001); //enable it
2500 fh_write32(CLK_CFG_3
, 0x00090001); //pll_pre_clk [1001: AD_TVHDMI_H_CK]
2502 fh_write32(CLK_CFG_3
, 0x00090001); //pll_clk_sel [0000: pll_pre_clk]
2504 fh_write32(CLK_CFG_3
, 0x00090F01); //abist_clk_sel [1111: pll_clk_out]
2508 else if(pll_id
== MT658X_FH_VENC_PLL
){
2509 fh_write32(MBIST_CFG_2
, 0x00000009); //divide by 9+1
2511 fh_write32(CLK_CFG_3
, 0x00000001); //enable it
2513 fh_write32(CLK_CFG_3
, 0x000A0001); //pll_pre_clk [1010: AD_LVDS_H180M_CK]
2515 fh_write32(CLK_CFG_3
, 0x000A0001); //pll_clk_sel [0000: pll_pre_clk]
2517 fh_write32(CLK_CFG_3
, 0x000A0F01); //abist_clk_sel [1111: pll_clk_out]
2524 FH_MSG(" bad argument!!");
2527 g_curr_clkgen
= pll_id
;
2534 #endif //MT_FH_CLK_GEN
2535 //TODO: __init void mt_freqhopping_init(void)
2536 static void mt_fh_hal_init(void)
2540 unsigned long flags
;
2542 FH_MSG("EN: %s",__func__
);
2544 if(g_initialize
== 1){
2545 FH_MSG("already init!");
2549 //init hopping table for mempll 200<->266
2550 memset(g_mempll_fh_table
, 0, sizeof(g_mempll_fh_table
));
2553 for(i
=0;i
<MT_FHPLL_MAX
;i
++) {
2555 //TODO: use the g_fh_pll[] to init the FHCTL
2556 spin_lock_irqsave(&freqhopping_lock
, flags
);
2558 g_fh_pll
[i
].setting_id
= 0;
2560 fh_write32(REG_FHCTL0_CFG
+(i
*0x14), 0x00000000); //No SSC and FH enabled
2561 fh_write32(REG_FHCTL0_UPDNLMT
+(i
*0x14), 0x00000000); //clear all the settings
2562 fh_write32(REG_FHCTL0_DDS
+(i
*0x14), 0x00000000); //clear all the settings
2564 //TODO: do we need this
2565 //fh_write32(REG_FHCTL0_MON+(i*0x10), 0x00000000); //clear all the settings
2567 spin_unlock_irqrestore(&freqhopping_lock
, flags
);
2570 //TODO: update each PLL status (go through g_fh_pll)
2571 //TODO: wait for sophie's table & query the EMI clock
2572 //TODO: ask sophie to call this init function during her init call (mt_clkmgr_init() ??)
2573 //TODO: call __freqhopping_ctrl() to init each pll
2577 //register change. enable_clock(MT_CG_PERI1_FHCTL, "FREQHOP") ;
2581 static void mt_fh_hal_lock(unsigned long *flags
)
2583 spin_lock_irqsave(&freqhopping_lock
, *flags
);
2586 static void mt_fh_hal_unlock(unsigned long *flags
)
2588 spin_unlock_irqrestore(&freqhopping_lock
, *flags
);
2591 static int mt_fh_hal_get_init(void)
2593 return(g_initialize
);
2596 static int mt_fh_hal_is_support_DFS_mode(void)
2601 //TODO: module_init(mt_freqhopping_init);
2602 //TODO: module_init(mt_freqhopping_init);
2603 //TODO: module_exit(cpufreq_exit);
2605 static struct mt_fh_hal_driver g_fh_hal_drv
;
2607 struct mt_fh_hal_driver
*mt_get_fh_hal_drv(void)
2609 memset(&g_fh_hal_drv
, 0, sizeof(g_fh_hal_drv
));
2611 g_fh_hal_drv
.fh_pll
= g_fh_pll
;
2612 g_fh_hal_drv
.fh_usrdef
= mt_ssc_fhpll_userdefined
;
2613 g_fh_hal_drv
.pll_cnt
= MT658X_FH_PLL_TOTAL_NUM
;
2614 g_fh_hal_drv
.mempll
= MT658X_FH_MEM_PLL
;
2615 g_fh_hal_drv
.mainpll
= MT658X_FH_MAIN_PLL
;
2616 g_fh_hal_drv
.msdcpll
= MT658X_FH_MSDC_PLL
;
2617 g_fh_hal_drv
.mmpll
= MT658X_FH_MM_PLL
;
2618 g_fh_hal_drv
.vencpll
= MT658X_FH_VENC_PLL
;
2620 g_fh_hal_drv
.lvdspll
= MT658X_FH_LVDS_PLL
;
2623 g_fh_hal_drv
.mt_fh_hal_init
= mt_fh_hal_init
;
2626 g_fh_hal_drv
.proc
.clk_gen_read
= freqhopping_clkgen_proc_read
;
2627 g_fh_hal_drv
.proc
.clk_gen_write
= freqhopping_clkgen_proc_write
;
2630 g_fh_hal_drv
.proc
.dramc_read
= freqhopping_dramc_proc_read
;
2631 g_fh_hal_drv
.proc
.dramc_write
= freqhopping_dramc_proc_write
;
2632 g_fh_hal_drv
.proc
.dumpregs_read
= freqhopping_dumpregs_proc_read
;
2634 g_fh_hal_drv
.proc
.dvfs_read
= freqhopping_dvfs_proc_read
;
2635 g_fh_hal_drv
.proc
.dvfs_write
= freqhopping_dvfs_proc_write
;
2637 g_fh_hal_drv
.mt_fh_hal_ctrl
= __freqhopping_ctrl
;
2638 g_fh_hal_drv
.mt_fh_lock
= mt_fh_hal_lock
;
2639 g_fh_hal_drv
.mt_fh_unlock
= mt_fh_hal_unlock
;
2640 g_fh_hal_drv
.mt_fh_get_init
= mt_fh_hal_get_init
;
2642 g_fh_hal_drv
.mt_fh_popod_restore
= mt_fh_hal_popod_restore
;
2643 g_fh_hal_drv
.mt_fh_popod_save
= mt_fh_hal_popod_save
;
2645 g_fh_hal_drv
.mt_l2h_mempll
= mt_fh_hal_l2h_mempll
;
2646 g_fh_hal_drv
.mt_h2l_mempll
= mt_fh_hal_h2l_mempll
;
2647 g_fh_hal_drv
.mt_l2h_dvfs_mempll
= mt_fh_hal_l2h_dvfs_mempll
;
2648 g_fh_hal_drv
.mt_h2l_dvfs_mempll
= mt_fh_hal_h2l_dvfs_mempll
;
2649 g_fh_hal_drv
.mt_dfs_armpll
= mt_fh_hal_dfs_armpll
;
2650 g_fh_hal_drv
.mt_is_support_DFS_mode
= mt_fh_hal_is_support_DFS_mode
;
2651 g_fh_hal_drv
.mt_dram_overclock
= mt_fh_hal_dram_overclock
;
2652 g_fh_hal_drv
.mt_get_dramc
= mt_fh_hal_get_dramc
;
2653 g_fh_hal_drv
.mt_fh_default_conf
= mt_fh_hal_default_conf
;
2655 return (&g_fh_hal_drv
);
2657 //TODO: module_exit(cpufreq_exit);