import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-mt8127 / mt_freqhopping.c
1 /*
2 * Copyright (C) 2011 MediaTek, Inc.
3 *
4 * Author: Holmes Chiou <holmes.chiou@mediatek.com>
5 *
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.
9 *
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.
14 *
15 */
16
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>
24 #include <linux/io.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>
32
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"
43
44 #include <mach/mt_freqhopping_drv.h>
45
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
49
50 #define MT_FH_CLK_GEN 0
51
52 #define USER_DEFINE_SETTING_ID 1
53
54 static DEFINE_SPINLOCK(freqhopping_lock);
55
56
57 //current DRAMC@mempll
58 static unsigned int g_curr_dramc=266; //default @266MHz ==> LPDDR2/DDR3 data rate 1066
59
60 //mempll mode
61 static unsigned int g_pll_mode;
62
63 #define PERCENT_TO_DDSLMT(dDS, pERCENT_M10) ((dDS * pERCENT_M10 >> 5) / 100)
64 #if MT_FH_CLK_GEN
65 static unsigned int g_curr_clkgen=MT658X_FH_PLL_TOTAL_NUM+1; //default clkgen ==> no clkgen output
66 #endif
67
68 static unsigned char g_mempll_fh_table[8];
69
70 static unsigned int g_initialize=0;
71
72 static unsigned int g_clk_en=0;
73
74 #ifndef PER_PROJECT_FH_SETTING
75
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
81
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
85 #if (MAINPLL_SSC)
86 {FH_FH_ENABLE_SSC, FH_PLL_ENABLE , 0, 1612000 , 0}, //MAINPLL default SSC disable
87 #else
88 {FH_FH_DISABLE, FH_PLL_ENABLE , 0, 1612000 , 0}, //MAINPLL default SSC disable
89 #endif
90 #if (MEMPLL_SSC)
91 {FH_FH_ENABLE_SSC, FH_PLL_ENABLE , 0, 266000 , 0}, //MEMPLL default SSC enable
92 #else
93 {FH_FH_DISABLE, FH_PLL_ENABLE , 0, 266000 , 0}, //MEMPLL default SSC enable
94 #endif
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
98 /* 8127 FHCTL MB */
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
101 /* 8127 FHCTL ME */
102 };
103
104
105
106 //ARMPLL
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
110 {0,0,0,0,0,0} //EOF
111 };
112
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
116 #if 0
117 {1612000 ,2 ,7 ,0, 4, 0xA8000},// 0~-4%
118 #else
119 {1612000 ,0 ,9 ,0, 8, 0xA8000},// 0~-8%
120 #endif
121 {0,0,0,0,0,0} //EOF
122 };
123
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%
129 {0,0,0,0,0,0} //EOF
130 };
131
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))
136 {0,0,0,0,0,0} //EOF
137
138 };
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))
143 {0,0,0,0,0,0} //EOF
144 };
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))
149 {0,0,0,0,0,0} //EOF
150 };
151
152 /* 8127 FHCTL MB */
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%
157 {0,0,0,0,0,0} //EOF
158 };
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%
163 {0,0,0,0,0,0} //EOF
164 };
165
166 /* 8127 FHCTL ME */
167
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
175 };
176
177 #else //PER_PROJECT_FH_SETTING
178
179 PER_PROJECT_FH_SETTING
180
181 #endif //PER_PROJECT_FH_SETTING
182
183 unsigned int mt_get_emi_freq(void);
184
185 #define PLL_STATUS_ENABLE 1
186 #define PLL_STATUS_DISABLE 0
187
188 static void mt_fh_hal_default_conf(void)
189 {
190 FH_MSG("EN: %s",__func__);
191 #if (MEMPLL_SSC)
192 freqhopping_config(MT658X_FH_MEM_PLL, 266000, true); //Enable MEMPLL SSC
193 #endif
194 freqhopping_config(MT658X_FH_MM_PLL, 1188000, true); //TODO: test only
195 freqhopping_config(MT658X_FH_VENC_PLL, 1200000, true); //TODO: test only
196 #if (MAINPLL_SSC)
197 freqhopping_config(MT658X_FH_MAIN_PLL, 1612000, true); //TODO: test only
198 #endif
199 freqhopping_config(MT658X_FH_MSDC_PLL, 1599000, true); //TODO: test only
200 }
201
202
203 static void mt_fh_hal_switch_register_to_FHCTL_control(enum FH_PLL_ID pll_id, int i_control)
204 {
205 if (pll_id==MT658X_FH_ARM_PLL) //FHCTL0
206 {
207 fh_set_field(PLL_HP_CON0, (0x1U<<0), i_control);
208 }
209 else if (pll_id==MT658X_FH_MAIN_PLL) //FHCTL1
210 {
211 fh_set_field(PLL_HP_CON0, (0x1U<<1), i_control);
212 }
213 else if (pll_id==MT658X_FH_MEM_PLL) //FHCTL2
214 {
215 fh_set_field(PLL_HP_CON0, (0x1U<<3), i_control);
216 }
217 else if (pll_id==MT658X_FH_MSDC_PLL) //FHCTL3
218 {
219 fh_set_field(PLL_HP_CON0, (0x1U<<4), i_control);
220 }
221 else if (pll_id==MT658X_FH_MM_PLL) //FHCTL4
222 {
223 fh_set_field(PLL_HP_CON0, (0x1U<<2), i_control);
224 }
225 else if (pll_id==MT658X_FH_VENC_PLL) //FHCTL5
226 {
227 fh_set_field(PLL_HP_CON0, (0x1U<<5), i_control);
228 }
229 /* 8127 FHCTL MB */
230 else if (pll_id==MT658X_FH_TVD_PLL) //FHCTL6
231 {
232 fh_set_field(PLL_HP_CON0, (0x1U<<6), i_control);
233 }
234 else if (pll_id==MT658X_FH_LVDS_PLL) //FHCTL7
235 {
236 fh_set_field(PLL_HP_CON0, (0x1U<<7), i_control);
237 }
238 /* 8127 FHCTL ME */
239 }
240 static int mt_fh_hal_sync_ncpo_to_FHCTL_DDS(enum FH_PLL_ID pll_id)
241 {
242 if (pll_id==MT658X_FH_ARM_PLL) //FHCTL0
243 {
244 fh_write32(REG_FHCTL0_DDS, (fh_read32(ARMPLL_CON1)&0x1FFFFF)|(1U<<31));
245 }
246 else if (pll_id==MT658X_FH_MAIN_PLL) //FHCTL1
247 {
248 fh_write32(REG_FHCTL1_DDS, (fh_read32(MAINPLL_CON1)&0x1FFFFF)|(1U<<31));
249 }
250 else if (pll_id==MT658X_FH_MEM_PLL) //FHCTL2
251 {
252 fh_write32(REG_FHCTL2_DDS, ((DRV_Reg32(DDRPHY_BASE+0x624) >> 11 )&0x1FFFFF)|(1U<<31));
253 }
254 else if (pll_id==MT658X_FH_MSDC_PLL) //FHCTL3
255 {
256 fh_write32(REG_FHCTL3_DDS, (fh_read32(MSDCPLL_CON1)&0x1FFFFF)|(1U<<31));
257 }
258 else if (pll_id==MT658X_FH_MM_PLL) //FHCTL4
259 {
260 fh_write32(REG_FHCTL4_DDS, (fh_read32(MMPLL_CON1)&0x1FFFFF)|(1U<<31));
261 }
262 else if (pll_id==MT658X_FH_VENC_PLL) //FHCTL5
263 {
264 fh_write32(REG_FHCTL5_DDS, (fh_read32(VENCPLL_CON1)&0x1FFFFF)|(1U<<31));
265 }
266 /* 8127 FHCTL MB */
267 else if (pll_id==MT658X_FH_TVD_PLL) //FHCTL6
268 {
269 fh_write32(REG_FHCTL6_DDS, (fh_read32(TVDPLL_CON1)&0x1FFFFF)|(1U<<31));
270 }
271 else if (pll_id==MT658X_FH_LVDS_PLL) //FHCTL7
272 {
273 fh_write32(REG_FHCTL7_DDS, (fh_read32(LVDSPLL_CON1)&0x1FFFFF)|(1U<<31));
274 }
275 /* 8127 FHCTL ME */
276 else
277 {
278 FH_MSG("Incorrect PLL");
279 return 0;
280 }
281 return 1;
282 }
283 static void update_fhctl_status(const int pll_id, const int enable)
284 {
285 int i = 0 ;
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
294 } ;
295
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
300 return ;
301 }
302
303 pll_status[pll_id] = enable ;
304
305 for(i = MT658X_FH_MINIMUMM_PLL ; i <= MT658X_FH_MAXIMUMM_PLL ; i++) {
306
307 if(pll_status[i] == PLL_STATUS_ENABLE) {
308 //FH_MSG("PLL#%d is enabled", i) ;
309 enabled_num++ ;
310 }
311 /*else {
312 FH_MSG("PLL#%d is disabled", i) ;
313 }*/
314 }
315
316 //FH_MSG("PLen#=%d",enabled_num) ;
317
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") ;
321 g_clk_en = 1;
322 }
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") ;
326 g_clk_en = 0;
327 }
328 }
329
330
331
332 static int __mt_enable_freqhopping(unsigned int pll_id,const struct freqhopping_ssc* ssc_setting)
333 {
334 //unsigned int pll_hp=0;
335 unsigned long flags=0;
336
337 //FH_MSG("EN: en_fh");
338 FH_MSG("EN: %s:: %x u: %x df: %d dt: %d dds:%x",__func__ ,ssc_setting->lowbnd
339 ,ssc_setting->upbnd
340 ,ssc_setting->df
341 ,ssc_setting->dt
342 ,ssc_setting->dds);
343
344 update_fhctl_status(pll_id, PLL_STATUS_ENABLE) ;
345 mb() ;
346
347
348 //lock @ __freqhopping_ctrl_lock()
349 //spin_lock_irqsave(&freqhopping_lock, flags);
350
351 g_fh_pll[pll_id].fh_status = FH_FH_ENABLE_SSC;
352
353
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);
359 //WARN_ON(1);
360 //spin_unlock_irqrestore(&freqhopping_lock, flags);
361 //return 1;
362 //}else {
363
364 local_irq_save(flags);
365
366 //Set the relative parameter registers (dt/df/upbnd/downbnd)
367 //Enable the fh bit
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);
370
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));
373
374
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));
377
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));
380
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);
384
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 );
388
389 mb();
390
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);
395
396 local_irq_restore(flags);
397
398 //FH_MSG("Exit");
399 return 0;
400 }
401
402 static int __mt_disable_freqhopping(unsigned int pll_id,const struct freqhopping_ssc* ssc_setting)
403 {
404 unsigned long flags=0;
405 // unsigned int pll_hp=0;
406 unsigned int fh_dds=0;
407 unsigned int pll_dds=0;
408
409
410 //FH_MSG("EN: _dis_fh");
411
412 //lock @ __freqhopping_ctrl_lock()
413 //spin_lock_irqsave(&freqhopping_lock, flags);
414
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);
419 mb();
420 local_irq_restore(flags);
421
422
423 if(pll_id == MT658X_FH_MEM_PLL){ //for mempll
424 unsigned int i=0;
425
426 pll_dds = (DRV_Reg32(DDRPHY_BASE+0x624)) >> 11 ;
427 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
428
429 FH_MSG(">p:f< %x:%x",pll_dds,fh_dds);
430
431 while((pll_dds != fh_dds) && ( i < 100)){
432
433 if(unlikely(i > 100)){
434 FH_BUG_ON(i > 100);
435 break;
436 }
437
438 udelay(10);
439 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
440 i++;
441 }
442
443 FH_MSG("<p:f:i> %x:%x:%d",pll_dds,fh_dds,i);
444 }
445 else{
446 //TODO: sync&wait DDS back to PLLCON1@other PLLs
447 //FH_MSG("n-mempll");
448 }
449
450
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 );
455
456 g_fh_pll[pll_id].fh_status = FH_FH_DISABLE;
457 local_irq_restore(flags);
458
459 //lock @ __freqhopping_ctrl_lock()
460 //spin_unlock_irqrestore(&freqhopping_lock, flags);
461
462 mb() ;
463 update_fhctl_status(pll_id, PLL_STATUS_DISABLE) ;
464
465
466 //FH_MSG("Exit");
467
468 return 0;
469 }
470
471
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)
474 {
475 unsigned int retVal = 0;
476 unsigned int i=2; //0 is disable, 1 is user defines, so start from 2
477
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);
480
481 switch(pll_id) {
482
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){
487 retVal = i;
488 break;
489 }
490 i++;
491 }
492 break;
493
494
495 case MT658X_FH_MAIN_PLL:
496 while(i < MT_SSC_NR_PREDEFINE_SETTING){
497 if(freq == mt_ssc_mainpll_setting[i].freq){
498 retVal = i;
499 break;
500 }
501 i++;
502 }
503 break;
504
505 case MT658X_FH_MEM_PLL:
506 while(i < MT_SSC_NR_PREDEFINE_SETTING){
507 if(freq == mt_ssc_mempll_setting[i].freq){
508 retVal = i;
509 break;
510 }
511 i++;
512 }
513 break;
514
515 case MT658X_FH_MSDC_PLL:
516 while(i < MT_SSC_NR_PREDEFINE_SETTING){
517 if(freq == mt_ssc_msdcpll_setting[i].freq){
518 retVal = i;
519 break;
520 }
521 i++;
522 }
523 break;
524
525 case MT658X_FH_MM_PLL:
526 while(i < MT_SSC_NR_PREDEFINE_SETTING){
527 if(freq == mt_ssc_mmpll_setting[i].freq){
528 retVal = i;
529 break;
530 }
531 i++;
532 }
533 break;
534
535 case MT658X_FH_VENC_PLL:
536 while(i < MT_SSC_NR_PREDEFINE_SETTING){
537 if(freq == mt_ssc_vencpll_setting[i].freq){
538 retVal = i;
539 break;
540 }
541 i++;
542 }
543 break;
544
545 /* 8127 FHCTL MB */
546 case MT658X_FH_TVD_PLL:
547 while(i < MT_SSC_NR_PREDEFINE_SETTING){
548 if(freq == mt_ssc_tvdpll_setting[i].freq){
549 retVal = i;
550 break;
551 }
552 i++;
553 }
554
555 case MT658X_FH_LVDS_PLL:
556 while(i < MT_SSC_NR_PREDEFINE_SETTING){
557 if(freq == mt_ssc_lvdspll_setting[i].freq){
558 retVal = i;
559 break;
560 }
561 i++;
562 }
563 /* 8127 FHCTL ME */
564
565 case MT658X_FH_PLL_TOTAL_NUM:
566 FH_MSG("Error MT658X_FH_PLL_TOTAL_NUM!");
567 break;
568
569
570 };
571
572 return retVal;
573 }
574
575 static int __freqhopping_ctrl(struct freqhopping_ioctl* fh_ctl,bool enable)
576 {
577 const struct freqhopping_ssc* pSSC_setting=NULL;
578 unsigned int ssc_setting_id=0;
579 int retVal=1;
580
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);
583
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);
587
588 if (fh_ctl->pll_id==MT658X_FH_MAIN_PLL)
589 {
590 g_fh_pll[fh_ctl->pll_id].curr_freq = 1612000;
591 }
592 else if (fh_ctl->pll_id==MT658X_FH_MEM_PLL)
593 {
594 g_fh_pll[fh_ctl->pll_id].curr_freq = 266000;
595 }
596 else if (fh_ctl->pll_id==MT658X_FH_MSDC_PLL)
597 {
598 g_fh_pll[fh_ctl->pll_id].curr_freq = 1599000;
599 }
600 else if (fh_ctl->pll_id==MT658X_FH_MM_PLL)
601 {
602 g_fh_pll[fh_ctl->pll_id].curr_freq = 1188000;
603 }
604 else if (fh_ctl->pll_id==MT658X_FH_VENC_PLL)
605 {
606 g_fh_pll[fh_ctl->pll_id].curr_freq = 1200000;
607 }
608 else if (fh_ctl->pll_id==MT658X_FH_ARM_PLL)
609 {
610 g_fh_pll[fh_ctl->pll_id].curr_freq = 0;
611 }
612 /* 8127 FHCTL MB */
613 else if (fh_ctl->pll_id==MT658X_FH_TVD_PLL)
614 {
615 g_fh_pll[fh_ctl->pll_id].curr_freq = 148500;
616 }
617 else if (fh_ctl->pll_id==MT658X_FH_LVDS_PLL)
618 {
619 g_fh_pll[fh_ctl->pll_id].curr_freq = 150000;
620 }
621 /* 8127 FHCTL ME */
622 else
623 {
624 FH_BUG_ON("Incorrect pll_id.");
625 }
626
627 if((enable == true) && (g_fh_pll[fh_ctl->pll_id].fh_status == FH_FH_ENABLE_SSC) ){
628
629 //The FH already enabled @ this PLL
630
631 //FH_MSG("re-en FH");
632
633 //disable FH first, will be enable later
634 __mt_disable_freqhopping(fh_ctl->pll_id,pSSC_setting);
635 }
636 else if((enable == false) && (g_fh_pll[fh_ctl->pll_id].fh_status == FH_FH_DISABLE)){
637
638 //The FH already been disabled @ this PLL, do nothing & return
639
640 //FH_MSG("re-dis FH");
641 retVal = 0;
642 goto Exit;
643 }
644
645
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;
648
649 if( enable == true) { //enable freq. hopping @ fh_ctl->pll_id
650
651 if(g_fh_pll[fh_ctl->pll_id].pll_status == FH_PLL_DISABLE) {
652 //FH_MSG("pll is dis");
653
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;
656 retVal = 0;
657 goto Exit;
658 }
659 else {
660 //FH_MSG("pll is en");
661 if(g_fh_pll[fh_ctl->pll_id].user_defined == true){
662 FH_MSG("use u-def");
663
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;
666 }
667 else {
668 //FH_MSG("n-user def");
669
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);
672 }
673 else{
674 ssc_setting_id = 0;
675 }
676
677
678 //FH_MSG("sid %d",ssc_setting_id);
679 if(ssc_setting_id == 0){
680 FH_MSG("!!! No corresponding setting found !!!");
681
682 //just disable FH & exit
683 __mt_disable_freqhopping(fh_ctl->pll_id,pSSC_setting);
684 goto Exit;
685 }
686
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];
691 break;
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];
695 break;
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];
699 break;
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];
703 break;
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];
707 break;
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];
711 break;
712 /* 8127 FHCTL MB */
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];
716 break;
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];
720 break;
721 /* 8127 FHCTL ME */
722 }
723 }//user defined
724
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);
729 goto Exit;
730 }
731
732 if( 0 == __mt_enable_freqhopping(fh_ctl->pll_id,pSSC_setting)) {
733 retVal = 0;
734 FH_MSG("en ok");
735 }
736 else{
737 FH_MSG("__mt_enable_freqhopping fail.");
738 }
739 }
740
741 }
742 else{ //disable req. hopping @ fh_ctl->pll_id
743 if( 0 == __mt_disable_freqhopping(fh_ctl->pll_id,pSSC_setting)) {
744 retVal = 0;
745 FH_MSG("dis ok");
746 }
747 else{
748 FH_MSG("__mt_disable_freqhopping fail.");
749 }
750 }
751
752 Exit:
753
754 //FH_MSG("Exit");
755 return retVal;
756 }
757
758
759
760
761
762 //mempll 266->293MHz using FHCTL
763 static int mt_h2oc_mempll(void)
764 {
765 unsigned long flags;
766 unsigned int fh_dds=0;
767 unsigned int pll_dds=0;
768 unsigned int i=0;
769
770 FH_MSG("EN: %s:%d",__func__,g_curr_dramc);
771
772 /*Please note that the DFS can¡¦t be applied in systems with DDR3 DRAM!
773 It¡¦s only for the mobile DRAM (LPDDR*)! */
774
775 if( (get_ddr_type() != LPDDR2) && (get_ddr_type() != LPDDR3) ) {
776 FH_MSG("Not LPDDR*");
777 return -1;
778 }
779
780 if(g_curr_dramc != 266){
781 FH_MSG("g_curr_dramc != 266)");
782 return -1;
783 }
784
785 FH_MSG("dds: %x",(DRV_Reg32(DDRPHY_BASE+0x624) >> 11 ));
786
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");
790 return -1;
791 }
792
793 //TODO: provelock issue spin_lock(&freqhopping_lock);
794 spin_lock_irqsave(&freqhopping_lock, flags);
795
796 //disable SSC when OC
797 __mt_disable_freqhopping(2, NULL);
798
799 if(g_fh_pll[MT658X_FH_MEM_PLL].fh_status == FH_FH_ENABLE_SSC){//only when SSC is enable
800
801 //Turn off MEMPLL hopping
802 fh_write32(REG_FHCTL2_CFG, 0x70700000);
803
804 //udelay(800);
805
806 pll_dds = (DRV_Reg32(DDRPHY_BASE+0x624)) >> 11 ;
807 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
808
809 FH_MSG(">p:f< %x:%x",pll_dds,fh_dds);
810
811 while((pll_dds != fh_dds) && ( i < 100)){
812
813 if(unlikely(i > 100)){
814 FH_BUG_ON(i > 100);
815 break;
816 }
817
818 udelay(10);
819 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
820 i++;
821 }
822
823 FH_MSG("<p:f:i> %x:%x:%d",pll_dds,fh_dds,i);
824 }
825
826 FH_MSG("=> 0x%x",DRV_Reg32(REG_FHCTL2_MON));
827
828 //TODO: provelock issue local_irq_save(flags);
829
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) );
835
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) );
840
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));
846
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));
850
851 //sync NCPO value
852 fh_write32(REG_FHCTL2_DDS, (DRV_Reg32(DDRPHY_BASE+0x624) >> 11 )|(1U<<31));
853
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)) );
856
857 mb();
858
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));
864
865 //-------------------------------------------------
866 // Trigger 2G1 Hopping on channel number 0
867 //-------------------------------------------------
868 fh_write32(REG_FHCTL_2G1_CH, 0);
869
870 g_curr_dramc = 293;
871
872 //TODO: provelock issue local_irq_restore(flags);
873
874 FH_MSG("-MON- 0x%x",DRV_Reg32(REG_FHCTL2_MON));
875
876 //TODO: provelock issue local_irq_save(flags);
877
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
880
881 //sync NCPO value
882 fh_write32(REG_FHCTL2_DDS, (DRV_Reg32(DDRPHY_BASE+0x624) >> 11 )|(1U<<31));
883
884 //Turn off MEMPLL hopping
885 fh_write32(REG_FHCTL2_CFG, 0x70700000);
886
887 //TODO: provelock issue local_irq_restore(flags);
888
889 if(g_fh_pll[MT658X_FH_MEM_PLL].fh_status == FH_FH_ENABLE_SSC){
890 FH_MSG("to SSC");
891
892 }
893 else{
894 //switch back to APMIXED
895 FH_MSG("to APM");
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)) );
898 }
899
900 FH_MSG("+MON+ 0x%x",DRV_Reg32(REG_FHCTL2_MON));
901
902 g_fh_pll[MT658X_FH_MEM_PLL].curr_freq = 293000;
903 g_fh_pll[MT658X_FH_MEM_PLL].pll_status = FH_PLL_ENABLE;
904
905 //TODO: provelock issue spin_unlock(&freqhopping_lock);
906 spin_unlock_irqrestore(&freqhopping_lock, flags);
907
908 freqhopping_config(MT658X_FH_MEM_PLL, 293000, true); //update freq.
909
910 return 0;
911 }
912
913 //mempll 293->266MHz using FHCTL
914 static int mt_oc2h_mempll(void)
915 {
916 unsigned long flags;
917 unsigned int fh_dds=0;
918 unsigned int pll_dds=0;
919 unsigned int i=0;
920
921 FH_MSG("EN: %s:%d",__func__,g_curr_dramc);
922
923 /*Please note that the DFS can¡¦t be applied in systems with DDR3 DRAM!
924 It¡¦s only for the mobile DRAM (LPDDR*)! */
925
926 if( (get_ddr_type() != LPDDR2) && (get_ddr_type() != LPDDR3) ) {
927 FH_MSG("Not LPDDR*");
928 return -1;
929 }
930
931 if(g_curr_dramc != 293){
932 FH_MSG("g_curr_dramc != 293)");
933 return -1;
934 }
935
936 FH_MSG("dds: %x",(DRV_Reg32(DDRPHY_BASE+0x624) >> 11 ));
937
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");
941 return 0;
942 }
943
944 //TODO: provelock issue spin_lock(&freqhopping_lock);
945 spin_lock_irqsave(&freqhopping_lock, flags);
946
947 if(g_fh_pll[MT658X_FH_MEM_PLL].fh_status == FH_FH_ENABLE_SSC){//only when SSC is enable
948
949 //Turn off MEMPLL hopping
950 fh_write32(REG_FHCTL2_CFG, 0x70700000);
951
952 //udelay(800);
953
954 pll_dds = (DRV_Reg32(DDRPHY_BASE+0x624)) >> 11 ;
955 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
956
957 FH_MSG(">p:f< %x:%x",pll_dds,fh_dds);
958
959 while((pll_dds != fh_dds) && ( i < 100)){
960
961 if(unlikely(i > 100)){
962 FH_BUG_ON(i > 100);
963 break;
964 }
965
966 udelay(10);
967 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
968 i++;
969 }
970
971 FH_MSG("<p:f:i> %x:%x:%d",pll_dds,fh_dds,i);
972 }
973
974
975 FH_MSG("=> 0x%x",DRV_Reg32(REG_FHCTL2_MON));
976
977 //TODO: provelock issue local_irq_save(flags);
978
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) );
984
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) );
989
990
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));
996
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));
1000
1001 //sync NCPO value
1002 fh_write32(REG_FHCTL2_DDS, (DRV_Reg32(DDRPHY_BASE+0x624) >> 11 )|(1U<<31));
1003
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)) );
1006
1007 mb();
1008
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));
1014
1015 //-------------------------------------------------
1016 // Trigger 2G1 Hopping on channel number 0
1017 //-------------------------------------------------
1018 fh_write32(REG_FHCTL_2G1_CH, 0);
1019
1020 g_curr_dramc = 266;
1021
1022 //TODO: provelock issue local_irq_restore(flags);
1023
1024 FH_MSG("-MON- 0x%x",DRV_Reg32(REG_FHCTL2_MON));
1025
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
1029
1030 //sync NCPO value
1031 fh_write32(REG_FHCTL2_DDS, (DRV_Reg32(DDRPHY_BASE+0x624) >> 11 )|(1U<<31));
1032
1033 //Turn off MEMPLL hopping
1034 fh_write32(REG_FHCTL2_CFG, 0x70700000);
1035 //TODO: provelock issue local_irq_restore(flags);
1036
1037 if(g_fh_pll[MT658X_FH_MEM_PLL].fh_status == FH_FH_ENABLE_SSC){
1038 FH_MSG("to SSC");
1039
1040 }
1041 else{
1042 //switch back to APMIXED
1043 FH_MSG("to APM");
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)) );
1046 }
1047
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;
1051
1052 //TODO: provelock issue spin_unlock(&freqhopping_lock);
1053 spin_unlock_irqrestore(&freqhopping_lock, flags);
1054
1055 freqhopping_config(MT658X_FH_MEM_PLL, 266000, true); //update freq.
1056
1057 return 0;
1058 }
1059
1060 //mempll 200->266MHz using FHCTL
1061 static int mt_fh_hal_l2h_mempll(void) //mempll low to high (200->266MHz)
1062 {
1063 unsigned long flags;
1064 unsigned int fh_dds=0;
1065 unsigned int pll_dds=0;
1066 unsigned int i=0;
1067
1068 FH_MSG("EN: %s:%d",__func__,g_curr_dramc);
1069
1070 /*Please note that the DFS can¡¦t be applied in systems with DDR3 DRAM!
1071 It¡¦s only for the mobile DRAM (LPDDR*)! */
1072
1073 if( (get_ddr_type() != LPDDR2) && (get_ddr_type() != LPDDR3) ) {
1074 FH_MSG("Not LPDDR*");
1075 return -1;
1076 }
1077
1078 if(g_curr_dramc == 266){
1079 return -1;
1080 }
1081
1082 FH_MSG("dds: %x",(DRV_Reg32(DDRPHY_BASE+0x624) >> 11 ));
1083
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);
1087 return 0;
1088 }
1089
1090 //TODO: provelock issue spin_lock(&freqhopping_lock);
1091 spin_lock_irqsave(&freqhopping_lock, flags);
1092
1093 if(g_fh_pll[MT658X_FH_MEM_PLL].fh_status == FH_FH_ENABLE_SSC){//only when SSC is enable
1094
1095 //Turn off MEMPLL hopping
1096 fh_write32(REG_FHCTL2_CFG, 0x70700000);
1097
1098 //udelay(800);
1099
1100 pll_dds = (DRV_Reg32(DDRPHY_BASE+0x624)) >> 11 ;
1101 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
1102
1103 FH_MSG(">p:f< %x:%x",pll_dds,fh_dds);
1104
1105 while((pll_dds != fh_dds) && ( i < 100)){
1106
1107 if(unlikely(i > 100)){
1108 FH_BUG_ON(i > 100);
1109 break;
1110 }
1111
1112 udelay(10);
1113 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
1114 i++;
1115 }
1116
1117 FH_MSG("<p:f:i> %x:%x:%d",pll_dds,fh_dds,i);
1118 }
1119
1120
1121 FH_MSG("=> 0x%x",DRV_Reg32(REG_FHCTL2_MON));
1122
1123 //TODO: provelock issue local_irq_save(flags);
1124
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) );
1130
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) );
1135
1136
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));
1142
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));
1146
1147 //sync NCPO value
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)) );
1151
1152 mb();
1153
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));
1159
1160 //-------------------------------------------------
1161 // Trigger 2G1 Hopping on channel number 0
1162 //-------------------------------------------------
1163 fh_write32(REG_FHCTL_2G1_CH, 0);
1164
1165 g_curr_dramc = 266;
1166
1167 //TODO: provelock issue local_irq_restore(flags);
1168
1169 FH_MSG("-MON- 0x%x",DRV_Reg32(REG_FHCTL2_MON));
1170
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
1174
1175 //sync NCPO value
1176 fh_write32(REG_FHCTL2_DDS, (DRV_Reg32(DDRPHY_BASE+0x624) >> 11 )|(1U<<31));
1177
1178 //Turn off MEMPLL hopping
1179 fh_write32(REG_FHCTL2_CFG, 0x70700000);
1180 //TODO: provelock issue local_irq_restore(flags);
1181
1182 if(g_fh_pll[MT658X_FH_MEM_PLL].fh_status == FH_FH_ENABLE_SSC){
1183 FH_MSG("to SSC");
1184
1185 }
1186 else{
1187 //switch back to APMIXED
1188 FH_MSG("to APM");
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)) );
1191 }
1192
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;
1196
1197 //TODO: provelock issue spin_unlock(&freqhopping_lock);
1198 spin_unlock_irqrestore(&freqhopping_lock, flags);
1199
1200 freqhopping_config(MT658X_FH_MEM_PLL, 266000, true); //update freq.
1201
1202 return 0;
1203 }
1204
1205 //mempll 266->200MHz using FHCTL
1206 static int mt_fh_hal_h2l_mempll(void) //mempll low to high (200->266MHz)
1207 {
1208 unsigned long flags;
1209 unsigned int fh_dds=0;
1210 unsigned int pll_dds=0;
1211 unsigned int i=0;
1212
1213 FH_MSG("EN: %s:%d",__func__,g_curr_dramc);
1214
1215 /*Please note that the DFS can¡¦t be applied in systems with DDR3 DRAM!
1216 It¡¦s only for the mobile DRAM (LPDDR*)! */
1217
1218 if( (get_ddr_type() != LPDDR2) && (get_ddr_type() != LPDDR3) ) {
1219 FH_MSG("Not LPDDR*");
1220 return -1;
1221 }
1222
1223 if(g_curr_dramc == LOW_DRAMC){
1224 return -1;
1225 }
1226
1227 FH_MSG("dds: %x",(DRV_Reg32(DDRPHY_BASE+0x624) >> 11 ));
1228
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");
1232 return 0;
1233 }
1234
1235 //TODO: provelock issue spin_lock(&freqhopping_lock);
1236 spin_lock_irqsave(&freqhopping_lock, flags);
1237
1238 if(g_fh_pll[MT658X_FH_MEM_PLL].fh_status == FH_FH_ENABLE_SSC){//only when SSC is enable
1239
1240 //Turn off MEMPLL hopping
1241 fh_write32(REG_FHCTL2_CFG, 0x70700000);
1242
1243 //udelay(800);
1244
1245 pll_dds = (DRV_Reg32(DDRPHY_BASE+0x624)) >> 11 ;
1246 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
1247
1248 FH_MSG(">p:f< %x:%x",pll_dds,fh_dds);
1249
1250 while((pll_dds != fh_dds) && ( i < 100)){
1251
1252 if(unlikely(i > 100)){
1253 FH_BUG_ON(i > 100);
1254 break;
1255 }
1256
1257 udelay(10);
1258 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
1259 i++;
1260 }
1261
1262 FH_MSG("<p:f:i> %x:%x:%d",pll_dds,fh_dds,i);
1263 }
1264
1265 FH_MSG("=> 0x%x",DRV_Reg32(REG_FHCTL2_MON));
1266
1267 //TODO: provelock issue local_irq_save(flags);
1268
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) );
1274
1275 //>>>Example<<<
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);
1280
1281
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));
1287
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));
1291
1292 //sync NCPO value
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)) );
1296
1297 mb();
1298
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));
1304
1305 //-------------------------------------------------
1306 // Trigger 2G1 Hopping on channel number 0
1307 //-------------------------------------------------
1308 fh_write32(REG_FHCTL_2G1_CH, 0);
1309
1310 g_curr_dramc = LOW_DRAMC;
1311
1312 //TODO: provelock issue local_irq_restore(flags);
1313
1314 FH_MSG("-MON- 0x%x",DRV_Reg32(REG_FHCTL2_MON));
1315
1316 //TODO: provelock issue local_irq_save(flags);
1317
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
1320
1321 //sync NCPO value
1322 fh_write32(REG_FHCTL2_DDS, (DRV_Reg32(DDRPHY_BASE+0x624) >> 11 )|(1U<<31));
1323
1324 //Turn off MEMPLL hopping
1325 fh_write32(REG_FHCTL2_CFG, 0x70700000);
1326
1327 //TODO: provelock issue local_irq_restore(flags);
1328
1329 if(g_fh_pll[MT658X_FH_MEM_PLL].fh_status == FH_FH_ENABLE_SSC){
1330 FH_MSG("to SSC");
1331
1332 }
1333 else{
1334 //switch back to APMIXED
1335 FH_MSG("to APM");
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)) );
1338 }
1339
1340 FH_MSG("+MON+ 0x%x",DRV_Reg32(REG_FHCTL2_MON));
1341
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;
1344
1345 //TODO: provelock issue spin_unlock(&freqhopping_lock);
1346 spin_unlock_irqrestore(&freqhopping_lock, flags);
1347
1348 freqhopping_config(MT658X_FH_MEM_PLL, LOW_DRAMC_FREQ, true); //update freq.
1349
1350 return 0;
1351 }
1352
1353 static int mt_fh_hal_dvfs(enum FH_PLL_ID pll_id, unsigned int dds_value)
1354 {
1355 unsigned int fh_dds=0;
1356 unsigned int i=0;
1357 unsigned long flags=0;
1358 unsigned int ilog =1;
1359 FH_MSG("EN: %s:",__func__);
1360
1361 local_irq_save(flags);
1362
1363 //1. sync ncpo to DDS of FHCTL
1364 if (!(mt_fh_hal_sync_ncpo_to_FHCTL_DDS(pll_id)))
1365 return 0;
1366 if(ilog)
1367 {
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));
1370 }
1371
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
1375
1376 if(ilog)
1377 {
1378 FH_MSG("2. enable DVFS and Hopping control");
1379 }
1380 //3. switch to hopping control
1381 mt_fh_hal_switch_register_to_FHCTL_control(pll_id,1);
1382 mb();
1383
1384 if(ilog)
1385 {
1386 FH_MSG("3. switch to hopping control");
1387 FH_MSG("PLL_HP_CON0: 0x%08x",(fh_read32(PLL_HP_CON0)&0x3F));
1388 }
1389
1390 //4. set DFS DDS
1391 fh_write32((REG_FHCTL0_DVFS+(pll_id*0x14)), (dds_value)|(1U<<31)); //set dds
1392
1393 if(ilog)
1394 {
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));
1398 }
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)){
1402
1403 if(unlikely(i > 100)){
1404 FH_BUG_ON(i > 100);
1405 break;
1406 }
1407
1408 udelay(10);
1409 fh_dds = (DRV_Reg32(REG_FHCTL0_MON+(pll_id*0x14))) & 0x1FFFFF;
1410 i++;
1411 }
1412
1413 if(ilog)
1414 {
1415 FH_MSG("4.1 ensure jump to target DDS");
1416 FH_MSG("i: %d",i);
1417 }
1418
1419 //5. write back to ncpo
1420
1421 if(ilog)
1422 {
1423 FH_MSG("5. write back to ncpo");
1424 }
1425 if (pll_id==MT658X_FH_ARM_PLL) //FHCTL0
1426 {
1427 fh_write32(ARMPLL_CON1, (fh_read32(REG_FHCTL0_DVFS)&0x1FFFFF)|(fh_read32(ARMPLL_CON1)&0xFFE00000)|(1U<<31));
1428
1429 if(ilog)
1430 {
1431 FH_MSG("ARMPLL_CON1: 0x%08x",(fh_read32(ARMPLL_CON1)&0x1FFFFF));
1432 }
1433 }
1434 else if (pll_id==MT658X_FH_MAIN_PLL) //FHCTL1
1435 {
1436 fh_write32(MAINPLL_CON1, (fh_read32(REG_FHCTL1_DVFS)&0x1FFFFF)|(fh_read32(MAINPLL_CON1)&0xFFE00000)|(1U<<31));
1437
1438 if(ilog)
1439 {
1440 FH_MSG("MAINPLL_CON1: 0x%08x",(fh_read32(MAINPLL_CON1)&0x1FFFFF));
1441 }
1442 }
1443 else if (pll_id==MT658X_FH_MEM_PLL) //FHCTL2
1444 {
1445 fh_write32((DDRPHY_BASE+0x624), ((fh_read32(REG_FHCTL2_DVFS)&0x1FFFFF)<<11)|((DRV_Reg32(DDRPHY_BASE+0x624))&0x7FF));
1446
1447 if(ilog)
1448 {
1449 FH_MSG("(DDRPHY_BASE+0x624): 0x%08x >>11: 0x%08x",(fh_read32(DDRPHY_BASE+0x624)),(fh_read32(DDRPHY_BASE+0x624)>>11));
1450 }
1451 if ((fh_read32(DDRPHY_BASE+0x624))&0x1)
1452 fh_write32((DDRPHY_BASE+0x624),((fh_read32(DDRPHY_BASE+0x624))&0xFFFFFFFE));
1453 else
1454 fh_write32((DDRPHY_BASE+0x624),((fh_read32(DDRPHY_BASE+0x624))|0x1));
1455
1456 if(ilog)
1457 {
1458 FH_MSG("(DDRPHY_BASE+0x624): 0x%08x >>11: 0x%08x",(fh_read32(DDRPHY_BASE+0x624)),(fh_read32(DDRPHY_BASE+0x624)>>11));
1459 }
1460 }
1461 else if (pll_id==MT658X_FH_MSDC_PLL) //FHCTL3
1462 {
1463 fh_write32(MSDCPLL_CON1, (fh_read32(REG_FHCTL3_DVFS)&0x1FFFFF)|(fh_read32(MSDCPLL_CON1)&0xFFE00000)|(1U<<31));
1464
1465 if(ilog)
1466 {
1467 FH_MSG("MSDCPLL_CON1: 0x%08x",(fh_read32(MSDCPLL_CON1)&0x1FFFFF));
1468 }
1469 }
1470 else if (pll_id==MT658X_FH_MM_PLL) //FHCTL4
1471 {
1472 fh_write32(MMPLL_CON1, (fh_read32(REG_FHCTL4_DVFS)&0x1FFFFF)|(fh_read32(MMPLL_CON1)&0xFFE00000)|(1U<<31));
1473
1474 if(ilog)
1475 {
1476 FH_MSG("MMPLL_CON1: 0x%08x",(fh_read32(MMPLL_CON1)&0x1FFFFF));
1477 }
1478 }
1479 else if (pll_id==MT658X_FH_VENC_PLL) //FHCTL5
1480 {
1481 fh_write32(VENCPLL_CON1, (fh_read32(REG_FHCTL5_DVFS)&0x1FFFFF)|(fh_read32(VENCPLL_CON1)&0xFFE00000)|(1U<<31));
1482
1483 if(ilog)
1484 {
1485 FH_MSG("VENCPLL_CON1: 0x%08x",(fh_read32(VENCPLL_CON1)&0x1FFFFF));
1486 }
1487 }
1488 /* 8127 FHCTL MB */
1489 else if (pll_id==MT658X_FH_TVD_PLL) //FHCTL3
1490 {
1491 fh_write32(TVDPLL_CON1, (fh_read32(REG_FHCTL3_DVFS)&0x1FFFFF)|(fh_read32(TVDPLL_CON1)&0xFFE00000)|(1U<<31));
1492
1493 if(ilog)
1494 {
1495 FH_MSG("TVDPLL_CON1: 0x%08x",(fh_read32(TVDPLL_CON1)&0x1FFFFF));
1496 }
1497 }
1498 else if (pll_id==MT658X_FH_LVDS_PLL) //FHCTL3
1499 {
1500 fh_write32(LVDSPLL_CON1, (fh_read32(REG_FHCTL3_DVFS)&0x1FFFFF)|(fh_read32(LVDSPLL_CON1)&0xFFE00000)|(1U<<31));
1501
1502 if(ilog)
1503 {
1504 FH_MSG("LVDSPLL_CON1: 0x%08x",(fh_read32(LVDSPLL_CON1)&0x1FFFFF));
1505 }
1506 }
1507 /* 8127 FHCTL ME */
1508
1509 //6. switch to register control
1510 mt_fh_hal_switch_register_to_FHCTL_control(pll_id,0);
1511 mb();
1512
1513 if(ilog)
1514 {
1515 FH_MSG("6. switch to register control");
1516 FH_MSG("PLL_HP_CON0: 0x%08x",(fh_read32(PLL_HP_CON0)&0x3F));
1517 }
1518
1519 local_irq_restore(flags);
1520 return 0;
1521 }
1522
1523 static int mt_fh_hal_dfs_armpll(unsigned int current_freq, unsigned int target_freq) //armpll dfs mdoe
1524 {
1525 unsigned long flags;
1526 unsigned int target_dds=0;
1527
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));
1531
1532 //TODO: provelock issue spin_lock(&freqhopping_lock);
1533 spin_lock_irqsave(&freqhopping_lock, flags);
1534
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);
1540
1541 mt_fh_hal_dvfs(MT658X_FH_ARM_PLL, target_dds);
1542
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);
1547
1548 return 0;
1549 }
1550 static int mt_fh_hal_l2h_dvfs_mempll(void) //mempll low to high (200->266MHz)
1551 {
1552 unsigned long flags;
1553 unsigned int fh_dds=0;
1554 unsigned int pll_dds=0;
1555 unsigned int i=0;
1556
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*)! */
1560
1561 if( (get_ddr_type() != LPDDR2) && (get_ddr_type() != LPDDR3) ) {
1562 FH_MSG("Not LPDDR*");
1563 return -1;
1564 }
1565
1566 FH_MSG("dds: 0x%x",(DRV_Reg32(DDRPHY_BASE+0x624) >> 11 ));
1567
1568 g_pll_mode = (DRV_Reg32(DDRPHY_BASE+0x60C) & 0x200);
1569 FH_MSG("g_pll_mode(0:1pll, 1:3pll): %x",g_pll_mode);
1570
1571 if (g_pll_mode==0) // 1pll mode
1572 {
1573 if ((DRV_Reg32(DDRPHY_BASE+0x624) >> 11 )==0x14030C)
1574 {
1575 FH_MSG("Already @533MHz");
1576 return 0;
1577 }
1578 else
1579 FH_MSG("Jump to 533MHz");
1580 }
1581 else if (g_pll_mode==0x200) // 3pll mode
1582 {
1583 if ((DRV_Reg32(DDRPHY_BASE+0x624) >> 11 )==0x131A2E)
1584 {
1585 FH_MSG("Already @533MHz");
1586 return 0;
1587 }
1588 else
1589 FH_MSG("Jump to 533MHz");
1590 }
1591
1592 //TODO: provelock issue spin_lock(&freqhopping_lock);
1593 spin_lock_irqsave(&freqhopping_lock, flags);
1594
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
1601
1602 //udelay(800);
1603
1604 pll_dds = (DRV_Reg32(REG_FHCTL2_DDS)) & 0x1FFFFF;
1605 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
1606
1607 FH_MSG(">p:f< %x:%x",pll_dds,fh_dds);
1608
1609 while((pll_dds != fh_dds) && ( i < 100)){
1610
1611 if(unlikely(i > 100)){
1612 FH_BUG_ON(i > 100);
1613 break;
1614 }
1615
1616 udelay(10);
1617 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
1618 i++;
1619 }
1620
1621 FH_MSG("<p:f:i> %x:%x:%d",pll_dds,fh_dds,i);
1622
1623 }
1624
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
1629
1630 g_curr_dramc = 266;
1631
1632 if(g_fh_pll[MT658X_FH_MEM_PLL].fh_status == FH_FH_ENABLE_SSC)
1633 {
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
1637
1638 if (!(mt_fh_hal_sync_ncpo_to_FHCTL_DDS(MT658X_FH_MEM_PLL)))
1639 return 0;
1640 FH_MSG("1. sync ncpo to DDS of FHCTL");
1641 FH_MSG("FHCTL2_DDS: 0x%08x", (fh_read32(REG_FHCTL2_DDS)&0x1FFFFF));
1642
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);
1645
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));
1648
1649 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL,1);
1650
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));
1654
1655 }
1656 //TODO: provelock issue spin_unlock(&freqhopping_lock);
1657 spin_unlock_irqrestore(&freqhopping_lock, flags);
1658
1659 return 0;
1660 }
1661
1662 static int mt_fh_hal_h2l_dvfs_mempll(void) //mempll high to low(266->200MHz)
1663 {
1664 unsigned long flags;
1665 unsigned int fh_dds=0;
1666 unsigned int pll_dds=0;
1667 unsigned int i=0;
1668
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*)! */
1672
1673 if( (get_ddr_type() != LPDDR2) && (get_ddr_type() != LPDDR3) ) {
1674 FH_MSG("Not LPDDR*");
1675 return -1;
1676 }
1677
1678 FH_MSG("dds: 0x%x",(DRV_Reg32(DDRPHY_BASE+0x624) >> 11 ));
1679
1680 g_pll_mode = (DRV_Reg32(DDRPHY_BASE+0x60C) & 0x200);
1681 FH_MSG("g_pll_mode(0:1pll, 1:3pll): %x",g_pll_mode);
1682
1683 if (g_pll_mode==0) // 1pll mode
1684 {
1685 if ((DRV_Reg32(DDRPHY_BASE+0x624) >> 11 )==0x0F04B0)
1686 {
1687 FH_MSG("Already @400MHz");
1688 return 0;
1689 }
1690 else
1691 FH_MSG("Jump to 400MHz");
1692 }
1693 else if (g_pll_mode==0x200) // 3pll mode
1694 {
1695 if ((DRV_Reg32(DDRPHY_BASE+0x624) >> 11 )==0x0E55EE)
1696 {
1697 FH_MSG("Already @400MHz");
1698 return 0;
1699 }
1700 else
1701 FH_MSG("Jump to 400MHz");
1702 }
1703
1704 //TODO: provelock issue spin_lock(&freqhopping_lock);
1705 spin_lock_irqsave(&freqhopping_lock, flags);
1706
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
1713
1714 //udelay(800);
1715
1716 pll_dds = (DRV_Reg32(REG_FHCTL2_DDS)) & 0x1FFFFF;
1717 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
1718
1719 FH_MSG(">p:f< %x:%x",pll_dds,fh_dds);
1720
1721 while((pll_dds != fh_dds) && ( i < 100)){
1722
1723 if(unlikely(i > 100)){
1724 FH_BUG_ON(i > 100);
1725 break;
1726 }
1727
1728 udelay(10);
1729 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
1730 i++;
1731 }
1732
1733 FH_MSG("<p:f:i> %x:%x:%d",pll_dds,fh_dds,i);
1734 }
1735
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
1740
1741 g_curr_dramc = 200;
1742
1743 if(g_fh_pll[MT658X_FH_MEM_PLL].fh_status == FH_FH_ENABLE_SSC)
1744 {
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
1748
1749 if (!(mt_fh_hal_sync_ncpo_to_FHCTL_DDS(MT658X_FH_MEM_PLL)))
1750 return 0;
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));
1754
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);
1757
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));
1760
1761 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL,1);
1762
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
1765
1766 FH_MSG("REG_FHCTL2_CFG: 0x%08x", fh_read32(REG_FHCTL2_CFG));
1767
1768 }
1769 //TODO: provelock issue spin_unlock(&freqhopping_lock);
1770 spin_unlock_irqrestore(&freqhopping_lock, flags);
1771
1772 return 0;
1773 }
1774
1775 static int mt_h2oc_dfs_mempll(void)
1776 {
1777 unsigned long flags;
1778 unsigned int fh_dds=0;
1779 unsigned int pll_dds=0;
1780 unsigned int i=0;
1781
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*)! */
1785
1786 if( (get_ddr_type() != LPDDR2) && (get_ddr_type() != LPDDR3) ) {
1787 FH_MSG("Not LPDDR*");
1788 return -1;
1789 }
1790
1791 FH_MSG("dds: 0x%x",(DRV_Reg32(DDRPHY_BASE+0x624) >> 11 ));
1792
1793 g_pll_mode = (DRV_Reg32(DDRPHY_BASE+0x60C) & 0x200);
1794 FH_MSG("g_pll_mode(0:1pll, 1:3pll): %x",g_pll_mode);
1795
1796 if (g_pll_mode==0) // 1pll mode
1797 {
1798 if ((DRV_Reg32(DDRPHY_BASE+0x624) >> 11 )==0x160077)
1799 {
1800 FH_MSG("Already @1172MHz");
1801 return 0;
1802 }
1803 else
1804 FH_MSG("Jump to 1172MHz");
1805 }
1806 else if (g_pll_mode==0x200) // 3pll mode
1807 {
1808 if ((DRV_Reg32(DDRPHY_BASE+0x624) >> 11 )==0x150071)
1809 {
1810 FH_MSG("Already @1172MHz");
1811 return 0;
1812 }
1813 else
1814 FH_MSG("Jump to 1172MHz");
1815 }
1816
1817 //TODO: provelock issue spin_lock(&freqhopping_lock);
1818 spin_lock_irqsave(&freqhopping_lock, flags);
1819
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
1826
1827 //udelay(800);
1828
1829 pll_dds = (DRV_Reg32(REG_FHCTL2_DDS)) & 0x1FFFFF;
1830 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
1831
1832 FH_MSG(">p:f< %x:%x",pll_dds,fh_dds);
1833
1834 while((pll_dds != fh_dds) && ( i < 100)){
1835
1836 if(unlikely(i > 100)){
1837 FH_BUG_ON(i > 100);
1838 break;
1839 }
1840
1841 udelay(10);
1842 fh_dds = (DRV_Reg32(REG_FHCTL2_MON)) & 0x1FFFFF;
1843 i++;
1844 }
1845
1846 FH_MSG("<p:f:i> %x:%x:%d",pll_dds,fh_dds,i);
1847
1848 }
1849
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
1854
1855 if(g_fh_pll[MT658X_FH_MEM_PLL].fh_status == FH_FH_ENABLE_SSC)
1856 {
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
1860
1861 if (!(mt_fh_hal_sync_ncpo_to_FHCTL_DDS(MT658X_FH_MEM_PLL)))
1862 return 0;
1863 FH_MSG("1. sync ncpo to DDS of FHCTL");
1864 FH_MSG("FHCTL2_DDS: 0x%08x", (fh_read32(REG_FHCTL2_DDS)&0x1FFFFF));
1865
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);
1868
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));
1871
1872 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MEM_PLL,1);
1873
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));
1877
1878 }
1879 //TODO: provelock issue spin_unlock(&freqhopping_lock);
1880 spin_unlock_irqrestore(&freqhopping_lock, flags);
1881
1882 return 0;
1883 }
1884
1885 static int mt_fh_hal_dram_overclock(int clk)
1886 {
1887 FH_MSG("EN: %s clk:%d",__func__,clk);
1888 if (1)//DFS mode
1889 {
1890 if( clk == 200)
1891 {
1892 g_curr_dramc = 200;
1893 return(mt_fh_hal_h2l_dvfs_mempll());
1894 }
1895
1896 if( clk == 266)
1897 {
1898 g_curr_dramc = 266;
1899 return(mt_fh_hal_l2h_dvfs_mempll());
1900 }
1901
1902 if( clk == 293)
1903 {
1904 g_curr_dramc = 293;
1905 return(mt_h2oc_dfs_mempll());
1906 }
1907 }
1908 else
1909 {
1910 if( clk == LOW_DRAMC){ //target freq: 208.5MHz
1911 if( g_curr_dramc != 266 ){ //266 -> 208.5 only
1912 FH_BUG_ON(1);
1913 return -1;
1914 }
1915 else{ //let's move from 266 to 208.5
1916 return(mt_fh_hal_h2l_mempll());
1917 }
1918 }
1919
1920 if( clk == 293){ //target freq: 293MHz
1921 if( g_curr_dramc != 266 ){ //266 -> 293 only
1922 FH_BUG_ON(1);
1923 return -1;
1924 }
1925 else{ //let's move from 266 to 293
1926 return(mt_h2oc_mempll());
1927 }
1928 }
1929
1930 if( clk == 266){ ////target freq: 293MHz
1931 if( g_curr_dramc == 266 ){ //cannot be 266 -> 266
1932 FH_BUG_ON(1);
1933 return -1;
1934 }
1935 else if( g_curr_dramc == LOW_DRAMC ){ //208 -> 266
1936 return(mt_fh_hal_l2h_mempll());
1937 }
1938 else if( g_curr_dramc == 293 ){ //293 -> 266
1939 return(mt_oc2h_mempll());
1940 }
1941 }
1942 }
1943 FH_BUG_ON(1);
1944 return(-1);
1945 }
1946
1947 static int mt_fh_hal_get_dramc(void)
1948 {
1949 return(g_curr_dramc);
1950 }
1951
1952 static void mt_fh_hal_popod_save(void)
1953 {
1954 unsigned int fh_dds=0;
1955 unsigned int pll_dds=0;
1956 unsigned int i=0;
1957
1958 FH_MSG("EN: %s",__func__);
1959
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
1962 {
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
1967
1968 //udelay(800);
1969
1970 pll_dds = (DRV_Reg32(REG_FHCTL1_DDS)) & 0x1FFFFF;
1971 fh_dds = (DRV_Reg32(REG_FHCTL1_MON)) & 0x1FFFFF;
1972
1973 FH_MSG("Org pll_dds:%x fh_dds:%x",pll_dds,fh_dds);
1974
1975 while((pll_dds != fh_dds) && ( i < 100))
1976 {
1977
1978 if(unlikely(i > 100)){
1979 FH_BUG_ON(i > 100);
1980 break;
1981 }
1982
1983 udelay(10);
1984 fh_dds = (DRV_Reg32(REG_FHCTL1_MON)) & 0x1FFFFF;
1985 i++;
1986 }
1987
1988 FH_MSG("pll_dds:%x fh_dds:%x i:%d",pll_dds,fh_dds,i);
1989
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));
1993
1994 // switch to register control
1995 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MAIN_PLL,0);
1996 mb();
1997 FH_MSG("switch to register control PLL_HP_CON0: 0x%08x",(fh_read32(PLL_HP_CON0)&0x3F));
1998
1999 }
2000
2001 }
2002
2003 static void mt_fh_hal_popod_restore(void)
2004 {
2005
2006 FH_MSG("EN: %s",__func__);
2007
2008 //enable maipll SSC mode
2009 if(g_fh_pll[MT658X_FH_MAIN_PLL].fh_status == FH_FH_ENABLE_SSC)
2010 {
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
2014
2015 if (!(mt_fh_hal_sync_ncpo_to_FHCTL_DDS(MT658X_FH_MAIN_PLL)))
2016 return;
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));
2020
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);
2023
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));
2026
2027 mt_fh_hal_switch_register_to_FHCTL_control(MT658X_FH_MAIN_PLL,1);
2028
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
2031
2032 FH_MSG("REG_FHCTL1_CFG: 0x%08x", fh_read32(REG_FHCTL1_CFG));
2033
2034 }
2035
2036 }
2037
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)
2040 {
2041 //char *p = page;
2042 //int len = 0;
2043
2044 FH_MSG("EN: %s",__func__);
2045
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));
2050
2051 #if 0
2052 *start = page + off;
2053
2054 len = p - page;
2055
2056 if (len > off)
2057 len -= off;
2058 else
2059 len = 0;
2060
2061 return len < count ? len : count;
2062 #endif
2063 return 0;
2064 }
2065
2066
2067 static int freqhopping_dramc_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
2068 {
2069 int len = 0, freq = 0;
2070 char dramc[32];
2071
2072 FH_MSG("EN: proc");
2073
2074 len = (count < (sizeof(dramc) - 1)) ? count : (sizeof(dramc) - 1);
2075
2076 if (copy_from_user(dramc, buffer, len))
2077 {
2078 FH_MSG("copy_from_user fail!");
2079 return 1;
2080 }
2081
2082 dramc[len] = '\0';
2083
2084 if (sscanf(dramc, "%d", &freq) == 1)
2085 {
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();
2089 }
2090 else if(freq == 293){
2091 mt_fh_hal_dram_overclock(293);
2092 }
2093 else{
2094 FH_MSG("must be 200/266/293!");
2095 }
2096
2097 #if 0
2098 if(freq == 266){
2099 FH_MSG("==> %d",mt_fh_hal_dram_overclock(266));
2100 }
2101 else if(freq == 293){
2102 FH_MSG("==> %d",mt_fh_hal_dram_overclock(293));
2103 }
2104 else if(freq == LOW_DRAMC){
2105 FH_MSG("==> %d",mt_fh_hal_dram_overclock(208));
2106 }
2107 #endif
2108
2109 return count;
2110 }
2111 else
2112 {
2113 FH_MSG(" bad argument!!");
2114 }
2115
2116 return -EINVAL;
2117 }
2118
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)
2121 {
2122 //char *p = page;
2123 //int len = 0;
2124 int i=0;
2125
2126 FH_MSG("EN: %s",__func__);
2127
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)));
2132 }
2133
2134 #if 0
2135 *start = page + off;
2136
2137 len = p - page;
2138
2139 if (len > off)
2140 len -= off;
2141 else
2142 len = 0;
2143
2144 return len < count ? len : count;
2145 #endif
2146 return 0;
2147 }
2148
2149
2150 static int freqhopping_dvfs_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
2151 {
2152 int ret;
2153 char kbuf[256];
2154 unsigned long len = 0;
2155 unsigned int p1,p2,p3,p4,p5;
2156 // struct freqhopping_ioctl fh_ctl;
2157
2158 p1=0;
2159 p2=0;
2160 p3=0;
2161 p4=0;
2162 p5=0;
2163
2164 FH_MSG("EN: %s",__func__);
2165
2166 len = min(count, (unsigned long)(sizeof(kbuf)-1));
2167
2168 if (count == 0)return -1;
2169 if(count > 255)count = 255;
2170
2171 ret = copy_from_user(kbuf, buffer, count);
2172 if (ret < 0)return -1;
2173
2174 kbuf[count] = '\0';
2175
2176 sscanf(kbuf, "%d %d %d %d %d", &p1, &p2, &p3, &p4, &p5);
2177
2178 FH_MSG("EN: p1=%d p2=%d p3=%d", p1, p2, p3);
2179
2180 if (p1==MT658X_FH_MEM_PLL)
2181 {
2182 if (p2==533)
2183 mt_fh_hal_l2h_dvfs_mempll();
2184 else if (p2==400)
2185 mt_fh_hal_h2l_dvfs_mempll();
2186 else if (p2==586)
2187 mt_h2oc_dfs_mempll();
2188 else
2189 FH_MSG("not define %d freq @mempll",p2);
2190 }
2191 else if (p1==MT658X_FH_ARM_PLL)
2192 {
2193 mt_fh_hal_dfs_armpll(p2, p3);
2194 }
2195 else if (p1==4370)
2196 {
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
2201
2202 if (!(mt_fh_hal_sync_ncpo_to_FHCTL_DDS(p2)))
2203 return 0;
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));
2207
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);
2210
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)));
2213
2214 mt_fh_hal_switch_register_to_FHCTL_control(p2,1);
2215
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
2218
2219 FH_MSG("REG_FHCTL%d_CFG: 0x%08x",p2 , fh_read32(REG_FHCTL0_CFG+(p2*0x14)));
2220 }
2221 else if (p1==2222)
2222 {
2223 if (p2==0) //disable
2224 mt_fh_hal_popod_save();
2225 else if (p2==1) //enable
2226 mt_fh_hal_popod_restore();
2227 }
2228 else
2229 mt_fh_hal_dvfs(p1, p2);
2230
2231 return count;
2232 }
2233
2234
2235
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)
2238 {
2239 //char *p = page;
2240 //int len = 0;
2241 int i=0;
2242
2243 FH_MSG("EN: %s",__func__);
2244
2245 seq_printf(m, "FHDMA_CFG:\r\n");
2246
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));
2252
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));
2258
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));
2265
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));
2271
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));
2276
2277
2278 for(i=0;i<MT_FHPLL_MAX;i++) {
2279
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)));
2286 }
2287
2288
2289 seq_printf(m, "\r\nPLL_HP_CON0:\r\n0x%08x\r\n",
2290 DRV_Reg32(PLL_HP_CON0));
2291
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));
2298
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));
2305
2306
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...
2317
2318 #if 0
2319 *start = page + off;
2320
2321 len = p - page;
2322
2323 if (len > off)
2324 len -= off;
2325 else
2326 len = 0;
2327
2328 return len < count ? len : count;
2329 #endif
2330 return 0;
2331 }
2332
2333
2334
2335
2336
2337 #if MT_FH_CLK_GEN
2338
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)
2341 {
2342 //char *p = page;
2343 //int len = 0;
2344
2345 FH_MSG("EN: %s",__func__);
2346
2347 if(g_curr_clkgen > MT658X_FH_PLL_TOTAL_NUM ){
2348 seq_printf(m, "no clkgen output.\r\n");
2349 }
2350 else{
2351 seq_printf(m, "clkgen:%d\r\n",g_curr_clkgen);
2352 }
2353
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));
2358
2359 seq_printf(m, "\r\nCLK_CFG_3: 0x%08x\r\n",
2360 DRV_Reg32(CLK_CFG_3));
2361
2362 seq_printf(m, "\r\nTOP_CKMUXSEL: 0x%08x\r\n",
2363 DRV_Reg32(TOP_CKMUXSEL));
2364
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));
2370
2371
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));
2379 #if 0
2380 *start = page + off;
2381
2382 len = p - page;
2383
2384 if (len > off)
2385 len -= off;
2386 else
2387 len = 0;
2388
2389 return len < count ? len : count;
2390 #endif
2391 return 0;
2392 }
2393
2394
2395 static int freqhopping_clkgen_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
2396 {
2397 int len = 0, pll_id = 0;
2398 char clkgen[32];
2399
2400 FH_MSG("EN: %s",__func__);
2401
2402 len = (count < (sizeof(clkgen) - 1)) ? count : (sizeof(clkgen) - 1);
2403
2404 //if you want to measue the clk by evb, you should turn on GPIO34.
2405 //mt_set_gpio_mode(GPIO34, GPIO_MODE_03);
2406
2407 if (copy_from_user(clkgen, buffer, len))
2408 {
2409 FH_MSG("copy_from_user fail!");
2410 return 1;
2411 }
2412
2413 clkgen[len] = '\0';
2414
2415 if (sscanf(clkgen, "%d", &pll_id) == 1)
2416 {
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
2420 udelay(1000);
2421 fh_write32(CLK_CFG_3, 0x00000001); //pll_pre_clk [don't care @ ARMPLL]
2422 udelay(1000);
2423 fh_write32(CLK_CFG_3, 0x00000001); //pll_clk_sel [don't care @ ARMPLL]
2424 udelay(1000);
2425 fh_write32(CLK_CFG_3, 0x00000401); //abist_clk_sel [0100: armpll_occ_mon]
2426 udelay(1000);
2427
2428 }
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
2432 udelay(1000);
2433 fh_write32(CLK_CFG_3, 0x000F0001); //pll_pre_clk [1111: AD_MAIN_H230P3M]
2434 udelay(1000);
2435 fh_write32(CLK_CFG_3, 0x000F0001); //pll_clk_sel [0000: pll_pre_clk]
2436 udelay(1000);
2437 fh_write32(CLK_CFG_3, 0x000F0F01); //abist_clk_sel [1111: pll_clk_out]
2438 udelay(1000);
2439
2440 }
2441 else if(pll_id == MT658X_FH_MEM_PLL){
2442
2443 fh_write32(DDRPHY_BASE+0x600, ( (DRV_Reg32(DDRPHY_BASE+0x600)) | 0x1<<5));
2444
2445
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));
2449
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));
2456
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));
2461
2462 #if 0
2463 fh_write32(DDRPHY_BASE+0x608, ( (DRV_Reg32(DDRPHY_BASE+0x608)) & ~0x000E0000 ));
2464 #endif
2465 fh_write32(DDRPHY_BASE+0x608, ( (DRV_Reg32(DDRPHY_BASE+0x608)) | 0x00040000 ));
2466
2467 fh_write32(DDRPHY_BASE+0x608, ( (DRV_Reg32(DDRPHY_BASE+0x608)) & ~0xF0000000 ));
2468 fh_write32(DDRPHY_BASE+0x608, ( (DRV_Reg32(DDRPHY_BASE+0x608)) | 0x80000000 ));
2469
2470 //fh_write32(MBIST_CFG_2, 0x00000001); //divide by 1+1
2471 fh_write32(CLK_CFG_3, 0x00000001); //enable it
2472 udelay(1000);
2473 fh_write32(CLK_CFG_3, 0x00000001); //pll_pre_clk [don't care @ ARMPLL]
2474 udelay(1000);
2475 fh_write32(CLK_CFG_3, 0x00000001); //pll_clk_sel [don't care @ ARMPLL]
2476 udelay(1000);
2477 fh_write32(CLK_CFG_3, 0x00000501); //abist_clk_sel [0101: AD_MEMPLL_MONCLK]
2478 udelay(1000);
2479
2480 }
2481 else if(pll_id == MT658X_FH_MSDC_PLL){
2482
2483 fh_write32(MBIST_CFG_2, 0x00000009); //divide by 9+1
2484
2485 fh_write32(CLK_CFG_3, 0x00000001); //enable it
2486 udelay(1000);
2487 fh_write32(CLK_CFG_3, 0x00080001); //pll_pre_clk [1000: AD_MSDCPLL_H208M]
2488 udelay(1000);
2489 fh_write32(CLK_CFG_3, 0x00080001); //pll_clk_sel [0000: pll_pre_clk]
2490 udelay(1000);
2491 fh_write32(CLK_CFG_3, 0x00080F01); //abist_clk_sel [1111: pll_clk_out]
2492 udelay(1000);
2493
2494 }
2495 else if(pll_id == MT658X_FH_MM_PLL){
2496 fh_write32(MBIST_CFG_2, 0x00000009); //divide by 9+1
2497
2498 fh_write32(CLK_CFG_3, 0x00000001); //enable it
2499 udelay(1000);
2500 fh_write32(CLK_CFG_3, 0x00090001); //pll_pre_clk [1001: AD_TVHDMI_H_CK]
2501 udelay(1000);
2502 fh_write32(CLK_CFG_3, 0x00090001); //pll_clk_sel [0000: pll_pre_clk]
2503 udelay(1000);
2504 fh_write32(CLK_CFG_3, 0x00090F01); //abist_clk_sel [1111: pll_clk_out]
2505 udelay(1000);
2506
2507 }
2508 else if(pll_id == MT658X_FH_VENC_PLL){
2509 fh_write32(MBIST_CFG_2, 0x00000009); //divide by 9+1
2510
2511 fh_write32(CLK_CFG_3, 0x00000001); //enable it
2512 udelay(1000);
2513 fh_write32(CLK_CFG_3, 0x000A0001); //pll_pre_clk [1010: AD_LVDS_H180M_CK]
2514 udelay(1000);
2515 fh_write32(CLK_CFG_3, 0x000A0001); //pll_clk_sel [0000: pll_pre_clk]
2516 udelay(1000);
2517 fh_write32(CLK_CFG_3, 0x000A0F01); //abist_clk_sel [1111: pll_clk_out]
2518 udelay(1000);
2519
2520 }
2521 }
2522 else
2523 {
2524 FH_MSG(" bad argument!!");
2525 }
2526
2527 g_curr_clkgen = pll_id;
2528
2529 return count;
2530
2531 //return -EINVAL;
2532 }
2533
2534 #endif //MT_FH_CLK_GEN
2535 //TODO: __init void mt_freqhopping_init(void)
2536 static void mt_fh_hal_init(void)
2537 {
2538 int i;
2539 // int ret = 0;
2540 unsigned long flags;
2541
2542 FH_MSG("EN: %s",__func__);
2543
2544 if(g_initialize == 1){
2545 FH_MSG("already init!");
2546 return;
2547 }
2548
2549 //init hopping table for mempll 200<->266
2550 memset(g_mempll_fh_table, 0, sizeof(g_mempll_fh_table));
2551
2552
2553 for(i=0;i<MT_FHPLL_MAX;i++) {
2554
2555 //TODO: use the g_fh_pll[] to init the FHCTL
2556 spin_lock_irqsave(&freqhopping_lock, flags);
2557
2558 g_fh_pll[i].setting_id = 0;
2559
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
2563
2564 //TODO: do we need this
2565 //fh_write32(REG_FHCTL0_MON+(i*0x10), 0x00000000); //clear all the settings
2566
2567 spin_unlock_irqrestore(&freqhopping_lock, flags);
2568 }
2569
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
2574
2575
2576 g_initialize = 1;
2577 //register change. enable_clock(MT_CG_PERI1_FHCTL, "FREQHOP") ;
2578
2579 }
2580
2581 static void mt_fh_hal_lock(unsigned long *flags)
2582 {
2583 spin_lock_irqsave(&freqhopping_lock, *flags);
2584 }
2585
2586 static void mt_fh_hal_unlock(unsigned long *flags)
2587 {
2588 spin_unlock_irqrestore(&freqhopping_lock, *flags);
2589 }
2590
2591 static int mt_fh_hal_get_init(void)
2592 {
2593 return(g_initialize);
2594 }
2595
2596 static int mt_fh_hal_is_support_DFS_mode(void)
2597 {
2598 return TRUE;
2599 }
2600
2601 //TODO: module_init(mt_freqhopping_init);
2602 //TODO: module_init(mt_freqhopping_init);
2603 //TODO: module_exit(cpufreq_exit);
2604
2605 static struct mt_fh_hal_driver g_fh_hal_drv;
2606
2607 struct mt_fh_hal_driver *mt_get_fh_hal_drv(void)
2608 {
2609 memset(&g_fh_hal_drv, 0, sizeof(g_fh_hal_drv));
2610
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;
2619 /* 8127 FHCTL MB */
2620 g_fh_hal_drv.lvdspll = MT658X_FH_LVDS_PLL;
2621 /* 8127 FHCTL ME */
2622
2623 g_fh_hal_drv.mt_fh_hal_init = mt_fh_hal_init;
2624
2625 #if MT_FH_CLK_GEN
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;
2628 #endif
2629
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;
2633
2634 g_fh_hal_drv.proc.dvfs_read = freqhopping_dvfs_proc_read;
2635 g_fh_hal_drv.proc.dvfs_write = freqhopping_dvfs_proc_write;
2636
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;
2641
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;
2644
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;
2654
2655 return (&g_fh_hal_drv);
2656 }
2657 //TODO: module_exit(cpufreq_exit);