import PULS_20180308
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / freqhopping / mt_freqhopping_drv.c
CommitLineData
6fa3eb70
S
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#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/kthread.h>
20#include <linux/delay.h>
21#include <linux/uaccess.h>
22#include <linux/io.h>
23#include <linux/platform_device.h>
24#include <linux/miscdevice.h>
25//#include <asm/sched_clock.h>
26#include <linux/vmalloc.h>
27#include <linux/dma-mapping.h>
28#include <board-custom.h>
29#include <linux/seq_file.h>
30
31#include "mach/mt_fhreg.h"
32
33#include <linux/xlog.h> //ccyeh: for 6572
34
35#if 0 //ccyeh: we don't need these header files here.
36#include "mach/mt_clkmgr.h"
37#include "mach/mt_typedefs.h"
38#include "mach/mt_gpio.h"
39#include "mach/mt_gpufreq.h"
40#include "mach/mt_cpufreq.h"
41#include "mach/emi_bwl.h"
42#include "mach/sync_write.h"
43#include "mach/mt_sleep.h"
44#endif
45
46#include <mach/mt_freqhopping_drv.h>
47
48
49#define FREQ_HOPPING_DEVICE "mt-freqhopping"
50
51#define FH_PLL_COUNT (g_p_fh_hal_drv->pll_cnt)
52
53//static unsigned int g_resume_mempll_ssc=false;
54static struct mt_fh_hal_driver *g_p_fh_hal_drv;
55
56static fh_pll_t *g_fh_drv_pll;
57static struct freqhopping_ssc *g_fh_drv_usr_def;
58static unsigned int g_drv_pll_count;
59
60static struct miscdevice mt_fh_device = {
61 .minor = MISC_DYNAMIC_MINOR,
62 .name = "mtfreqhopping",
63 //.fops = &mt_fh_fops, //TODO: Interface for UI maybe in the future...
64};
65
66
67static int mt_freqhopping_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
68
69static int mt_fh_drv_probe(struct platform_device *dev)
70{
71 int err = 0;
72
73 FH_MSG("EN: mt_fh_probe()");
74
75 if ((err = misc_register(&mt_fh_device)))
76 FH_MSG("register fh driver error!");
77
78 return err;
79}
80
81static int mt_fh_drv_remove(struct platform_device *dev)
82{
83 int err = 0;
84
85 if ((err = misc_deregister(&mt_fh_device)))
86 FH_MSG("deregister fh driver error!");
87
88 return err;
89}
90
91static void mt_fh_drv_shutdown(struct platform_device *dev)
92{
93 FH_MSG("mt_fh_shutdown");
94}
95
96static int mt_fh_drv_suspend(struct platform_device *dev, pm_message_t state)
97{
98// struct freqhopping_ioctl fh_ctl;
99
100 FH_MSG("-supd-");
101
102 return 0;
103}
104
105static int mt_fh_drv_resume(struct platform_device *dev)
106{
107// struct freqhopping_ioctl fh_ctl;
108
109 FH_MSG("+resm+");
110
111 return 0;
112}
113
114static struct platform_driver freqhopping_driver = {
115 .probe = mt_fh_drv_probe,
116 .remove = mt_fh_drv_remove,
117 .shutdown = mt_fh_drv_shutdown,
118 .suspend = mt_fh_drv_suspend,
119 .resume = mt_fh_drv_resume,
120 .driver = {
121 .name = FREQ_HOPPING_DEVICE,
122 .owner = THIS_MODULE,
123 },
124};
125
126static int mt_fh_enable_usrdef(struct freqhopping_ioctl* fh_ctl)
127{
128 unsigned long flags = 0;
129 const unsigned int pll_id = fh_ctl->pll_id;
130
131 FH_MSG("EN: %s",__func__);
132 FH_MSG("pll_id: %d",fh_ctl->pll_id);
133
134 if (fh_ctl->pll_id < FH_PLL_COUNT){
135 //we don't care the PLL status , we just change the flag & update the table
136 //the setting will be applied during the following FH enable
137
138 g_p_fh_hal_drv->mt_fh_lock(&flags);
139 memcpy(&g_fh_drv_usr_def[pll_id],&(fh_ctl->ssc_setting),sizeof(g_fh_drv_usr_def[pll_id]));
140 g_fh_drv_pll[pll_id].user_defined = true;
141 g_p_fh_hal_drv->mt_fh_unlock(&flags);
142 }
143
144 //FH_MSG("Exit");
145
146 return 0;
147
148}
149
150static int mt_fh_disable_usrdef(struct freqhopping_ioctl* fh_ctl)
151{
152 unsigned long flags = 0;
153 const unsigned int pll_id = fh_ctl->pll_id;
154
155 FH_MSG("EN: %s",__func__);
156 FH_MSG("id: %d",fh_ctl->pll_id);
157
158 if (fh_ctl->pll_id < FH_PLL_COUNT){
159 g_p_fh_hal_drv->mt_fh_lock(&flags);
160 memset(&g_fh_drv_usr_def[pll_id], 0,sizeof(g_fh_drv_usr_def[pll_id]));
161 g_fh_drv_pll[pll_id].user_defined = false;
162 g_p_fh_hal_drv->mt_fh_unlock(&flags);
163 }
164
165 //FH_MSG("Exit");
166
167 return 0;
168}
169
170static int mt_fh_hal_ctrl_lock(struct freqhopping_ioctl* fh_ctl,bool enable)
171{
172 int retVal=1;
173 unsigned long flags = 0;
174
175 FH_MSG("EN: _fctr_lck %d:%d",fh_ctl->pll_id,enable);
176
177 g_p_fh_hal_drv->mt_fh_lock(&flags);
178 retVal = g_p_fh_hal_drv->mt_fh_hal_ctrl(fh_ctl, enable);
179 g_p_fh_hal_drv->mt_fh_unlock(&flags);
180
181 return retVal;
182}
183
184
185static int mt_freqhopping_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
186{
187 //Get the structure of ioctl
188 int ret = 0;
189
190 struct freqhopping_ioctl *freqhopping_ctl = (struct freqhopping_ioctl *)arg;
191
192 FH_MSG("EN:CMD:%d pll id:%d",cmd,freqhopping_ctl->pll_id);
193
194 if(FH_CMD_ENABLE == cmd) {
195 ret = mt_fh_hal_ctrl_lock(freqhopping_ctl,true);
196 }else if(FH_CMD_DISABLE == cmd) {
197 ret = mt_fh_hal_ctrl_lock(freqhopping_ctl,false);
198 }
199 else if(FH_CMD_ENABLE_USR_DEFINED == cmd) {
200 ret = mt_fh_enable_usrdef(freqhopping_ctl);
201 }
202 else if(FH_CMD_DISABLE_USR_DEFINED == cmd) {
203 ret = mt_fh_disable_usrdef(freqhopping_ctl);
204 }else {
205 //Invalid command is not acceptable!!
206 WARN_ON(1);
207 }
208
209 //FH_MSG("Exit");
210
211 return ret;
212}
213
214//static int freqhopping_userdefine_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
215static int freqhopping_userdefine_proc_read(struct seq_file* m, void* v)
216{
217 int i=0;
218
219 FH_MSG("EN: %s",__func__);
220
221 seq_printf(m, "user defined settings:\n");
222
223 seq_printf(m, "===============================================\r\n" );
224 seq_printf(m, " freq == delta t == delta f == up bond == low bond == dds ==\r\n" );
225
226 for(i = 0;i < g_drv_pll_count ; ++i) {
227 seq_printf(m, "%10d 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\r\n"
228 ,g_fh_drv_usr_def[i].freq
229 ,g_fh_drv_usr_def[i].dt
230 ,g_fh_drv_usr_def[i].df
231 ,g_fh_drv_usr_def[i].upbnd
232 ,g_fh_drv_usr_def[i].lowbnd
233 ,g_fh_drv_usr_def[i].dds);
234 }
235
236 return 0;
237
238#if 0
239 char *p = page;
240 int len = 0;
241 int i=0;
242
243 FH_MSG("EN: %s",__func__);
244
245 p += sprintf(p, "user defined settings:\n");
246
247 p += sprintf(p, "===============================================\r\n" );
248 p += sprintf(p, " freq == delta t == delta f == up bond == low bond == dds ==\r\n" );
249
250 for(i=0;i<g_drv_pll_count ;i++) {
251 p += sprintf(p, "%10d 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\r\n"
252 ,g_fh_drv_usr_def[i].freq
253 ,g_fh_drv_usr_def[i].dt
254 ,g_fh_drv_usr_def[i].df
255 ,g_fh_drv_usr_def[i].upbnd
256 ,g_fh_drv_usr_def[i].lowbnd
257 ,g_fh_drv_usr_def[i].dds);
258 }
259
260 *start = page + off;
261
262 len = p - page;
263
264 if (len > off)
265 len -= off;
266 else
267 len = 0;
268
269 return len < count ? len : count;
270#endif
271}
272
273static ssize_t freqhopping_userdefine_proc_write(struct file *file, const char *buffer, size_t count, loff_t *data)
274{
275 int ret;
276 char kbuf[256];
277 size_t len = 0;
278 unsigned int p1,p2,p3,p4,p5,p6,p7;
279 struct freqhopping_ioctl fh_ctl;
280
281 p1 = p2 = p3 = p4 = p5 = p6 = p7 = 0;
282
283 FH_MSG("EN: %s",__func__);
284
285 len = min(count, (sizeof(kbuf)-1));
286
287 if (count == 0)return -1;
288 if(count > 255)count = 255;
289
290 ret = copy_from_user(kbuf, buffer, count);
291 if (ret < 0)return -1;
292
293 kbuf[count] = '\0';
294
295 sscanf(kbuf, "%x %x %x %x %x %x %x", &p1, &p2, &p3, &p4, &p5, &p6, &p7);
296
297 fh_ctl.pll_id = p2;
298 fh_ctl.ssc_setting.df = p3;
299 fh_ctl.ssc_setting.dt = p4;
300 fh_ctl.ssc_setting.upbnd = p5;
301 fh_ctl.ssc_setting.lowbnd = p6;
302 fh_ctl.ssc_setting.dds = p7;
303 fh_ctl.ssc_setting.freq = 0;
304
4b9e9796
S
305 /* Check validity of PLL ID */
306 if (fh_ctl.pll_id >= FH_PLL_COUNT)
307 return -1;
308
6fa3eb70
S
309
310 if( p1 == FH_CMD_ENABLE){
311 ret = mt_fh_enable_usrdef(&fh_ctl);
312 if(ret){
313 FH_MSG("__EnableUsrSetting() fail!");
314 }
315 }
316 else{
317 ret = mt_fh_disable_usrdef(&fh_ctl);
318 if(ret){
319 FH_MSG("__DisableUsrSetting() fail!");
320 }
321 }
322
323 FH_MSG("Exit: %s",__func__);
324 return count;
325}
326
327//static int freqhopping_status_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
328static int freqhopping_status_proc_read(struct seq_file* m, void* v)
329{
330 int i=0;
331
332 FH_MSG("EN: %s",__func__);
333
334 seq_printf(m, "FH status:\r\n");
335
336 seq_printf(m, "===============================================\r\n" );
337 seq_printf(m, "id == fh_status == pll_status == setting_id == curr_freq == user_defined ==\r\n" );
338
339
340 for(i = 0;i < g_drv_pll_count ; ++i) {
341 seq_printf(m, "%2d %8d %8d",
342 i,
343 g_fh_drv_pll[i].fh_status,
344 g_fh_drv_pll[i].pll_status);
345 seq_printf(m, " %8d %8d ",
346 g_fh_drv_pll[i].setting_id,
347 g_fh_drv_pll[i].curr_freq);
348
349 seq_printf(m, " %d\r\n",
350 g_fh_drv_pll[i].user_defined);
351 }
352 seq_printf(m, "\r\n");
353
354 return 0;
355
356#if 0
357 char *p = page;
358 int len = 0;
359 int i=0;
360
361 FH_MSG("EN: %s",__func__);
362
363 p += sprintf(p, "FH status:\r\n");
364
365 p += sprintf(p, "===============================================\r\n" );
366 p += sprintf(p, "id == fh_status == pll_status == setting_id == curr_freq == user_defined ==\r\n" );
367
368
369 for(i=0;i<g_drv_pll_count ;i++) {
370 p += sprintf(p, "%2d %8d %8d",
371 i,
372 g_fh_drv_pll[i].fh_status,
373 g_fh_drv_pll[i].pll_status);
374 p += sprintf(p, " %8d %8d ",
375 g_fh_drv_pll[i].setting_id,
376 g_fh_drv_pll[i].curr_freq);
377
378 p += sprintf(p, " %d\r\n",
379 g_fh_drv_pll[i].user_defined);
380 }
381#if 0
382 p += sprintf(p, "\r\nPLL status:\r\n");
383 for(i=0;i<g_drv_pll_count ;i++) {
384 p += sprintf(p, "%d ",pll_is_on(i));
385 }
386#endif
387 p += sprintf(p, "\r\n");
388
389 //TODO: unsigned int mt_get_cpu_freq(void)
390
391
392 *start = page + off;
393
394 len = p - page;
395
396 if (len > off)
397 len -= off;
398 else
399 len = 0;
400
401 return len < count ? len : count;
402#endif
403}
404
405static ssize_t freqhopping_status_proc_write(struct file *file, const char *buffer, size_t count, loff_t *data)
406{
407 int ret;
408 char kbuf[256];
409 size_t len = 0;
410 unsigned int p1,p2,p3,p4,p5,p6;
411 struct freqhopping_ioctl fh_ctl;
412
413 p1 = p2 = p3 = p4 = p5 = p6 = 0;
414
415 FH_MSG("EN: %s",__func__);
416
417 len = min(count, (sizeof(kbuf)-1));
418
419 if (count == 0)return -1;
420 if(count > 255)count = 255;
421
422 ret = copy_from_user(kbuf, buffer, count);
423 if (ret < 0)return -1;
424
425 kbuf[count] = '\0';
426
427 sscanf(kbuf, "%x %x", &p1, &p2);
428
429 fh_ctl.pll_id = p2;
430 fh_ctl.ssc_setting.df= 0;
431 fh_ctl.ssc_setting.dt= 0;
432 fh_ctl.ssc_setting.upbnd= 0;
433 fh_ctl.ssc_setting.lowbnd= 0;
434
4b9e9796
S
435 /* Check validity of PLL ID */
436 if (fh_ctl.pll_id >= FH_PLL_COUNT)
437 return -1;
438
6fa3eb70
S
439 if( p1 == 0){
440 mt_freqhopping_ioctl(NULL,FH_CMD_DISABLE,(unsigned long)(&fh_ctl));
441 }
442 else{
443 mt_freqhopping_ioctl(NULL,FH_CMD_ENABLE,(unsigned long)(&fh_ctl));
444 }
445
446 return count;
447}
448
449//static int freqhopping_debug_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
450static int freqhopping_debug_proc_read(struct seq_file* m, void* v)
451{
452#if defined(PLATFORM_DEP_DEBUG_PROC_READ)
453 FH_IO_PROC_READ_T arg;
454 arg.m = m;
455 arg.v = v;
456 arg.pll = g_fh_drv_pll;
4b9e9796 457 //g_p_fh_hal_drv->ioctl(FH_IO_PROC_READ, &arg);
6fa3eb70
S
458 return 0;
459#else
460 FH_MSG("EN: %s",__func__);
461
462 seq_printf(m, "\r\n[freqhopping debug flag]\r\n");
463 seq_printf(m, "===============================================\r\n" );
464 seq_printf(m, "id==ARMPLL==MAINPLL==MEMPLL==MSDCPLL==MMPLL==VENCPLL\r\n" );
465 seq_printf(m, " == %04d====%04d====%04d====%04d====%04d====%04d=\r\n" ,
466 g_fh_drv_pll[MT658X_FH_ARM_PLL].fh_status, g_fh_drv_pll[MT658X_FH_MAIN_PLL].fh_status,
467 g_fh_drv_pll[MT658X_FH_MEM_PLL].fh_status, g_fh_drv_pll[MT658X_FH_MSDC_PLL].fh_status,
468 g_fh_drv_pll[MT658X_FH_MM_PLL].fh_status, g_fh_drv_pll[MT658X_FH_VENC_PLL].fh_status);
469 seq_printf(m, " == %04d====%04d====%04d====%04d====%04d====%04d=\r\n" ,
470 g_fh_drv_pll[MT658X_FH_ARM_PLL].setting_id, g_fh_drv_pll[MT658X_FH_MAIN_PLL].setting_id,
471 g_fh_drv_pll[MT658X_FH_MEM_PLL].setting_id, g_fh_drv_pll[MT658X_FH_MSDC_PLL].setting_id,
472 g_fh_drv_pll[MT658X_FH_MM_PLL].setting_id, g_fh_drv_pll[MT658X_FH_VENC_PLL].setting_id);
473 return 0;
474#if 0
475 char *p = page;
476 int len = 0;
477
478 FH_MSG("EN: %s",__func__);
479
480 p += sprintf(p, "\r\n[freqhopping debug flag]\r\n");
481 p += sprintf(p, "===============================================\r\n" );
482 p += sprintf(p, "id==ARMPLL==MAINPLL==MEMPLL==MSDCPLL==MMPLL==VENCPLL\r\n" );
483 p += sprintf(p, " == %04d====%04d====%04d====%04d====%04d====%04d=\r\n" ,
484 g_fh_drv_pll[MT658X_FH_ARM_PLL].fh_status, g_fh_drv_pll[MT658X_FH_MAIN_PLL].fh_status,
485 g_fh_drv_pll[MT658X_FH_MEM_PLL].fh_status, g_fh_drv_pll[MT658X_FH_MSDC_PLL].fh_status,
486 g_fh_drv_pll[MT658X_FH_MM_PLL].fh_status, g_fh_drv_pll[MT658X_FH_VENC_PLL].fh_status);
487 p += sprintf(p, " == %04d====%04d====%04d====%04d====%04d====%04d=\r\n" ,
488 g_fh_drv_pll[MT658X_FH_ARM_PLL].setting_id, g_fh_drv_pll[MT658X_FH_MAIN_PLL].setting_id,
489 g_fh_drv_pll[MT658X_FH_MEM_PLL].setting_id, g_fh_drv_pll[MT658X_FH_MSDC_PLL].setting_id,
490 g_fh_drv_pll[MT658X_FH_MM_PLL].setting_id, g_fh_drv_pll[MT658X_FH_VENC_PLL].setting_id);
491
492 *start = page + off;
493
494 len = p - page;
495
496 if (len > off)
497 len -= off;
498 else
499 len = 0;
500
501 return len < count ? len : count;
502#endif
503#endif
504}
505
506static ssize_t freqhopping_debug_proc_write(struct file *file, const char *buffer, size_t count, loff_t *data)
507{
508 int ret;
509 char kbuf[256];
510 size_t len = 0;
511 unsigned int cmd,p1,p2,p3,p4,p5,p6,p7;
512 struct freqhopping_ioctl fh_ctl;
513
514 p1 = p2 = p3 = p4 = p5 = p6 = p7 = 0;
515
516 FH_MSG("EN: %s",__func__);
517
518 len = min(count, (sizeof(kbuf)-1));
519
520 if (count == 0)return -1;
521 if(count > 255)count = 255;
522
523 ret = copy_from_user(kbuf, buffer, count);
524 if (ret < 0)return -1;
525
526 kbuf[count] = '\0';
527
528 sscanf(kbuf, "%x %x %x %x %x %x %x %x", &cmd, &p1, &p2, &p3, &p4, &p5, &p6, &p7);
529
530 //ccyeh fh_ctl.opcode = p1;
531 fh_ctl.pll_id = p2;
532 //ccyeh removed fh_ctl.ssc_setting_id = p3;
533 fh_ctl.ssc_setting.dds = p3;
534 fh_ctl.ssc_setting.df = p4;
535 fh_ctl.ssc_setting.dt = p5;
536 fh_ctl.ssc_setting.upbnd = p6;
537 fh_ctl.ssc_setting.lowbnd = p7;
538 fh_ctl.ssc_setting.freq = 0;
539
4b9e9796
S
540 /* Check validity of PLL ID */
541 if (fh_ctl.pll_id >= FH_PLL_COUNT)
542 return -1;
543
6fa3eb70
S
544
545 if (cmd < FH_CMD_INTERNAL_MAX_CMD) {
546 mt_freqhopping_ioctl(NULL,cmd,(unsigned long)(&fh_ctl));
547 }
548 else if((cmd > FH_DCTL_CMD_ID) && (cmd < FH_DCTL_CMD_MAX))
549 {
550 mt_freqhopping_devctl(cmd, &fh_ctl);
551 }
552 else {
553 FH_MSG("CMD error!");
554 }
555
556 return count;
557}
558
559static int freqhopping_debug_proc_open(struct inode *inode, struct file *file)
560{
561 return single_open(file, freqhopping_debug_proc_read, NULL);
562}
563
564static int freqhopping_dramc_proc_open(struct inode *inode, struct file *file)
565{
566 return single_open(file, g_p_fh_hal_drv->proc.dramc_read, NULL);
567}
568static ssize_t freqhopping_dramc_proc_write(struct file *file, const char *buffer, size_t count, loff_t *data)
569{
570 return (ssize_t)(g_p_fh_hal_drv->proc.dramc_write(file, buffer, count, data));
571}
572
573static int freqhopping_dvfs_proc_open(struct inode *inode, struct file *file)
574{
575 return single_open(file, g_p_fh_hal_drv->proc.dvfs_read, NULL);
576}
577static ssize_t freqhopping_dvfs_proc_write(struct file *file, const char *buffer, size_t count, loff_t *data)
578{
579 return (ssize_t)(g_p_fh_hal_drv->proc.dvfs_write(file, buffer, count, data));
580}
581
582static int freqhopping_dumpregs_proc_open(struct inode *inode, struct file *file)
583{
584 return single_open(file, g_p_fh_hal_drv->proc.dumpregs_read, NULL);
585}
586
587static int freqhopping_status_proc_open(struct inode *inode, struct file *file)
588{
589 return single_open(file, freqhopping_status_proc_read, NULL);
590}
591static int freqhopping_userdefine_proc_open(struct inode *inode, struct file *file)
592{
593 return single_open(file, freqhopping_userdefine_proc_read, NULL);
594}
595
596static const struct file_operations freqhopping_debug_fops = {
597 .owner = THIS_MODULE,
598 .open = freqhopping_debug_proc_open,
599 .read = seq_read,
600 .write = freqhopping_debug_proc_write,
601};
602static const struct file_operations dramc_fops = {
603 .owner = THIS_MODULE,
604 .open = freqhopping_dramc_proc_open,
605 .read = seq_read,
606 .write = freqhopping_dramc_proc_write,
607};
608static const struct file_operations dvfs_fops = {
609 .owner = THIS_MODULE,
610 .open = freqhopping_dvfs_proc_open,
611 .read = seq_read,
612 .write = freqhopping_dvfs_proc_write,
613};
614static const struct file_operations dumpregs_fops = {
615 .owner = THIS_MODULE,
616 .open = freqhopping_dumpregs_proc_open,
617 .read = seq_read,
618};
619static const struct file_operations status_fops = {
620 .owner = THIS_MODULE,
621 .open = freqhopping_status_proc_open,
622 .read = seq_read,
623 .write = freqhopping_status_proc_write,
624};
625static const struct file_operations userdef_fops = {
626 .owner = THIS_MODULE,
627 .open = freqhopping_userdefine_proc_open,
628 .read = seq_read,
629 .write = freqhopping_userdefine_proc_write,
630};
631
632static int freqhopping_debug_proc_init(void)
633{
634 struct proc_dir_entry *prDebugEntry;
635 struct proc_dir_entry *prDramcEntry;
636 struct proc_dir_entry *prDumpregEntry;
637 struct proc_dir_entry *prStatusEntry;
638 struct proc_dir_entry *prUserdefEntry;
639 struct proc_dir_entry *fh_proc_dir = NULL;
640
641 //TODO: check the permission!!
642
643 FH_MSG("EN: %s",__func__);
644
645 fh_proc_dir = proc_mkdir("freqhopping", NULL);
646 if (!fh_proc_dir){
647 FH_MSG("proc_mkdir fail!");
648 return 1;
649 }
650 else{
651
652
653 /* /proc/freqhopping/freqhopping_debug */
654 //prDebugEntry = create_proc_entry("freqhopping_debug", S_IRUGO | S_IWUSR | S_IWGRP, fh_proc_dir);
655 prDebugEntry = proc_create("freqhopping_debug", S_IRUGO | S_IWUSR | S_IWGRP, fh_proc_dir, &freqhopping_debug_fops);
656 if(prDebugEntry)
657 {
658 //prDebugEntry->read_proc = freqhopping_debug_proc_read;
659 //prDebugEntry->write_proc = freqhopping_debug_proc_write;
660 FH_MSG("[%s]: successfully create /proc/freqhopping_debug", __func__);
661 }else{
662 FH_MSG("[%s]: failed to create /proc/freqhopping/freqhopping_debug", __func__);
663 return 1;
664 }
665
666
667 /* /proc/freqhopping/dramc */
668 //prDramcEntry = create_proc_entry("dramc", S_IRUGO | S_IWUSR | S_IWGRP, fh_proc_dir);
669 prDramcEntry = proc_create("dramc", S_IRUGO | S_IWUSR | S_IWGRP, fh_proc_dir, &dramc_fops);
670 if(prDramcEntry)
671 {
672 //prDramcEntry->read_proc = g_p_fh_hal_drv->proc.dramc_read;
673 //prDramcEntry->write_proc = g_p_fh_hal_drv->proc.dramc_write;
674 FH_MSG("[%s]: successfully create /proc/freqhopping/prDramcEntry", __func__);
675 }else{
676 FH_MSG("[%s]: failed to create /proc/freqhopping/prDramcEntry", __func__);
677 return 1;
678 }
679 /* /proc/freqhopping/dvfs */
680 //prDramcEntry = create_proc_entry("dvfs", S_IRUGO | S_IWUSR | S_IWGRP, fh_proc_dir);
681 prDramcEntry = proc_create("dvfs", S_IRUGO | S_IWUSR | S_IWGRP, fh_proc_dir, &dvfs_fops);
682 if(prDramcEntry)
683 {
684 //prDramcEntry->read_proc = g_p_fh_hal_drv->proc.dvfs_read;
685 //prDramcEntry->write_proc = g_p_fh_hal_drv->proc.dvfs_write;
686 FH_MSG("[%s]: successfully create /proc/freqhopping/dvfs", __func__);
687 }else{
688 FH_MSG("[%s]: failed to create /proc/freqhopping/dvfs", __func__);
689 return 1;
690 }
691
692
693 /* /proc/freqhopping/dumpregs */
694 //prDumpregEntry = create_proc_entry("dumpregs", S_IRUGO | S_IWUSR | S_IWGRP, fh_proc_dir);
695 prDumpregEntry = proc_create("dumpregs", S_IRUGO | S_IWUSR | S_IWGRP, fh_proc_dir, &dumpregs_fops);
696 if(prDumpregEntry)
697 {
698 //prDumpregEntry->read_proc = g_p_fh_hal_drv->proc.dumpregs_read;
699 //prDumpregEntry->write_proc = NULL;
700 FH_MSG("[%s]: successfully create /proc/freqhopping/dumpregs", __func__);
701 }else{
702 FH_MSG("[%s]: failed to create /proc/freqhopping/dumpregs", __func__);
703 return 1;
704 }
705
706
707 /* /proc/freqhopping/status */
708 //prStatusEntry = create_proc_entry("status", S_IRUGO | S_IWUSR | S_IWGRP, fh_proc_dir);
709 prStatusEntry = proc_create("status", S_IRUGO | S_IWUSR | S_IWGRP, fh_proc_dir, &status_fops);
710 if(prStatusEntry)
711 {
712 //prStatusEntry->read_proc = freqhopping_status_proc_read;
713 //prStatusEntry->write_proc = freqhopping_status_proc_write;
714 FH_MSG("[%s]: successfully create /proc/freqhopping/status", __func__);
715 }else{
716 FH_MSG("[%s]: failed to create /proc/freqhopping/status", __func__);
717 return 1;
718 }
719
720
721 /* /proc/freqhopping/userdefine */
722 //prUserdefEntry = create_proc_entry("userdef", S_IRUGO | S_IWUSR | S_IWGRP, fh_proc_dir);
723 prUserdefEntry = proc_create("userdef", S_IRUGO | S_IWUSR | S_IWGRP, fh_proc_dir, &userdef_fops);
724 if(prUserdefEntry)
725 {
726 //prUserdefEntry->read_proc = freqhopping_userdefine_proc_read;
727 //prUserdefEntry->write_proc = freqhopping_userdefine_proc_write;
728 FH_MSG("[%s]: successfully create /proc/freqhopping/userdef", __func__);
729 }else{
730 FH_MSG("[%s]: failed to create /proc/freqhopping/userdef", __func__);
731 return 1;
732 }
733
734#if 0// MT_FH_CLK_GEN
735 /* /proc/freqhopping/clkgen */
736 prUserdefEntry = create_proc_entry("clkgen", S_IRUGO | S_IWUSR | S_IWGRP, fh_proc_dir);
737 if(prUserdefEntry)
738 {
739 prUserdefEntry->read_proc = g_p_fh_hal_drv->proc.clk_gen_read;
740 prUserdefEntry->write_proc = g_p_fh_hal_drv->proc.clk_gen_write;
741 FH_MSG("[%s]: successfully create /proc/freqhopping/clkgen", __func__);
742 }else{
743 FH_MSG("[%s]: failed to create /proc/freqhopping/clkgen", __func__);
744 return 1;
745 }
746#endif //MT_FH_CLK_GEN
747 }
748
749 return 0 ;
750}
751
752#if defined(DISABLE_FREQ_HOPPING)
753void mt_fh_popod_save(void){}
754EXPORT_SYMBOL(mt_fh_popod_save);
755
756void mt_fh_popod_restore(void){}
757EXPORT_SYMBOL(mt_fh_popod_restore);
758
759int freqhopping_config(unsigned int pll_id, unsigned long vco_freq, unsigned int enable){return 0;}
760EXPORT_SYMBOL(freqhopping_config);
761
762int mt_l2h_mempll(void){return 0;}
763EXPORT_SYMBOL(mt_l2h_mempll);
764
765int mt_h2l_mempll(void){return 0;}
766EXPORT_SYMBOL(mt_h2l_mempll);
767
768int mt_dfs_armpll(unsigned int current_freq, unsigned int target_dds){return 0;}
769EXPORT_SYMBOL(mt_dfs_armpll);
770
771int mt_dfs_mmpll(unsigned int target_dds){ return 0;}
772EXPORT_SYMBOL(mt_dfs_mmpll);
773
774int mt_dfs_vencpll(unsigned int target_dds){return 0;}
775EXPORT_SYMBOL(mt_dfs_vencpll);
776
777int mt_dfs_mpll(unsigned int target_dds){return 0;}
778EXPORT_SYMBOL(mt_dfs_mpll);
779
780int mt_is_support_DFS_mode(void){return 0;}
781EXPORT_SYMBOL(mt_is_support_DFS_mode);
782
783int mt_l2h_dvfs_mempll(void){return 0;}
784EXPORT_SYMBOL(mt_l2h_dvfs_mempll);
785
786int mt_h2l_dvfs_mempll(void){return 0;}
787EXPORT_SYMBOL(mt_h2l_dvfs_mempll);
788
789int mt_fh_dram_overclock(int clk){return 0;}
790EXPORT_SYMBOL(mt_fh_dram_overclock);
791
792int mt_fh_get_dramc(void){return 0;}
793EXPORT_SYMBOL(mt_fh_get_dramc);
794
795void mt_freqhopping_init(void){}
796EXPORT_SYMBOL(mt_freqhopping_init);
797
798void mt_freqhopping_pll_init(void){}
799EXPORT_SYMBOL(mt_freqhopping_pll_init);
800
801int mt_freqhopping_devctl(unsigned int cmd, void* args){return 0;}
802EXPORT_SYMBOL(mt_freqhopping_devctl);
803
804#else
805void mt_fh_popod_save(void)
806{
807 if(!g_p_fh_hal_drv)
808 {
809 FH_MSG("[%s]: g_p_fh_hal_drv is uninitialized.", __func__);
810 return;
811 }
812 FH_MSG("EN: %s",__func__);
813
814 g_p_fh_hal_drv->mt_fh_popod_save();
815}
816EXPORT_SYMBOL(mt_fh_popod_save);
817
818void mt_fh_popod_restore(void)
819{
820 if(!g_p_fh_hal_drv)
821 {
822 FH_MSG("[%s]: g_p_fh_hal_drv is uninitialized.", __func__);
823 return;
824 }
825
826 FH_MSG("EN: %s",__func__);
827
828 g_p_fh_hal_drv->mt_fh_popod_restore();
829}
830EXPORT_SYMBOL(mt_fh_popod_restore);
831
832int freqhopping_config(unsigned int pll_id, unsigned long vco_freq, unsigned int enable)
833{
834 struct freqhopping_ioctl fh_ctl;
835 unsigned int fh_status;
836 unsigned long flags=0;
837 unsigned int skip_flag=0;
838
839 FH_MSG("conf() id: %d f: %d, e: %d",(int)pll_id, (int)vco_freq, (int)enable);
840
841 if( (g_p_fh_hal_drv->mt_fh_get_init()) == 0){
842 FH_MSG("Not init yet, init first.");
843 return 1;
844 }
845
846 g_p_fh_hal_drv->mt_fh_lock(&flags);
847
848 //backup
849 fh_status = g_fh_drv_pll[pll_id].fh_status;
850
851 g_fh_drv_pll[pll_id].curr_freq = vco_freq;
852 g_fh_drv_pll[pll_id].pll_status = (enable > 0) ? FH_PLL_ENABLE:FH_PLL_DISABLE;
853
854
855 //prepare freqhopping_ioctl
856 fh_ctl.pll_id = pll_id;
857
858 if(g_fh_drv_pll[pll_id].fh_status != FH_FH_DISABLE){
859 //FH_MSG("+fh");
860 g_p_fh_hal_drv->mt_fh_hal_ctrl(&fh_ctl,enable);
861
862 }
863 else{
864 skip_flag = 1;
865 //FH_MSG("-fh,skip");
866 }
867
868 //restore
869 g_fh_drv_pll[pll_id].fh_status = fh_status;
870
871 g_p_fh_hal_drv->mt_fh_unlock(&flags);
872
873 if(skip_flag)
874 FH_MSG("-fh,skip");
875
876 return 0;
877}
878EXPORT_SYMBOL(freqhopping_config);
879
880
881int mt_l2h_mempll(void)
882{
883 return(g_p_fh_hal_drv->mt_l2h_mempll());
884}
885EXPORT_SYMBOL(mt_l2h_mempll);
886
887int mt_h2l_mempll(void)
888{
889 return(g_p_fh_hal_drv->mt_h2l_mempll());
890}
891EXPORT_SYMBOL(mt_h2l_mempll);
892
893int mt_dfs_armpll(unsigned int current_freq, unsigned int target_dds)
894{
895 if(!g_p_fh_hal_drv)
896 {
897 FH_MSG("[%s]: g_p_fh_hal_drv is uninitialized.", __func__);
898 return 1;
899 }
900
901 return(g_p_fh_hal_drv->mt_dfs_armpll(current_freq, target_dds));
902}
903EXPORT_SYMBOL(mt_dfs_armpll);
904int mt_dfs_mmpll(unsigned int target_dds)
905{
906 if(!g_p_fh_hal_drv)
907 {
908 FH_MSG("[%s]: g_p_fh_hal_drv is uninitialized.", __func__);
909 return 1;
910 }
911 return(g_p_fh_hal_drv->mt_dfs_mmpll(target_dds));
912}
913EXPORT_SYMBOL(mt_dfs_mmpll);
914int mt_dfs_vencpll(unsigned int target_dds)
915{
916 if(!g_p_fh_hal_drv)
917 {
918 FH_MSG("[%s]: g_p_fh_hal_drv is uninitialized.", __func__);
919 return 1;
920 }
921
922 return(g_p_fh_hal_drv->mt_dfs_vencpll(target_dds));
923}
924EXPORT_SYMBOL(mt_dfs_vencpll);
925
926int mt_dfs_mpll(unsigned int target_dds)
927{
928 if((!g_p_fh_hal_drv) || (!g_p_fh_hal_drv->mt_dfs_mpll))
929 {
930 FH_MSG("[%s]: g_p_fh_hal_drv is uninitialized.", __func__);
931 return 1;
932 }
933
934 return(g_p_fh_hal_drv->mt_dfs_mpll(target_dds));
935
936}
937EXPORT_SYMBOL(mt_dfs_mpll);
938
939
940int mt_is_support_DFS_mode(void)
941{
942 return(g_p_fh_hal_drv->mt_is_support_DFS_mode());
943}
944EXPORT_SYMBOL(mt_is_support_DFS_mode);
945int mt_l2h_dvfs_mempll(void)
946{
947 if(!g_p_fh_hal_drv)
948 {
949 FH_MSG("[%s]: g_p_fh_hal_drv is uninitialized.", __func__);
950 return 1;
951 }
952 return(g_p_fh_hal_drv->mt_l2h_dvfs_mempll());
953}
954EXPORT_SYMBOL(mt_l2h_dvfs_mempll);
955
956int mt_h2l_dvfs_mempll(void)
957{
958 if(!g_p_fh_hal_drv)
959 {
960 FH_MSG("[%s]: g_p_fh_hal_drv is uninitialized.", __func__);
961 return 1;
962 }
963
964 return(g_p_fh_hal_drv->mt_h2l_dvfs_mempll());
965}
966EXPORT_SYMBOL(mt_h2l_dvfs_mempll);
967int mt_fh_dram_overclock(int clk)
968{
969 return (g_p_fh_hal_drv->mt_dram_overclock(clk));
970}
971EXPORT_SYMBOL(mt_fh_dram_overclock);
972
973int mt_fh_get_dramc(void)
974{
975 return (g_p_fh_hal_drv->mt_get_dramc());
976}
977EXPORT_SYMBOL(mt_fh_get_dramc);
978
979void mt_freqhopping_init(void)
980{
981 g_p_fh_hal_drv = mt_get_fh_hal_drv();
982
983 g_p_fh_hal_drv->mt_fh_hal_init();
984
985 g_fh_drv_pll = g_p_fh_hal_drv->fh_pll;
986 g_fh_drv_usr_def = g_p_fh_hal_drv->fh_usrdef;
987 g_drv_pll_count = g_p_fh_hal_drv->pll_cnt;
988
989 freqhopping_debug_proc_init();
990 platform_driver_register(&freqhopping_driver);
991
992 mt_freqhopping_pll_init(); //TODO_HAL: wait for clkmgr to invoke this function
993}
994EXPORT_SYMBOL(mt_freqhopping_init);
995
996void mt_freqhopping_pll_init(void)
997{
998 g_p_fh_hal_drv->mt_fh_default_conf();
999}
1000EXPORT_SYMBOL(mt_freqhopping_pll_init);
1001
1002int mt_freqhopping_devctl(unsigned int cmd, void* args)
1003{
1004 if(!g_p_fh_hal_drv)
1005 {
1006 return 1;
1007 }
1008
4b9e9796 1009 //g_p_fh_hal_drv->ioctl(cmd, args);
6fa3eb70
S
1010 return 0;
1011
1012}
1013EXPORT_SYMBOL(mt_freqhopping_devctl);
1014
1015
1016#endif