]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/arm/mach-mx6/bus_freq.c
ENGR00221161 [MX6SL]- Add audio bus freq mode support.
[karo-tx-linux.git] / arch / arm / mach-mx6 / bus_freq.c
1 /*
2  * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 /*!
20  * @file bus_freq.c
21  *
22  * @brief A common API for the Freescale Semiconductor i.MXC CPUfreq module
23  * and DVFS CORE module.
24  *
25  * The APIs are for setting bus frequency to low or high.
26  *
27  * @ingroup PM
28  */
29 #include <asm/io.h>
30 #include <linux/sched.h>
31 #include <linux/proc_fs.h>
32 #include <linux/clk.h>
33 #include <linux/delay.h>
34 #include <linux/platform_device.h>
35 #include <linux/regulator/consumer.h>
36 #include <linux/mutex.h>
37 #include <mach/iram.h>
38 #include <mach/hardware.h>
39 #include <mach/clock.h>
40 #include <mach/mxc_dvfs.h>
41 #include <mach/sdram_autogating.h>
42 #include <asm/mach/map.h>
43 #include <asm/mach-types.h>
44 #include <asm/cacheflush.h>
45 #include <asm/tlb.h>
46 #include "crm_regs.h"
47 #include <linux/suspend.h>
48
49 #define LPAPM_CLK               24000000
50 #define DDR_AUDIO_CLK   50000000
51 #define DDR_MED_CLK             400000000
52 #define DDR3_NORMAL_CLK         528000000
53 #define GPC_PGC_GPU_PGCR_OFFSET 0x260
54 #define GPC_CNTR_OFFSET         0x0
55
56 static DEFINE_SPINLOCK(freq_lock);
57
58 int low_bus_freq_mode;
59 int audio_bus_freq_mode;
60 int high_bus_freq_mode;
61 int med_bus_freq_mode;
62
63 int bus_freq_scaling_initialized;
64 static struct device *busfreq_dev;
65 static int busfreq_suspended;
66
67 /* True if bus_frequency is scaled not using DVFS-PER */
68 int bus_freq_scaling_is_active;
69
70 int lp_high_freq;
71 int lp_med_freq;
72 int lp_audio_freq;
73 int high_cpu_freq;
74 unsigned int ddr_low_rate;
75 unsigned int ddr_med_rate;
76 unsigned int ddr_normal_rate;
77
78 int low_freq_bus_used(void);
79 void set_ddr_freq(int ddr_freq);
80 void *mx6sl_wfi_iram_base;
81 void (*mx6sl_wfi_iram)(int arm_podf, unsigned long wfi_iram_addr) = NULL;
82 extern void mx6sl_wait (int arm_podf, unsigned long wfi_iram_addr);
83
84 void *mx6sl_ddr_freq_base;
85 void (*mx6sl_ddr_freq_change_iram)(int ddr_freq, int low_bus_freq_mode) = NULL;
86 extern void mx6sl_ddr_iram(int ddr_freq);
87
88 extern int init_mmdc_settings(void);
89 extern struct cpu_op *(*get_cpu_op)(int *op);
90 extern int update_ddr_freq(int ddr_rate);
91 extern int chip_rev;
92
93 DEFINE_MUTEX(bus_freq_mutex);
94
95 struct timeval start_time;
96 struct timeval end_time;
97
98 static int cpu_op_nr;
99 static u32 org_arm_podf;
100 static struct cpu_op *cpu_op_tbl;
101 static struct clk *pll2_400;
102 static struct clk *axi_clk;
103 static struct clk *ahb_clk;
104 static struct clk *periph_clk;
105 static struct clk *osc_clk;
106 static struct clk *cpu_clk;
107 static struct clk *pll3;
108 static struct clk *pll2;
109 static struct clk *pll1;
110 static struct clk *pll1_sw_clk;
111 static struct clk *pll3_sw_clk;
112 static struct clk *pll2_200;
113 static struct clk *mmdc_ch0_axi;
114 static struct clk *pll3_540;
115
116 static struct delayed_work low_bus_freq_handler;
117
118 static void reduce_bus_freq_handler(struct work_struct *work)
119 {
120         mutex_lock(&bus_freq_mutex);
121         if (low_bus_freq_mode || !low_freq_bus_used()) {
122                 mutex_unlock(&bus_freq_mutex);
123                 return;
124         }
125
126         if (audio_bus_freq_mode && lp_audio_freq) {
127                 mutex_unlock(&bus_freq_mutex);
128                 return;
129         }
130
131         if (!cpu_is_mx6sl()) {
132                 if (cpu_is_mx6dl() &&
133                         (clk_get_parent(axi_clk) != periph_clk))
134                         /* Set the axi_clk to be sourced from the periph_clk.
135                           * So that its frequency can be lowered down to 50MHz
136                           * or 24MHz as the case may be.
137                           */
138                         clk_set_parent(axi_clk, periph_clk);
139
140                 clk_enable(pll3);
141                 if (lp_audio_freq) {
142                         /* Need to ensure that PLL2_PFD_400M is kept ON. */
143                         clk_enable(pll2_400);
144                         update_ddr_freq(DDR_AUDIO_CLK);
145                         /* Make sure periph clk's parent also got updated */
146                         clk_set_parent(periph_clk, pll2_200);
147                         audio_bus_freq_mode = 1;
148                         low_bus_freq_mode = 0;
149                 } else {
150                         update_ddr_freq(LPAPM_CLK);
151                         /* Make sure periph clk's parent also got updated */
152                         clk_set_parent(periph_clk, osc_clk);
153                         if (audio_bus_freq_mode)
154                                 clk_disable(pll2_400);
155                         low_bus_freq_mode = 1;
156                         audio_bus_freq_mode = 0;
157                 }
158
159                 if (med_bus_freq_mode)
160                         clk_disable(pll2_400);
161
162                 clk_disable(pll3);
163                 med_bus_freq_mode = 0;
164         } else {
165                 u32 reg;
166                 u32  div;
167                 unsigned long flags;
168
169                 spin_lock_irqsave(&freq_lock, flags);
170
171                 if (high_bus_freq_mode) {
172                         /* Set periph_clk to be sourced from OSC_CLK */
173                         /* Set AXI to 24MHz. */
174                         clk_set_parent(periph_clk, osc_clk);
175                         clk_set_rate(axi_clk,
176                                 clk_round_rate(axi_clk, LPAPM_CLK));
177                         /* Set AHB to 24MHz. */
178                         clk_set_rate(ahb_clk,
179                                 clk_round_rate(ahb_clk, LPAPM_CLK));
180                 }
181                 if (lp_audio_freq) {
182                         /* PLL2 is on in this mode, as DDR is at 50MHz. */
183                         /* Now change DDR freq while running from IRAM. */
184                         mx6sl_ddr_freq_change_iram(DDR_AUDIO_CLK,
185                                                         low_bus_freq_mode);
186
187                         if (low_bus_freq_mode) {
188                                 /* Swtich ARM to run off PLL2_PFD2_400MHz
189                                  * since DDR is anway at 50MHz.
190                                  */
191                                 clk_set_parent(pll1_sw_clk, pll2_400);
192
193                                 /* Ensure that the clock will be
194                                   * at original speed.
195                                   */
196                                 reg = __raw_writel(org_arm_podf, MXC_CCM_CACRR);
197                                 while (__raw_readl(MXC_CCM_CDHIPR))
198                                         ;
199                         }
200                         low_bus_freq_mode = 0;
201                         audio_bus_freq_mode = 1;
202                 } else {
203                         /* Set MMDC clk to 24MHz. */
204                         /* Since we are going to set PLL2 in bypass mode,
205                           * move the CPU clock off PLL2.
206                           */
207                         /* Ensure that the clock will be at
208                           * lowest possible freq.
209                           */
210                         org_arm_podf = __raw_readl(MXC_CCM_CACRR);
211                         div = clk_get_rate(pll1) /
212                                         cpu_op_tbl[cpu_op_nr - 1].cpu_rate;
213
214                         reg = __raw_writel(div - 1, MXC_CCM_CACRR);
215                         while (__raw_readl(MXC_CCM_CDHIPR))
216                                 ;
217                         clk_set_parent(pll1_sw_clk, pll1);
218
219                         /* Now change DDR freq while running from IRAM. */
220                         mx6sl_ddr_freq_change_iram(LPAPM_CLK,
221                                         low_bus_freq_mode);
222
223                         low_bus_freq_mode = 1;
224                         audio_bus_freq_mode = 0;
225                 }
226                 spin_unlock_irqrestore(&freq_lock, flags);
227         }
228         high_bus_freq_mode = 0;
229         mutex_unlock(&bus_freq_mutex);
230 }
231
232 /* Set the DDR, AHB to 24MHz.
233   * This mode will be activated only when none of the modules that
234   * need a higher DDR or AHB frequency are active.
235   */
236 int set_low_bus_freq(void)
237 {
238         if (busfreq_suspended)
239                 return 0;
240
241         if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
242                 return 0;
243
244         /* Don't lower the frequency immediately. Instead scheduled a delayed
245           * work and drop the freq if the conditions still remain the same.
246           */
247         schedule_delayed_work(&low_bus_freq_handler, usecs_to_jiffies(3000000));
248         return 0;
249 }
250
251 /* Set the DDR to either 528MHz or 400MHz for MX6q
252  * or 400MHz for MX6DL.
253  */
254 int set_high_bus_freq(int high_bus_freq)
255 {
256         if (bus_freq_scaling_initialized && bus_freq_scaling_is_active)
257                 cancel_delayed_work_sync(&low_bus_freq_handler);
258
259         if (busfreq_suspended)
260                 return 0;
261
262
263         if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
264                 return 0;
265
266
267         if (high_bus_freq_mode && high_bus_freq)
268                 return 0;
269
270
271         /* medium bus freq is only supported for MX6DQ */
272         if (cpu_is_mx6q() && med_bus_freq_mode && !high_bus_freq)
273                 return 0;
274
275         if (cpu_is_mx6dl() && high_bus_freq)
276                 high_bus_freq = 0;
277
278         if (cpu_is_mx6dl() && med_bus_freq_mode)
279                 return 0;
280
281         if ((high_bus_freq_mode && (high_bus_freq || lp_high_freq)) ||
282             (med_bus_freq_mode && !high_bus_freq && lp_med_freq &&
283              !lp_high_freq))
284                 return 0;
285
286         if (cpu_is_mx6sl()) {
287                 u32 reg;
288                 unsigned long flags;
289
290                 spin_lock_irqsave(&freq_lock, flags);
291                 /* Change DDR freq in IRAM. */
292                 mx6sl_ddr_freq_change_iram(ddr_normal_rate, low_bus_freq_mode);
293
294                 /* Set periph_clk to be sourced from pll2_pfd2_400M */
295                 /* First need to set the divider before changing the */
296                 /* parent if parent clock is larger than previous one */
297                 clk_set_rate(ahb_clk, clk_round_rate(ahb_clk,
298                                                      LPAPM_CLK / 3));
299                 clk_set_rate(axi_clk,
300                              clk_round_rate(axi_clk, LPAPM_CLK / 2));
301                 clk_set_parent(periph_clk, pll2_400);
302
303                 if (low_bus_freq_mode) {
304                         /* Now move ARM to be sourced from PLL2_400 too. */
305                         clk_set_parent(pll1_sw_clk, pll2_400);
306
307                         /* Ensure that the clock will be at original speed. */
308                         reg = __raw_writel(org_arm_podf, MXC_CCM_CACRR);
309                         while (__raw_readl(MXC_CCM_CDHIPR))
310                                 ;
311                 }
312                 high_bus_freq_mode = 1;
313                 low_bus_freq_mode = 0;
314                 audio_bus_freq_mode = 0;
315                 spin_unlock_irqrestore(&freq_lock, flags);
316         } else {
317                 clk_enable(pll3);
318                 if (high_bus_freq) {
319                         update_ddr_freq(ddr_normal_rate);
320                         /* Make sure periph clk's parent also got updated */
321                         clk_set_parent(periph_clk, pll2);
322                         if (med_bus_freq_mode)
323                                 clk_disable(pll2_400);
324                         high_bus_freq_mode = 1;
325                         med_bus_freq_mode = 0;
326                 } else {
327                         clk_enable(pll2_400);
328                         update_ddr_freq(ddr_med_rate);
329                         /* Make sure periph clk's parent also got updated */
330                         clk_set_parent(periph_clk, pll2_400);
331                         high_bus_freq_mode = 0;
332                         med_bus_freq_mode = 1;
333                 }
334                 if (audio_bus_freq_mode)
335                         clk_disable(pll2_400);
336
337                 /* AXI_CLK is sourced from PLL3_PFD_540 on MX6DL */
338                 if (cpu_is_mx6dl() &&
339                         clk_get_parent(axi_clk) != pll3_540)
340                         clk_set_parent(axi_clk, pll3_540);
341
342                 low_bus_freq_mode = 0;
343                 audio_bus_freq_mode = 0;
344
345                 clk_disable(pll3);
346         }
347         return 0;
348 }
349
350 int low_freq_bus_used(void)
351 {
352         if (!bus_freq_scaling_initialized)
353                 return 0;
354
355         /* We only go the lowest setpoint if ARM is also
356          * at the lowest setpoint.
357          */
358         if (high_cpu_freq)
359                 return 0;
360
361         if ((lp_high_freq == 0)
362             && (lp_med_freq == 0))
363                 return 1;
364         else
365                 return 0;
366 }
367
368 void bus_freq_update(struct clk *clk, bool flag)
369 {
370         mutex_lock(&bus_freq_mutex);
371
372         if (flag) {
373                 if (clk == cpu_clk) {
374                         /* The CPU freq is being increased.
375                           * check if we need to increase the bus freq
376                           */
377                         high_cpu_freq = 1;
378                         if (low_bus_freq_mode || audio_bus_freq_mode)
379                                 set_high_bus_freq(0);
380                 } else {
381                         /* Update count */
382                         if (clk->flags & AHB_HIGH_SET_POINT)
383                                 lp_high_freq++;
384                         else if (clk->flags & AHB_MED_SET_POINT)
385                                 lp_med_freq++;
386                         else if (clk->flags & AHB_AUDIO_SET_POINT)
387                                 lp_audio_freq++;
388                         /* Update bus freq */
389                         if ((clk->flags & CPU_FREQ_TRIG_UPDATE)
390                                 && (clk_get_usecount(clk) == 0)) {
391                                 if (!(clk->flags &
392                                         (AHB_HIGH_SET_POINT | AHB_MED_SET_POINT))) {
393                                         if (low_freq_bus_used()) {
394                                                 if ((clk->flags & AHB_AUDIO_SET_POINT) &
395                                                                 !audio_bus_freq_mode)
396                                                         set_low_bus_freq();
397                                                 else if (!low_bus_freq_mode)
398                                                         set_low_bus_freq();
399                                         }
400                                 } else {
401                                         if ((clk->flags & AHB_MED_SET_POINT)
402                                                 && !med_bus_freq_mode) {
403                                                 /* Set to Medium setpoint */
404                                                 set_high_bus_freq(0);
405                                         } else if ((clk->flags & AHB_HIGH_SET_POINT)
406                                                 && !high_bus_freq_mode) {
407                                                 /* Currently at low or medium
408                                                   * set point, need to set to
409                                                   * high setpoint
410                                                   */
411                                                 set_high_bus_freq(1);
412                                         }
413                                 }
414                         }
415                 }
416         } else {
417                 if (clk == cpu_clk) {
418                         /* CPU freq is dropped, check if we can
419                           * lower the bus freq.
420                           */
421                         high_cpu_freq = 0;
422
423                         if (low_freq_bus_used() &&
424                                 !(low_bus_freq_mode || audio_bus_freq_mode))
425                                 set_low_bus_freq();
426                 } else {
427                         /* Update count */
428                         if (clk->flags & AHB_HIGH_SET_POINT)
429                                 lp_high_freq--;
430                         else if (clk->flags & AHB_MED_SET_POINT)
431                                 lp_med_freq--;
432                         else if (clk->flags & AHB_AUDIO_SET_POINT)
433                                 lp_audio_freq--;
434                         /* Update bus freq */
435                         if ((clk->flags & CPU_FREQ_TRIG_UPDATE)
436                                 && (clk_get_usecount(clk) == 0)) {
437                                 if (low_freq_bus_used())
438                                         set_low_bus_freq();
439                                 else {
440                                         /* Set to either high or
441                                           * medium setpoint.
442                                           */
443                                         set_high_bus_freq(0);
444                                 }
445                         }
446                 }
447         }
448         mutex_unlock(&bus_freq_mutex);
449         return;
450 }
451 void setup_pll(void)
452 {
453 }
454
455 static ssize_t bus_freq_scaling_enable_show(struct device *dev,
456                                 struct device_attribute *attr, char *buf)
457 {
458         if (bus_freq_scaling_is_active)
459                 return sprintf(buf, "Bus frequency scaling is enabled\n");
460         else
461                 return sprintf(buf, "Bus frequency scaling is disabled\n");
462 }
463
464 static ssize_t bus_freq_scaling_enable_store(struct device *dev,
465                                  struct device_attribute *attr,
466                                  const char *buf, size_t size)
467 {
468         if (strncmp(buf, "1", 1) == 0) {
469 #ifdef CONFIG_MX6_VPU_352M
470                 if (cpu_is_mx6q())
471                         /*do not enable bus freq*/
472                         bus_freq_scaling_is_active = 0;
473                 printk(KERN_WARNING "Bus frequency can't be enabled if using VPU 352M!\n");
474                 return size;
475 #else
476                 bus_freq_scaling_is_active = 1;
477 #endif
478                 set_high_bus_freq(0);
479                 /* Make sure system can enter low bus mode if it should be in
480                 low bus mode */
481                 if (low_freq_bus_used() && !low_bus_freq_mode)
482                         set_low_bus_freq();
483         } else if (strncmp(buf, "0", 1) == 0) {
484                 if (bus_freq_scaling_is_active)
485                         set_high_bus_freq(1);
486                 bus_freq_scaling_is_active = 0;
487         }
488         return size;
489 }
490
491 static int busfreq_suspend(struct platform_device *pdev, pm_message_t message)
492 {
493         return 0;
494 }
495
496 static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event,
497         void *dummy)
498 {
499         if (event == PM_SUSPEND_PREPARE) {
500                 set_high_bus_freq(1);
501                 busfreq_suspended = 1;
502         } else if (event == PM_POST_SUSPEND) {
503                 busfreq_suspended = 0;
504         }
505
506         return NOTIFY_OK;
507 }
508 static int busfreq_resume(struct platform_device *pdev)
509 {
510         return  0;
511 }
512 static struct notifier_block imx_bus_freq_pm_notifier = {
513         .notifier_call = bus_freq_pm_notify,
514 };
515
516 static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show,
517                         bus_freq_scaling_enable_store);
518
519 /*!
520  * This is the probe routine for the bus frequency driver.
521  *
522  * @param   pdev   The platform device structure
523  *
524  * @return         The function returns 0 on success
525  *
526  */
527
528 static int __devinit busfreq_probe(struct platform_device *pdev)
529 {
530         u32 err;
531
532         busfreq_dev = &pdev->dev;
533
534         pll2_400 = clk_get(NULL, "pll2_pfd_400M");
535         if (IS_ERR(pll2_400)) {
536                 printk(KERN_DEBUG "%s: failed to get pll2_pfd_400M\n",
537                        __func__);
538                 return PTR_ERR(pll2_400);
539         }
540
541         pll2_200 = clk_get(NULL, "pll2_200M");
542         if (IS_ERR(pll2_200)) {
543                 printk(KERN_DEBUG "%s: failed to get pll2_200M\n",
544                        __func__);
545                 return PTR_ERR(pll2_200);
546         }
547
548         pll2 = clk_get(NULL, "pll2");
549         if (IS_ERR(pll2)) {
550                 printk(KERN_DEBUG "%s: failed to get pll2\n",
551                        __func__);
552                 return PTR_ERR(pll2);
553         }
554
555         pll1 = clk_get(NULL, "pll1_main_clk");
556         if (IS_ERR(pll1)) {
557                 printk(KERN_DEBUG "%s: failed to get pll1\n",
558                        __func__);
559                 return PTR_ERR(pll1);
560         }
561
562         pll1_sw_clk = clk_get(NULL, "pll1_sw_clk");
563         if (IS_ERR(pll1_sw_clk)) {
564                 printk(KERN_DEBUG "%s: failed to get pll1_sw_clk\n",
565                        __func__);
566                 return PTR_ERR(pll1_sw_clk);
567         }
568
569
570         if (IS_ERR(pll2)) {
571                 printk(KERN_DEBUG "%s: failed to get pll2\n",
572                        __func__);
573                 return PTR_ERR(pll2);
574         }
575
576
577         cpu_clk = clk_get(NULL, "cpu_clk");
578         if (IS_ERR(cpu_clk)) {
579                 printk(KERN_DEBUG "%s: failed to get cpu_clk\n",
580                        __func__);
581                 return PTR_ERR(cpu_clk);
582         }
583
584         pll3 = clk_get(NULL, "pll3_main_clk");
585         if (IS_ERR(pll3)) {
586                 printk(KERN_DEBUG "%s: failed to get pll3\n",
587                        __func__);
588                 return PTR_ERR(pll3);
589         }
590
591         pll3_540 = clk_get(NULL, "pll3_pfd_540M");
592         if (IS_ERR(pll3_540)) {
593                 printk(KERN_DEBUG "%s: failed to get periph_clk\n",
594                        __func__);
595                 return PTR_ERR(pll3_540);
596         }
597
598         pll3_sw_clk = clk_get(NULL, "pll3_sw_clk");
599         if (IS_ERR(pll3_sw_clk)) {
600                 printk(KERN_DEBUG "%s: failed to get pll3_sw_clk\n",
601                        __func__);
602                 return PTR_ERR(pll3_sw_clk);
603         }
604
605         axi_clk = clk_get(NULL, "axi_clk");
606         if (IS_ERR(axi_clk)) {
607                 printk(KERN_DEBUG "%s: failed to get axi_clk\n",
608                        __func__);
609                 return PTR_ERR(axi_clk);
610         }
611
612         ahb_clk = clk_get(NULL, "ahb");
613         if (IS_ERR(ahb_clk)) {
614                 printk(KERN_DEBUG "%s: failed to get ahb_clk\n",
615                        __func__);
616                 return PTR_ERR(ahb_clk);
617         }
618
619         periph_clk = clk_get(NULL, "periph_clk");
620         if (IS_ERR(periph_clk)) {
621                 printk(KERN_DEBUG "%s: failed to get periph_clk\n",
622                        __func__);
623                 return PTR_ERR(periph_clk);
624         }
625
626         osc_clk = clk_get(NULL, "osc");
627         if (IS_ERR(osc_clk)) {
628                 printk(KERN_DEBUG "%s: failed to get osc_clk\n",
629                        __func__);
630                 return PTR_ERR(osc_clk);
631         }
632
633         mmdc_ch0_axi = clk_get(NULL, "mmdc_ch0_axi");
634         if (IS_ERR(mmdc_ch0_axi)) {
635                 printk(KERN_DEBUG "%s: failed to get mmdc_ch0_axi\n",
636                        __func__);
637                 return PTR_ERR(mmdc_ch0_axi);
638         }
639
640         err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
641         if (err) {
642                 printk(KERN_ERR
643                        "Unable to register sysdev entry for BUSFREQ");
644                 return err;
645         }
646
647         cpu_op_tbl = get_cpu_op(&cpu_op_nr);
648         low_bus_freq_mode = 0;
649         if (cpu_is_mx6dl()) {
650                 high_bus_freq_mode = 0;
651                 med_bus_freq_mode = 1;
652                 /* To make pll2_400 use count right, as when
653                 system enter 24M, it will disable pll2_400 */
654                 clk_enable(pll2_400);
655         } else if (cpu_is_mx6sl()) {
656                 /* Set med_bus_freq_mode to 1 since med_bus_freq_mode
657                 is not supported as yet for MX6SL */
658                 high_bus_freq_mode = 1;
659                 med_bus_freq_mode = 1;
660         } else {
661                 high_bus_freq_mode = 1;
662                 med_bus_freq_mode = 0;
663         }
664         bus_freq_scaling_is_active = 0;
665         bus_freq_scaling_initialized = 1;
666
667         if (cpu_is_mx6q()) {
668                 ddr_low_rate = LPAPM_CLK;
669                 ddr_med_rate = DDR_MED_CLK;
670                 ddr_normal_rate = DDR3_NORMAL_CLK;
671         }
672         if (cpu_is_mx6dl() || cpu_is_mx6sl()) {
673                 ddr_low_rate = LPAPM_CLK;
674                 ddr_normal_rate = ddr_med_rate = DDR_MED_CLK;
675         }
676
677         INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler);
678         register_pm_notifier(&imx_bus_freq_pm_notifier);
679
680         if (!cpu_is_mx6sl())
681                 init_mmdc_settings();
682         else {
683                 unsigned long iram_paddr;
684
685                 /* Allocate IRAM for WFI code when system is
686                   * in low freq mode.
687                   */
688                 iram_alloc(SZ_4K, &iram_paddr);
689                 /* Need to remap the area here since we want
690                    * the memory region to be executable.
691                    */
692                 mx6sl_wfi_iram_base = __arm_ioremap(iram_paddr,
693                                                 SZ_4K, MT_MEMORY_NONCACHED);
694                 memcpy(mx6sl_wfi_iram_base, mx6sl_wait, SZ_4K);
695                 mx6sl_wfi_iram = (void *)mx6sl_wfi_iram_base;
696
697                 /* Allocate IRAM for WFI code when system is
698                   *in low freq mode.
699                   */
700                 iram_alloc(SZ_4K, &iram_paddr);
701                 /* Need to remap the area here since we want the memory region
702                          to be executable. */
703                 mx6sl_ddr_freq_base = __arm_ioremap(iram_paddr,
704                                         SZ_4K, MT_MEMORY_NONCACHED);
705                 memcpy(mx6sl_ddr_freq_base, mx6sl_ddr_iram, SZ_4K);
706                 mx6sl_ddr_freq_change_iram = (void *)mx6sl_ddr_freq_base;
707
708         }
709
710         return 0;
711 }
712
713 static struct platform_driver busfreq_driver = {
714         .driver = {
715                    .name = "imx_busfreq",
716                 },
717         .probe = busfreq_probe,
718         .suspend = busfreq_suspend,
719         .resume = busfreq_resume,
720 };
721
722 /*!
723  * Initialise the busfreq_driver.
724  *
725  * @return  The function always returns 0.
726  */
727
728 static int __init busfreq_init(void)
729 {
730         if (platform_driver_register(&busfreq_driver) != 0) {
731                 printk(KERN_ERR "busfreq_driver register failed\n");
732                 return -ENODEV;
733         }
734
735         printk(KERN_INFO "Bus freq driver module loaded\n");
736
737 #ifdef CONFIG_MX6_VPU_352M
738         if (cpu_is_mx6q())
739                 bus_freq_scaling_is_active = 0;/*disable bus_freq*/
740
741 #else
742         /* Enable busfreq by default. */
743         bus_freq_scaling_is_active = 1;
744 #endif
745         if (cpu_is_mx6q())
746                 set_high_bus_freq(1);
747         else if (cpu_is_mx6dl())
748                 set_high_bus_freq(0);
749
750         printk(KERN_INFO "Bus freq driver Enabled\n");
751         return 0;
752 }
753
754 static void __exit busfreq_cleanup(void)
755 {
756         sysfs_remove_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
757
758         /* Unregister the device structure */
759         platform_driver_unregister(&busfreq_driver);
760         bus_freq_scaling_initialized = 0;
761 }
762
763 late_initcall(busfreq_init);
764 module_exit(busfreq_cleanup);
765
766 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
767 MODULE_DESCRIPTION("BusFreq driver");
768 MODULE_LICENSE("GPL");