aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRanjani Vaidyanathan <ra5478@freescale.com>2013-09-17 18:09:48 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:05:40 -0400
commit604e3e1076cd5c6c1802672198bb2a6a9e2608cb (patch)
tree6acc026de4f74c78c744a36c4e911e0c30079348
parentfa8c9f5067418ea20dca46a3f32b01e53b9878fd (diff)
ENGR00280101-1 [iMX6SL] Add busfreq support
Add support to scale the DDR frequency between 400MHz and 24MHz. Add support to scale AHB between 132MHz and 24MHz. Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
-rw-r--r--arch/arm/mach-imx/Makefile1
-rw-r--r--arch/arm/mach-imx/busfreq-imx6.c453
-rw-r--r--arch/arm/mach-imx/busfreq_ddr3.c40
-rw-r--r--arch/arm/mach-imx/busfreq_lpddr2.c172
-rw-r--r--arch/arm/mach-imx/clk-imx6sl.c63
-rw-r--r--arch/arm/mach-imx/lpddr2_freq_imx6.S483
-rw-r--r--include/dt-bindings/clock/imx6sl-clock.h4
7 files changed, 1073 insertions, 143 deletions
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 9b80b2328785..50887de73cde 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -108,6 +108,7 @@ obj-$(CONFIG_PM) += pm-imx6.o headsmp.o suspend-imx6.o
108ifeq ($(CONFIG_ARM_IMX6_CPUFREQ),y) 108ifeq ($(CONFIG_ARM_IMX6_CPUFREQ),y)
109obj-y += busfreq-imx6.o 109obj-y += busfreq-imx6.o
110obj-$(CONFIG_SOC_IMX6Q) += ddr3_freq_imx6.o busfreq_ddr3.o 110obj-$(CONFIG_SOC_IMX6Q) += ddr3_freq_imx6.o busfreq_ddr3.o
111obj-$(CONFIG_SOC_IMX6SL) += lpddr2_freq_imx6.o busfreq_lpddr2.o
111endif 112endif
112 113
113 114
diff --git a/arch/arm/mach-imx/busfreq-imx6.c b/arch/arm/mach-imx/busfreq-imx6.c
index c7a7cce30315..53f4ebff52c4 100644
--- a/arch/arm/mach-imx/busfreq-imx6.c
+++ b/arch/arm/mach-imx/busfreq-imx6.c
@@ -41,33 +41,37 @@
41#include <linux/of.h> 41#include <linux/of.h>
42#include <linux/platform_device.h> 42#include <linux/platform_device.h>
43#include <linux/proc_fs.h> 43#include <linux/proc_fs.h>
44#include <linux/reboot.h>
44#include <linux/regulator/consumer.h> 45#include <linux/regulator/consumer.h>
45#include <linux/sched.h> 46#include <linux/sched.h>
46#include <linux/suspend.h> 47#include <linux/suspend.h>
47#include "hardware.h" 48#include "hardware.h"
48 49
49#define LPAPM_CLK 24000000 50#define LPAPM_CLK 24000000
50#define DDR_AUDIO_CLK 50000000 51#define DDR_AUDIO_CLK 100000000
51 52
52int high_bus_freq_mode; 53int high_bus_freq_mode;
53int med_bus_freq_mode; 54int med_bus_freq_mode;
54int audio_bus_freq_mode; 55int audio_bus_freq_mode;
55int low_bus_freq_mode; 56int low_bus_freq_mode;
57unsigned int ddr_med_rate;
58unsigned int ddr_normal_rate;
56 59
57static int bus_freq_scaling_initialized; 60static int bus_freq_scaling_initialized;
58static struct device *busfreq_dev; 61static struct device *busfreq_dev;
59static int busfreq_suspended; 62static int busfreq_suspended;
60 63static u32 org_arm_rate;
61static int bus_freq_scaling_is_active; 64static int bus_freq_scaling_is_active;
62static int high_bus_count, med_bus_count, audio_bus_count; 65static int high_bus_count, med_bus_count, audio_bus_count;
63static unsigned int ddr_low_rate; 66static unsigned int ddr_low_rate;
64unsigned int ddr_med_rate;
65unsigned int ddr_normal_rate;
66 67
67extern int init_mmdc_settings(struct platform_device *dev); 68extern int init_mmdc_lpddr2_settings(struct platform_device *dev);
69extern int init_mmdc_ddr3_settings(struct platform_device *dev);
68extern int update_ddr_freq(int ddr_rate); 70extern int update_ddr_freq(int ddr_rate);
71extern int update_lpddr2_freq(int ddr_rate);
69 72
70DEFINE_MUTEX(bus_freq_mutex); 73DEFINE_MUTEX(bus_freq_mutex);
74static DEFINE_SPINLOCK(freq_lock);
71 75
72static struct clk *pll2_400; 76static struct clk *pll2_400;
73static struct clk *periph_clk; 77static struct clk *periph_clk;
@@ -79,55 +83,181 @@ static struct clk *cpu_clk;
79static struct clk *pll3; 83static struct clk *pll3;
80static struct clk *pll2; 84static struct clk *pll2;
81static struct clk *pll2_200; 85static struct clk *pll2_200;
82 86static struct clk *pll1_sys;
87static struct clk *periph2_clk;
88static struct clk *ocram_clk;
89static struct clk *ahb_clk;
90static struct clk *pll1_sw_clk;
91static struct clk *periph2_pre_clk;
92static struct clk *periph2_clk2_sel;
93static struct clk *periph2_clk2;
94
95static u32 pll2_org_rate;
83static struct delayed_work low_bus_freq_handler; 96static struct delayed_work low_bus_freq_handler;
84static struct delayed_work bus_freq_daemon; 97static struct delayed_work bus_freq_daemon;
85 98
86int low_bus_freq; 99static void enter_lpm_imx6sl(void)
87
88int reduce_bus_freq(void)
89{ 100{
90 int ret = 0; 101 unsigned long flags;
91 clk_prepare_enable(pll3); 102
92 if (low_bus_freq) { 103 if (high_bus_freq_mode) {
93 /* Need to ensure that PLL2_PFD_400M is kept ON. */ 104 pll2_org_rate = clk_get_rate(pll2);
94 clk_prepare_enable(pll2_400); 105 /* Set periph_clk to be sourced from OSC_CLK */
95 update_ddr_freq(DDR_AUDIO_CLK); 106 clk_set_parent(periph_clk2_sel, osc_clk);
96 /* Make sure periph clk's parent also got updated */ 107 clk_set_parent(periph_clk, periph_clk2);
97 ret = clk_set_parent(periph_clk2_sel, pll3); 108 /* Ensure AHB/AXI clks are at 24MHz. */
98 if (ret) 109 clk_set_rate(ahb_clk, LPAPM_CLK);
99 dev_WARN(busfreq_dev, "%s: %d: clk set parent fail!\n", 110 clk_set_rate(ocram_clk, LPAPM_CLK);
100 __func__, __LINE__); 111 }
101 ret = clk_set_parent(periph_pre_clk, pll2_200); 112 if (audio_bus_count) {
102 if (ret) 113 /* Set up DDR to 100MHz. */
103 dev_WARN(busfreq_dev, "%s: %d: clk set parent fail!\n", 114 spin_lock_irqsave(&freq_lock, flags);
104 __func__, __LINE__); 115 update_lpddr2_freq(DDR_AUDIO_CLK);
105 ret = clk_set_parent(periph_clk, periph_pre_clk); 116 spin_unlock_irqrestore(&freq_lock, flags);
106 if (ret) 117
107 dev_WARN(busfreq_dev, "%s: %d: clk set parent fail!\n", 118 /* Fix the clock tree in kernel */
108 __func__, __LINE__); 119 clk_set_rate(pll2, pll2_org_rate);
109 audio_bus_freq_mode = 1; 120 clk_set_parent(periph2_pre_clk, pll2_200);
121 clk_set_parent(periph2_clk, periph2_pre_clk);
122
123 if (low_bus_freq_mode) {
124 /*
125 * Swtich ARM to run off PLL2_PFD2_400MHz
126 * since DDR is anyway at 100MHz.
127 */
128 clk_set_parent(pll1_sw_clk, pll2_400);
129 /*
130 * Ensure that the clock will be
131 * at original speed.
132 */
133 clk_set_rate(cpu_clk, org_arm_rate);
134 }
110 low_bus_freq_mode = 0; 135 low_bus_freq_mode = 0;
136 audio_bus_freq_mode = 1;
111 } else { 137 } else {
112 update_ddr_freq(LPAPM_CLK); 138 u32 arm_div, pll1_rate;
113 /* Make sure periph clk's parent also got updated */ 139 org_arm_rate = clk_get_rate(cpu_clk);
114 ret = clk_set_parent(periph_clk2_sel, osc_clk); 140 /*
115 if (ret) 141 * Set DDR to 24MHz.
116 dev_WARN(busfreq_dev, "%s: %d: clk set parent fail!\n", 142 * Since we are going to bypass PLL2, we need
117 __func__, __LINE__); 143 * to move ARM clk off PLL2_PFD2 to PLL1.
118 ret = clk_set_parent(periph_clk, periph_clk2); 144 * Make sure the PLL1 is running at the lowest possible freq.
119 if (ret) 145 */
120 dev_WARN(busfreq_dev, "%s: %d: clk set parent fail!\n", 146 clk_set_rate(pll1_sys, clk_round_rate(pll1_sys, org_arm_rate));
121 __func__, __LINE__); 147 pll1_rate = clk_get_rate(pll1_sys);
122 if (audio_bus_freq_mode) 148 arm_div = pll1_rate / org_arm_rate + 1;
123 clk_disable_unprepare(pll2_400); 149 /* Ensure ARM CLK is lower before changing the parent. */
150 clk_set_rate(cpu_clk, org_arm_rate / arm_div);
151 /* Now set the ARM clk parent to PLL1_SYS. */
152 clk_set_parent(pll1_sw_clk, pll1_sys);
153
154 /* Now set DDR to 24MHz. */
155 spin_lock_irqsave(&freq_lock, flags);
156 update_lpddr2_freq(LPAPM_CLK);
157 spin_unlock_irqrestore(&freq_lock, flags);
158
159 /*
160 * Fix the clock tree in kernel.
161 * Make sure PLL2 rate is updated as it gets
162 * bypassed in the DDR freq change code.
163 */
164 clk_set_rate(pll2, LPAPM_CLK);
165 clk_set_parent(periph2_clk2_sel, pll2);
166 clk_set_parent(periph2_clk, periph2_clk2_sel);
167
124 low_bus_freq_mode = 1; 168 low_bus_freq_mode = 1;
125 audio_bus_freq_mode = 0; 169 audio_bus_freq_mode = 0;
126 } 170 }
127 if (high_bus_freq_mode && cpu_is_imx6dl()) 171}
128 clk_disable_unprepare(pll2_400); 172
173static void exit_lpm_imx6sl(void)
174{
175 unsigned long flags;
176 spin_lock_irqsave(&freq_lock, flags);
177 /* Change DDR freq in IRAM. */
178 update_lpddr2_freq(ddr_normal_rate);
179 spin_unlock_irqrestore(&freq_lock, flags);
129 180
181 /*
182 * Fix the clock tree in kernel.
183 * Make sure PLL2 rate is updated as it gets
184 * un-bypassed in the DDR freq change code.
185 */
186 clk_set_rate(pll2, pll2_org_rate);
187 clk_set_parent(periph2_pre_clk, pll2_400);
188 clk_set_parent(periph2_clk, periph2_pre_clk);
189
190 /* Ensure that periph_clk is sourced from PLL2_400. */
191 clk_set_parent(periph_pre_clk, pll2_400);
192 /*
193 * Before switching the perhiph_clk, ensure that the
194 * AHB/AXI will not be too fast.
195 */
196 clk_set_rate(ahb_clk, LPAPM_CLK / 3);
197 clk_set_rate(ocram_clk, LPAPM_CLK / 2);
198 clk_set_parent(periph_clk, periph_pre_clk);
199
200 if (low_bus_freq_mode) {
201 /* Move ARM from PLL1_SW_CLK to PLL2_400. */
202 clk_set_parent(pll1_sw_clk, pll2_400);
203 clk_set_rate(cpu_clk, org_arm_rate);
204 }
205}
206
207int reduce_bus_freq(void)
208{
209 int ret = 0;
210 clk_prepare_enable(pll3);
211 if (cpu_is_imx6sl())
212 enter_lpm_imx6sl();
213 else {
214 if (audio_bus_count) {
215 /* Need to ensure that PLL2_PFD_400M is kept ON. */
216 clk_prepare_enable(pll2_400);
217 update_ddr_freq(DDR_AUDIO_CLK);
218 /* Make sure periph clk's parent also got updated */
219 ret = clk_set_parent(periph_clk2_sel, pll3);
220 if (ret)
221 dev_WARN(busfreq_dev,
222 "%s: %d: clk set parent fail!\n",
223 __func__, __LINE__);
224 ret = clk_set_parent(periph_pre_clk, pll2_200);
225 if (ret)
226 dev_WARN(busfreq_dev,
227 "%s: %d: clk set parent fail!\n",
228 __func__, __LINE__);
229 ret = clk_set_parent(periph_clk, periph_pre_clk);
230 if (ret)
231 dev_WARN(busfreq_dev,
232 "%s: %d: clk set parent fail!\n",
233 __func__, __LINE__);
234 audio_bus_freq_mode = 1;
235 low_bus_freq_mode = 0;
236 } else {
237 update_ddr_freq(LPAPM_CLK);
238 /* Make sure periph clk's parent also got updated */
239 ret = clk_set_parent(periph_clk2_sel, osc_clk);
240 if (ret)
241 dev_WARN(busfreq_dev,
242 "%s: %d: clk set parent fail!\n",
243 __func__, __LINE__);
244 /* Set periph_clk parent to OSC via periph_clk2_sel */
245 ret = clk_set_parent(periph_clk, periph_clk2);
246 if (ret)
247 dev_WARN(busfreq_dev,
248 "%s: %d: clk set parent fail!\n",
249 __func__, __LINE__);
250 if (audio_bus_freq_mode)
251 clk_disable_unprepare(pll2_400);
252 low_bus_freq_mode = 1;
253 audio_bus_freq_mode = 0;
254 }
255 if (high_bus_freq_mode && cpu_is_imx6dl())
256 clk_disable_unprepare(pll2_400);
257
258 }
130 clk_disable_unprepare(pll3); 259 clk_disable_unprepare(pll3);
260
131 med_bus_freq_mode = 0; 261 med_bus_freq_mode = 0;
132 high_bus_freq_mode = 0; 262 high_bus_freq_mode = 0;
133 263
@@ -153,10 +283,10 @@ static void reduce_bus_freq_handler(struct work_struct *work)
153} 283}
154 284
155/* 285/*
156 * Set the DDR, AHB to 24MHz. 286 * Set the DDR, AHB to 24MHz.
157 * This mode will be activated only when none of the modules that 287 * This mode will be activated only when none of the modules that
158 * need a higher DDR or AHB frequency are active. 288 * need a higher DDR or AHB frequency are active.
159 */ 289 */
160int set_low_bus_freq(int low_bus_mode) 290int set_low_bus_freq(int low_bus_mode)
161{ 291{
162 if (busfreq_suspended) 292 if (busfreq_suspended)
@@ -166,23 +296,31 @@ int set_low_bus_freq(int low_bus_mode)
166 return 0; 296 return 0;
167 297
168 /* 298 /*
169 * Don't lower the frequency immediately. Instead 299 * Check to see if we need to got from
170 * scheduled a delayed work and drop the freq if 300 * low bus freq mode to audio bus freq mode.
171 * the conditions still remain the same. 301 * If so, the change needs to be done immediately.
172 */ 302 */
173 low_bus_freq = low_bus_mode; 303 if (audio_bus_count && low_bus_freq_mode)
174 schedule_delayed_work(&low_bus_freq_handler, 304 reduce_bus_freq();
175 usecs_to_jiffies(3000000)); 305 else
306 /*
307 * Don't lower the frequency immediately. Instead
308 * scheduled a delayed work and drop the freq if
309 * the conditions still remain the same.
310 */
311 schedule_delayed_work(&low_bus_freq_handler,
312 usecs_to_jiffies(3000000));
176 return 0; 313 return 0;
177} 314}
178 315
179/* 316/*
180 * Set the DDR to either 528MHz or 400MHz for iMX6qd 317 * Set the DDR to either 528MHz or 400MHz for iMX6qd
181 * or 400MHz for iMX6dl. 318 * or 400MHz for iMX6dl.
182 */ 319 */
183int set_high_bus_freq(int high_bus_freq) 320int set_high_bus_freq(int high_bus_freq)
184{ 321{
185 int ret = 0; 322 int ret = 0;
323 struct clk *periph_clk_parent;
186 324
187 if (bus_freq_scaling_initialized && bus_freq_scaling_is_active) 325 if (bus_freq_scaling_initialized && bus_freq_scaling_is_active)
188 cancel_delayed_work_sync(&low_bus_freq_handler); 326 cancel_delayed_work_sync(&low_bus_freq_handler);
@@ -190,11 +328,10 @@ int set_high_bus_freq(int high_bus_freq)
190 if (busfreq_suspended) 328 if (busfreq_suspended)
191 return 0; 329 return 0;
192 330
193 /* for high setpoint, i.MX6Q is 528MHz, i.MX6DL is 400MHz */
194 if (cpu_is_imx6q()) 331 if (cpu_is_imx6q())
195 high_bus_freq = 1; 332 periph_clk_parent = pll2;
196 else 333 else
197 high_bus_freq = 0; 334 periph_clk_parent = pll2_400;
198 335
199 if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active) 336 if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
200 return 0; 337 return 0;
@@ -207,42 +344,49 @@ int set_high_bus_freq(int high_bus_freq)
207 return 0; 344 return 0;
208 345
209 clk_prepare_enable(pll3); 346 clk_prepare_enable(pll3);
210 if (high_bus_freq) { 347 if (cpu_is_imx6sl())
211 update_ddr_freq(ddr_normal_rate); 348 exit_lpm_imx6sl();
212 /* Make sure periph clk's parent also got updated */ 349 else {
213 ret = clk_set_parent(periph_clk2_sel, pll3); 350 if (high_bus_freq) {
214 if (ret) 351 update_ddr_freq(ddr_normal_rate);
215 dev_WARN(busfreq_dev, "%s: %d: clk set parent fail!\n", 352 /* Make sure periph clk's parent also got updated */
216 __func__, __LINE__); 353 ret = clk_set_parent(periph_clk2_sel, pll3);
217 ret = clk_set_parent(periph_pre_clk, pll2); 354 if (ret)
218 if (ret) 355 dev_WARN(busfreq_dev,
219 dev_WARN(busfreq_dev, "%s: %d: clk set parent fail!\n", 356 "%s: %d: clk set parent fail!\n",
220 __func__, __LINE__); 357 __func__, __LINE__);
221 ret = clk_set_parent(periph_clk, periph_pre_clk); 358 ret = clk_set_parent(periph_pre_clk, periph_clk_parent);
222 if (ret) 359 if (ret)
223 dev_WARN(busfreq_dev, "%s: %d: clk set parent fail!\n", 360 dev_WARN(busfreq_dev,
224 __func__, __LINE__); 361 "%s: %d: clk set parent fail!\n",
225 if (med_bus_freq_mode) 362 __func__, __LINE__);
363 ret = clk_set_parent(periph_clk, periph_pre_clk);
364 if (ret)
365 dev_WARN(busfreq_dev,
366 "%s: %d: clk set parent fail!\n",
367 __func__, __LINE__);
368 } else {
369 update_ddr_freq(ddr_med_rate);
370 /* Make sure periph clk's parent also got updated */
371 ret = clk_set_parent(periph_clk2_sel, pll3);
372 if (ret)
373 dev_WARN(busfreq_dev,
374 "%s: %d: clk set parent fail!\n",
375 __func__, __LINE__);
376 ret = clk_set_parent(periph_pre_clk, pll2_400);
377 if (ret)
378 dev_WARN(busfreq_dev,
379 "%s: %d: clk set parent fail!\n",
380 __func__, __LINE__);
381 ret = clk_set_parent(periph_clk, periph_pre_clk);
382 if (ret)
383 dev_WARN(busfreq_dev,
384 "%s: %d: clk set parent fail!\n",
385 __func__, __LINE__);
386 }
387 if (audio_bus_freq_mode)
226 clk_disable_unprepare(pll2_400); 388 clk_disable_unprepare(pll2_400);
227 } else {
228 clk_prepare_enable(pll2_400);
229 update_ddr_freq(ddr_med_rate);
230 /* Make sure periph clk's parent also got updated */
231 ret = clk_set_parent(periph_clk2_sel, pll3);
232 if (ret)
233 dev_WARN(busfreq_dev, "%s: %d: clk set parent fail!\n",
234 __func__, __LINE__);
235 ret = clk_set_parent(periph_pre_clk, pll2_400);
236 if (ret)
237 dev_WARN(busfreq_dev, "%s: %d: clk set parent fail!\n",
238 __func__, __LINE__);
239 ret = clk_set_parent(periph_clk, periph_pre_clk);
240 if (ret)
241 dev_WARN(busfreq_dev, "%s: %d: clk set parent fail!\n",
242 __func__, __LINE__);
243 } 389 }
244 if (audio_bus_freq_mode)
245 clk_disable_unprepare(pll2_400);
246 390
247 high_bus_freq_mode = 1; 391 high_bus_freq_mode = 1;
248 med_bus_freq_mode = 0; 392 med_bus_freq_mode = 0;
@@ -281,6 +425,15 @@ void request_bus_freq(enum bus_freq_mode mode)
281 } 425 }
282 426
283 cancel_delayed_work_sync(&low_bus_freq_handler); 427 cancel_delayed_work_sync(&low_bus_freq_handler);
428
429 if (cpu_is_imx6dl()) {
430 /* No support for medium setpoint on MX6DL. */
431 if (mode == BUS_FREQ_MED) {
432 high_bus_count++;
433 mode = BUS_FREQ_HIGH;
434 }
435 }
436
284 if ((mode == BUS_FREQ_HIGH) && (!high_bus_freq_mode)) { 437 if ((mode == BUS_FREQ_HIGH) && (!high_bus_freq_mode)) {
285 set_high_bus_freq(1); 438 set_high_bus_freq(1);
286 mutex_unlock(&bus_freq_mutex); 439 mutex_unlock(&bus_freq_mutex);
@@ -340,6 +493,14 @@ void release_bus_freq(enum bus_freq_mode mode)
340 return; 493 return;
341 } 494 }
342 495
496 if (cpu_is_imx6dl()) {
497 /* No support for medium setpoint on MX6DL. */
498 if (mode == BUS_FREQ_MED) {
499 high_bus_count--;
500 mode = BUS_FREQ_HIGH;
501 }
502 }
503
343 if ((!audio_bus_freq_mode) && (high_bus_count == 0) && 504 if ((!audio_bus_freq_mode) && (high_bus_count == 0) &&
344 (med_bus_count == 0) && (audio_bus_count != 0)) { 505 (med_bus_count == 0) && (audio_bus_count != 0)) {
345 set_low_bus_freq(1); 506 set_low_bus_freq(1);
@@ -417,10 +578,24 @@ static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event,
417 return NOTIFY_OK; 578 return NOTIFY_OK;
418} 579}
419 580
581static int busfreq_reboot_notifier_event(struct notifier_block *this,
582 unsigned long event, void *ptr)
583{
584 /* System is rebooting. Set the system into high_bus_freq_mode. */
585 request_bus_freq(BUS_FREQ_HIGH);
586
587 return 0;
588}
589
420static struct notifier_block imx_bus_freq_pm_notifier = { 590static struct notifier_block imx_bus_freq_pm_notifier = {
421 .notifier_call = bus_freq_pm_notify, 591 .notifier_call = bus_freq_pm_notify,
422}; 592};
423 593
594static struct notifier_block imx_busfreq_reboot_notifier = {
595 .notifier_call = busfreq_reboot_notifier_event,
596};
597
598
424static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show, 599static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show,
425 bus_freq_scaling_enable_store); 600 bus_freq_scaling_enable_store);
426 601
@@ -442,73 +617,135 @@ static int busfreq_probe(struct platform_device *pdev)
442 pll2_400 = devm_clk_get(&pdev->dev, "pll2_pfd2_396m"); 617 pll2_400 = devm_clk_get(&pdev->dev, "pll2_pfd2_396m");
443 if (IS_ERR(pll2_400)) { 618 if (IS_ERR(pll2_400)) {
444 dev_err(busfreq_dev, "%s: failed to get pll2_pfd2_396m\n", 619 dev_err(busfreq_dev, "%s: failed to get pll2_pfd2_396m\n",
445 __func__); 620 __func__);
446 return PTR_ERR(pll2_400); 621 return PTR_ERR(pll2_400);
447 } 622 }
448 623
449 pll2_200 = devm_clk_get(&pdev->dev, "pll2_198m"); 624 pll2_200 = devm_clk_get(&pdev->dev, "pll2_198m");
450 if (IS_ERR(pll2_200)) { 625 if (IS_ERR(pll2_200)) {
451 dev_err(busfreq_dev, "%s: failed to get pll2_198m\n", 626 dev_err(busfreq_dev, "%s: failed to get pll2_198m\n",
452 __func__); 627 __func__);
453 return PTR_ERR(pll2_200); 628 return PTR_ERR(pll2_200);
454 } 629 }
455 630
456 pll2 = devm_clk_get(&pdev->dev, "pll2_bus"); 631 pll2 = devm_clk_get(&pdev->dev, "pll2_bus");
457 if (IS_ERR(pll2)) { 632 if (IS_ERR(pll2)) {
458 dev_err(busfreq_dev, "%s: failed to get pll2_bus\n", 633 dev_err(busfreq_dev, "%s: failed to get pll2_bus\n",
459 __func__); 634 __func__);
460 return PTR_ERR(pll2); 635 return PTR_ERR(pll2);
461 } 636 }
462 637
463 cpu_clk = devm_clk_get(&pdev->dev, "arm"); 638 cpu_clk = devm_clk_get(&pdev->dev, "arm");
464 if (IS_ERR(cpu_clk)) { 639 if (IS_ERR(cpu_clk)) {
465 dev_err(busfreq_dev, "%s: failed to get cpu_clk\n", 640 dev_err(busfreq_dev, "%s: failed to get cpu_clk\n",
466 __func__); 641 __func__);
467 return PTR_ERR(cpu_clk); 642 return PTR_ERR(cpu_clk);
468 } 643 }
469 644
470 pll3 = devm_clk_get(&pdev->dev, "pll3_usb_otg"); 645 pll3 = devm_clk_get(&pdev->dev, "pll3_usb_otg");
471 if (IS_ERR(pll3)) { 646 if (IS_ERR(pll3)) {
472 dev_err(busfreq_dev, "%s: failed to get pll3_usb_otg\n", 647 dev_err(busfreq_dev, "%s: failed to get pll3_usb_otg\n",
473 __func__); 648 __func__);
474 return PTR_ERR(pll3); 649 return PTR_ERR(pll3);
475 } 650 }
476 651
477 periph_clk = devm_clk_get(&pdev->dev, "periph"); 652 periph_clk = devm_clk_get(&pdev->dev, "periph");
478 if (IS_ERR(periph_clk)) { 653 if (IS_ERR(periph_clk)) {
479 dev_err(busfreq_dev, "%s: failed to get periph\n", 654 dev_err(busfreq_dev, "%s: failed to get periph\n",
480 __func__); 655 __func__);
481 return PTR_ERR(periph_clk); 656 return PTR_ERR(periph_clk);
482 } 657 }
483 658
484 periph_pre_clk = devm_clk_get(&pdev->dev, "periph_pre"); 659 periph_pre_clk = devm_clk_get(&pdev->dev, "periph_pre");
485 if (IS_ERR(periph_pre_clk)) { 660 if (IS_ERR(periph_pre_clk)) {
486 dev_err(busfreq_dev, "%s: failed to get periph_pre\n", 661 dev_err(busfreq_dev, "%s: failed to get periph_pre\n",
487 __func__); 662 __func__);
488 return PTR_ERR(periph_pre_clk); 663 return PTR_ERR(periph_pre_clk);
489 } 664 }
490 665
491 periph_clk2 = devm_clk_get(&pdev->dev, "periph_clk2"); 666 periph_clk2 = devm_clk_get(&pdev->dev, "periph_clk2");
492 if (IS_ERR(periph_clk2)) { 667 if (IS_ERR(periph_clk2)) {
493 dev_err(busfreq_dev, "%s: failed to get periph_clk2\n", 668 dev_err(busfreq_dev, "%s: failed to get periph_clk2\n",
494 __func__); 669 __func__);
495 return PTR_ERR(periph_clk2); 670 return PTR_ERR(periph_clk2);
496 } 671 }
497 672
498 periph_clk2_sel = devm_clk_get(&pdev->dev, "periph_clk2_sel"); 673 periph_clk2_sel = devm_clk_get(&pdev->dev, "periph_clk2_sel");
499 if (IS_ERR(periph_clk2_sel)) { 674 if (IS_ERR(periph_clk2_sel)) {
500 dev_err(busfreq_dev, "%s: failed to get periph_clk2_sel\n", 675 dev_err(busfreq_dev, "%s: failed to get periph_clk2_sel\n",
501 __func__); 676 __func__);
502 return PTR_ERR(periph_clk2_sel); 677 return PTR_ERR(periph_clk2_sel);
503 } 678 }
504 679
505 osc_clk = devm_clk_get(&pdev->dev, "osc"); 680 osc_clk = devm_clk_get(&pdev->dev, "osc");
506 if (IS_ERR(osc_clk)) { 681 if (IS_ERR(osc_clk)) {
507 dev_err(busfreq_dev, "%s: failed to get osc_clk\n", 682 dev_err(busfreq_dev, "%s: failed to get osc_clk\n",
508 __func__); 683 __func__);
509 return PTR_ERR(osc_clk); 684 return PTR_ERR(osc_clk);
510 } 685 }
511 686
687 if (cpu_is_imx6sl()) {
688 pll1_sys = devm_clk_get(&pdev->dev, "pll1_sys");
689 if (IS_ERR(pll1_sys)) {
690 dev_err(busfreq_dev, "%s: failed to get pll1_sys\n",
691 __func__);
692 return PTR_ERR(pll1_sys);
693 }
694
695 ahb_clk = devm_clk_get(&pdev->dev, "ahb");
696 if (IS_ERR(ahb_clk)) {
697 dev_err(busfreq_dev, "%s: failed to get ahb_clk\n",
698 __func__);
699 return PTR_ERR(ahb_clk);
700 }
701
702 ocram_clk = devm_clk_get(&pdev->dev, "ocram");
703 if (IS_ERR(ocram_clk)) {
704 dev_err(busfreq_dev, "%s: failed to get ocram_clk\n",
705 __func__);
706 return PTR_ERR(ocram_clk);
707 }
708
709 pll1_sw_clk = devm_clk_get(&pdev->dev, "pll1_sw");
710 if (IS_ERR(pll1_sw_clk)) {
711 dev_err(busfreq_dev, "%s: failed to get pll1_sw_clk\n",
712 __func__);
713 return PTR_ERR(pll1_sw_clk);
714 }
715
716 periph2_clk = devm_clk_get(&pdev->dev, "periph2");
717 if (IS_ERR(periph2_clk)) {
718 dev_err(busfreq_dev, "%s: failed to get periph2\n",
719 __func__);
720 return PTR_ERR(periph2_clk);
721 }
722
723 periph2_pre_clk = devm_clk_get(&pdev->dev, "periph2_pre");
724 if (IS_ERR(periph2_pre_clk)) {
725 dev_err(busfreq_dev,
726 "%s: failed to get periph2_pre_clk\n",
727 __func__);
728 return PTR_ERR(periph2_pre_clk);
729 }
730
731 periph2_clk2 = devm_clk_get(&pdev->dev, "periph2_clk2");
732 if (IS_ERR(periph2_clk2)) {
733 dev_err(busfreq_dev,
734 "%s: failed to get periph2_clk2\n",
735 __func__);
736 return PTR_ERR(periph2_clk2);
737 }
738
739 periph2_clk2_sel = devm_clk_get(&pdev->dev, "periph2_clk2_sel");
740 if (IS_ERR(periph2_clk2_sel)) {
741 dev_err(busfreq_dev,
742 "%s: failed to get periph2_clk2_sel\n",
743 __func__);
744 return PTR_ERR(periph2_clk2_sel);
745 }
746
747 }
748
512 err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr); 749 err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
513 if (err) { 750 if (err) {
514 dev_err(busfreq_dev, 751 dev_err(busfreq_dev,
@@ -534,7 +771,7 @@ static int busfreq_probe(struct platform_device *pdev)
534 if (cpu_is_imx6q()) { 771 if (cpu_is_imx6q()) {
535 if (of_property_read_u32(pdev->dev.of_node, "fsl,med_ddr_freq", 772 if (of_property_read_u32(pdev->dev.of_node, "fsl,med_ddr_freq",
536 &ddr_med_rate)) { 773 &ddr_med_rate)) {
537 dev_err(busfreq_dev, 774 dev_WARN(busfreq_dev,
538 "DDR medium rate not supported.\n"); 775 "DDR medium rate not supported.\n");
539 ddr_med_rate = ddr_normal_rate; 776 ddr_med_rate = ddr_normal_rate;
540 } 777 }
@@ -543,8 +780,12 @@ static int busfreq_probe(struct platform_device *pdev)
543 INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler); 780 INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler);
544 INIT_DELAYED_WORK(&bus_freq_daemon, bus_freq_daemon_handler); 781 INIT_DELAYED_WORK(&bus_freq_daemon, bus_freq_daemon_handler);
545 register_pm_notifier(&imx_bus_freq_pm_notifier); 782 register_pm_notifier(&imx_bus_freq_pm_notifier);
783 register_reboot_notifier(&imx_busfreq_reboot_notifier);
546 784
547 err = init_mmdc_settings(pdev); 785 if (cpu_is_imx6sl())
786 err = init_mmdc_lpddr2_settings(pdev);
787 else
788 err = init_mmdc_ddr3_settings(pdev);
548 if (err) { 789 if (err) {
549 dev_err(busfreq_dev, "Busfreq init of MMDC failed\n"); 790 dev_err(busfreq_dev, "Busfreq init of MMDC failed\n");
550 return err; 791 return err;
diff --git a/arch/arm/mach-imx/busfreq_ddr3.c b/arch/arm/mach-imx/busfreq_ddr3.c
index 6ecd2f8a4407..6ac7d27fe86f 100644
--- a/arch/arm/mach-imx/busfreq_ddr3.c
+++ b/arch/arm/mach-imx/busfreq_ddr3.c
@@ -54,6 +54,13 @@ static void __iomem *l2_base;
54static void __iomem *gic_dist_base; 54static void __iomem *gic_dist_base;
55static u32 *irqs_used; 55static u32 *irqs_used;
56 56
57static void *ddr_freq_change_iram_base;
58static int ddr_settings_size;
59static int iomux_settings_size;
60static volatile unsigned int cpus_in_wfe;
61static volatile bool wait_for_ddr_freq_update;
62static int curr_ddr_rate;
63
57void (*mx6_change_ddr_freq)(u32 freq, void *ddr_settings, 64void (*mx6_change_ddr_freq)(u32 freq, void *ddr_settings,
58 bool dll_mode, void *iomux_offsets) = NULL; 65 bool dll_mode, void *iomux_offsets) = NULL;
59 66
@@ -64,13 +71,6 @@ extern int audio_bus_freq_mode;
64extern void mx6_ddr3_freq_change(u32 freq, void *ddr_settings, 71extern void mx6_ddr3_freq_change(u32 freq, void *ddr_settings,
65 bool dll_mode, void *iomux_offsets); 72 bool dll_mode, void *iomux_offsets);
66 73
67static void *ddr_freq_change_iram_base;
68static int ddr_settings_size;
69static int iomux_settings_size;
70static volatile unsigned int cpus_in_wfe;
71static volatile bool wait_for_ddr_freq_update;
72static int curr_ddr_rate;
73
74#define MIN_DLL_ON_FREQ 333000000 74#define MIN_DLL_ON_FREQ 333000000
75#define MAX_DLL_OFF_FREQ 125000000 75#define MAX_DLL_OFF_FREQ 125000000
76#define DDR_FREQ_CHANGE_SIZE 0x2000 76#define DDR_FREQ_CHANGE_SIZE 0x2000
@@ -250,7 +250,7 @@ int update_ddr_freq(int ddr_rate)
250 return 0; 250 return 0;
251} 251}
252 252
253int init_mmdc_settings(struct platform_device *busfreq_pdev) 253int init_mmdc_ddr3_settings(struct platform_device *busfreq_pdev)
254{ 254{
255 struct device *dev = &busfreq_pdev->dev; 255 struct device *dev = &busfreq_pdev->dev;
256 struct platform_device *ocram_dev; 256 struct platform_device *ocram_dev;
@@ -400,17 +400,17 @@ int init_mmdc_settings(struct platform_device *busfreq_pdev)
400 } 400 }
401 401
402 /* 402 /*
403 * Allocate extra space to store the number of entries in the 403 * Allocate extra space to store the number of entries in the
404 * ddr_settings plus 4 extra regsiter information that needs 404 * ddr_settings plus 4 extra regsiter information that needs
405 * to be passed to the frequency change code. 405 * to be passed to the frequency change code.
406 * sizeof(iram_ddr_settings) = sizeof(ddr_settings) + 406 * sizeof(iram_ddr_settings) = sizeof(ddr_settings) +
407 * entries in ddr_settings + 16. 407 * entries in ddr_settings + 16.
408 * The last 4 enties store the addresses of the registers: 408 * The last 4 enties store the addresses of the registers:
409 * CCM_BASE_ADDR 409 * CCM_BASE_ADDR
410 * MMDC_BASE_ADDR 410 * MMDC_BASE_ADDR
411 * IOMUX_BASE_ADDR 411 * IOMUX_BASE_ADDR
412 * L2X0_BASE_ADDR 412 * L2X0_BASE_ADDR
413 */ 413 */
414 iram_addr = (void *)gen_pool_alloc(iram_pool, 414 iram_addr = (void *)gen_pool_alloc(iram_pool,
415 (ddr_settings_size * 8) + 8 + 32); 415 (ddr_settings_size * 8) + 8 + 32);
416 iram_ddr_settings = iram_addr; 416 iram_ddr_settings = iram_addr;
@@ -456,7 +456,7 @@ int init_mmdc_settings(struct platform_device *busfreq_pdev)
456 iram_paddr = gen_pool_virt_to_phys(iram_pool, 456 iram_paddr = gen_pool_virt_to_phys(iram_pool,
457 (unsigned long)ddr_freq_change_iram_base); 457 (unsigned long)ddr_freq_change_iram_base);
458 /* 458 /*
459 * need to remap the area here since we want 459 * Need to remap the area here since we want
460 * the memory region to be executable. 460 * the memory region to be executable.
461 */ 461 */
462 ddr_freq_change_iram_base = __arm_ioremap(iram_paddr, 462 ddr_freq_change_iram_base = __arm_ioremap(iram_paddr,
diff --git a/arch/arm/mach-imx/busfreq_lpddr2.c b/arch/arm/mach-imx/busfreq_lpddr2.c
new file mode 100644
index 000000000000..f15b8290669c
--- /dev/null
+++ b/arch/arm/mach-imx/busfreq_lpddr2.c
@@ -0,0 +1,172 @@
1/*
2 * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
3 */
4
5/*
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14/*!
15 * @file busfreq_lpddr2.c
16 *
17 * @brief iMX6 LPDDR2 frequency change specific file.
18 *
19 * @ingroup PM
20 */
21#include <asm/cacheflush.h>
22#include <asm/fncpy.h>
23#include <asm/io.h>
24#include <asm/mach/map.h>
25#include <asm/mach-types.h>
26#include <asm/tlb.h>
27#include <linux/clk.h>
28#include <linux/cpumask.h>
29#include <linux/delay.h>
30#include <linux/genalloc.h>
31#include <linux/interrupt.h>
32#include <linux/irqchip/arm-gic.h>
33#include <linux/kernel.h>
34#include <linux/mutex.h>
35#include <linux/of.h>
36#include <linux/of_address.h>
37#include <linux/of_device.h>
38#include <linux/platform_device.h>
39#include <linux/proc_fs.h>
40#include <linux/sched.h>
41#include <linux/smp.h>
42
43#include "hardware.h"
44
45/* DDR settings */
46static void __iomem *mmdc_base;
47static void __iomem *anatop_base;
48static void __iomem *ccm_base;
49static void __iomem *l2_base;
50static struct device *busfreq_dev;
51static void *ddr_freq_change_iram_base;
52static int curr_ddr_rate;
53static unsigned long reg_addrs[4];
54
55void (*mx6_change_lpddr2_freq)(u32 ddr_freq, int bus_freq_mode,
56 void *iram_addr) = NULL;
57
58extern unsigned int ddr_normal_rate;
59extern int low_bus_freq_mode;
60extern int audio_bus_freq_mode;
61extern void mx6_lpddr2_freq_change(u32 freq, int bus_freq_mode,
62 void *iram_addr);
63
64
65#define LPDDR2_FREQ_CHANGE_SIZE 0x1000
66
67
68/* change the DDR frequency. */
69int update_lpddr2_freq(int ddr_rate)
70{
71 if (ddr_rate == curr_ddr_rate)
72 return 0;
73
74 mx6_change_lpddr2_freq(ddr_rate, low_bus_freq_mode, reg_addrs);
75
76 curr_ddr_rate = ddr_rate;
77
78 dev_dbg(busfreq_dev, "\nBus freq set to %d start...\n", ddr_rate);
79
80 return 0;
81}
82
83int init_mmdc_lpddr2_settings(struct platform_device *busfreq_pdev)
84{
85 struct platform_device *ocram_dev;
86 unsigned int iram_paddr;
87 struct device_node *node;
88 struct gen_pool *iram_pool;
89
90 busfreq_dev = &busfreq_pdev->dev;
91 node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-mmdc");
92 if (!node) {
93 printk(KERN_ERR "failed to find imx6sl-mmdc device tree data!\n");
94 return -EINVAL;
95 }
96 mmdc_base = of_iomap(node, 0);
97 WARN(!mmdc_base, "unable to map mmdc registers\n");
98
99 node = NULL;
100 node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-ccm");
101 if (!node) {
102 printk(KERN_ERR "failed to find imx6sl-ccm device tree data!\n");
103 return -EINVAL;
104 }
105 ccm_base = of_iomap(node, 0);
106 WARN(!ccm_base, "unable to map ccm registers\n");
107
108 node = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
109 if (!node) {
110 printk(KERN_ERR "failed to find imx6sl-pl310-cache device tree data!\n");
111 return -EINVAL;
112 }
113 l2_base = of_iomap(node, 0);
114 WARN(!l2_base, "unable to map PL310 registers\n");
115
116 node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop");
117 if (!node) {
118 printk(KERN_ERR "failed to find imx6sl-pl310-cache device tree data!\n");
119 return -EINVAL;
120 }
121 anatop_base = of_iomap(node, 0);
122 WARN(!anatop_base, "unable to map anatop registers\n");
123
124 node = NULL;
125 node = of_find_compatible_node(NULL, NULL, "mmio-sram");
126 if (!node) {
127 dev_err(busfreq_dev, "%s: failed to find ocram node\n",
128 __func__);
129 return -EINVAL;
130 }
131
132 ocram_dev = of_find_device_by_node(node);
133 if (!ocram_dev) {
134 dev_err(busfreq_dev, "failed to find ocram device!\n");
135 return -EINVAL;
136 }
137
138 iram_pool = dev_get_gen_pool(&ocram_dev->dev);
139 if (!iram_pool) {
140 dev_err(busfreq_dev, "iram pool unavailable!\n");
141 return -EINVAL;
142 }
143
144 reg_addrs[0] = (unsigned long)anatop_base;
145 reg_addrs[1] = (unsigned long)ccm_base;
146 reg_addrs[2] = (unsigned long)mmdc_base;
147 reg_addrs[3] = (unsigned long)l2_base;
148
149 ddr_freq_change_iram_base = (void *)gen_pool_alloc(iram_pool,
150 LPDDR2_FREQ_CHANGE_SIZE);
151 if (!ddr_freq_change_iram_base) {
152 dev_err(busfreq_dev,
153 "Cannot alloc iram for ddr freq change code!\n");
154 return -ENOMEM;
155 }
156
157 iram_paddr = gen_pool_virt_to_phys(iram_pool,
158 (unsigned long)ddr_freq_change_iram_base);
159 /*
160 * Need to remap the area here since we want
161 * the memory region to be executable.
162 */
163 ddr_freq_change_iram_base = __arm_ioremap(iram_paddr,
164 LPDDR2_FREQ_CHANGE_SIZE,
165 MT_MEMORY_NONCACHED);
166 mx6_change_lpddr2_freq = (void *)fncpy(ddr_freq_change_iram_base,
167 &mx6_lpddr2_freq_change, LPDDR2_FREQ_CHANGE_SIZE);
168
169 curr_ddr_rate = ddr_normal_rate;
170
171 return 0;
172}
diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c
index 5a7e76af7698..660656c449bc 100644
--- a/arch/arm/mach-imx/clk-imx6sl.c
+++ b/arch/arm/mach-imx/clk-imx6sl.c
@@ -7,9 +7,13 @@
7 * 7 *
8 */ 8 */
9 9
10#define CCM_CCDR_OFFSET 0x4
11#define CCDR_CH0_HS_BYP 17
12
10#include <linux/clk.h> 13#include <linux/clk.h>
11#include <linux/clkdev.h> 14#include <linux/clkdev.h>
12#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/io.h>
13#include <linux/of.h> 17#include <linux/of.h>
14#include <linux/of_address.h> 18#include <linux/of_address.h>
15#include <linux/of_irq.h> 19#include <linux/of_irq.h>
@@ -25,10 +29,11 @@ static const char const *ocram_sels[] = { "periph", "ocram_alt_sels", };
25static const char const *pre_periph_sels[] = { "pll2_bus", "pll2_pfd2", "pll2_pfd0", "pll2_198m", }; 29static const char const *pre_periph_sels[] = { "pll2_bus", "pll2_pfd2", "pll2_pfd0", "pll2_198m", };
26static const char const *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", }; 30static const char const *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", };
27static const char const *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", }; 31static const char const *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
28static const char const *periph_sels[] = { "pre_periph_sel", "periph_clk2_podf", }; 32static const char const *periph_sels[] = { "pre_periph_sel", "periph_clk2", };
29static const char const *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2_podf", }; 33static const char const *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2", };
30static const char const *csi_sels[] = { "osc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", }; 34static const char const *csi_sels[] = { "osc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", };
31static const char const *lcdif_axi_sels[] = { "pll2_bus", "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", }; 35static const char const *lcdif_axi_sels[] = { "pll2_bus", "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", };
36static const char const *csi_lcdif_sels[] = { "mmdc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", };
32static const char const *usdhc_sels[] = { "pll2_pfd2", "pll2_pfd0", }; 37static const char const *usdhc_sels[] = { "pll2_pfd2", "pll2_pfd0", };
33static const char const *ssi_sels[] = { "pll3_pfd2", "pll3_pfd3", "pll4_audio_div", "dummy", }; 38static const char const *ssi_sels[] = { "pll3_pfd2", "pll3_pfd3", "pll4_audio_div", "dummy", };
34static const char const *perclk_sels[] = { "ipg", "osc", }; 39static const char const *perclk_sels[] = { "ipg", "osc", };
@@ -69,27 +74,49 @@ static struct clk *clks[IMX6SL_CLK_CLK_END];
69static struct clk_onecell_data clk_data; 74static struct clk_onecell_data clk_data;
70static u32 cur_arm_podf; 75static u32 cur_arm_podf;
71 76
77extern int low_bus_freq_mode;
78
72/* 79/*
73 * On MX6SL, need to ensure that the ARM:IPG clock ratio is maintained 80 * On MX6SL, need to ensure that the ARM:IPG clock ratio is maintained
74 * within 12:5 when the clocks to ARM are gated when the SOC enters 81 * within 12:5 when the clocks to ARM are gated when the SOC enters
75 * WAIT mode. This is necessary to avoid WAIT mode issue (an early 82 * WAIT mode. This is necessary to avoid WAIT mode issue (an early
76 * interrupt waking up the ARM). 83 * interrupt waking up the ARM).
77 * This function will set the ARM clk to max value within the 12:5 limit. 84 * This function will set the ARM clk to max value within the 12:5 limit.
78 */ 85 */
79void imx6sl_set_wait_clk(bool enter) 86void imx6sl_set_wait_clk(bool enter)
80{ 87{
81 u32 parent_rate = clk_get_rate(clk_get_parent(clks[IMX6SL_CLK_ARM])); 88 u32 parent_rate;
82 89
83 if (enter) { 90 if (enter) {
91 u32 wait_podf, new_parent_rate;
84 u32 ipg_rate = clk_get_rate(clks[IMX6SL_CLK_IPG]); 92 u32 ipg_rate = clk_get_rate(clks[IMX6SL_CLK_IPG]);
85 u32 max_arm_wait_clk = (12 * ipg_rate) / 5; 93 u32 max_arm_wait_clk = (12 * ipg_rate) / 5;
86 u32 wait_podf = (parent_rate + max_arm_wait_clk - 1) / 94 parent_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SW]);
95 cur_arm_podf = parent_rate / clk_get_rate(clks[IMX6SL_CLK_ARM]);
96 if (low_bus_freq_mode) {
97 /*
98 * IPG clk is at 12MHz at this point, we can only run
99 * ARM at a max of 28.8MHz. So we need to set ARM
100 * to run from the 24MHz OSC, as there is no way to
101 * get 28.8MHz when ARM is sourced from PLL1.
102 */
103 clk_set_parent(clks[IMX6SL_CLK_STEP],
104 clks[IMX6SL_CLK_OSC]);
105 clk_set_parent(clks[IMX6SL_CLK_PLL1_SW],
106 clks[IMX6SL_CLK_STEP]);
107 }
108 new_parent_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SW]);
109 wait_podf = (new_parent_rate + max_arm_wait_clk - 1) /
87 max_arm_wait_clk; 110 max_arm_wait_clk;
88 111
89 cur_arm_podf = parent_rate / clk_get_rate(clks[IMX6SL_CLK_ARM]); 112 clk_set_rate(clks[IMX6SL_CLK_ARM], new_parent_rate / wait_podf);
90 clk_set_rate(clks[IMX6SL_CLK_ARM], parent_rate / wait_podf); 113 } else {
91 } else 114 if (low_bus_freq_mode)
115 /* Move ARM back to PLL1. */
116 clk_set_parent(clks[IMX6SL_CLK_PLL1_SW], clks[IMX6SL_CLK_PLL1_SYS]);
117 parent_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SW]);
92 clk_set_rate(clks[IMX6SL_CLK_ARM], parent_rate / cur_arm_podf); 118 clk_set_rate(clks[IMX6SL_CLK_ARM], parent_rate / cur_arm_podf);
119 }
93} 120}
94 121
95static void __init imx6sl_clocks_init(struct device_node *ccm_node) 122static void __init imx6sl_clocks_init(struct device_node *ccm_node)
@@ -99,6 +126,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
99 int irq; 126 int irq;
100 int ret; 127 int ret;
101 int i; 128 int i;
129 u32 reg;
102 130
103 clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); 131 clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
104 clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0); 132 clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
@@ -193,8 +221,8 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
193 221
194 /* name parent_name reg shift width */ 222 /* name parent_name reg shift width */
195 clks[IMX6SL_CLK_OCRAM_PODF] = imx_clk_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3); 223 clks[IMX6SL_CLK_OCRAM_PODF] = imx_clk_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3);
196 clks[IMX6SL_CLK_PERIPH_CLK2_PODF] = imx_clk_divider("periph_clk2_podf", "periph_clk2_sel", base + 0x14, 27, 3); 224 clks[IMX6SL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
197 clks[IMX6SL_CLK_PERIPH2_CLK2_PODF] = imx_clk_divider("periph2_clk2_podf", "periph2_clk2_sel", base + 0x14, 0, 3); 225 clks[IMX6SL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
198 clks[IMX6SL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); 226 clks[IMX6SL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
199 clks[IMX6SL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3); 227 clks[IMX6SL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
200 clks[IMX6SL_CLK_LCDIF_AXI_PODF] = imx_clk_divider("lcdif_axi_podf", "lcdif_axi_sel", base + 0x3c, 16, 3); 228 clks[IMX6SL_CLK_LCDIF_AXI_PODF] = imx_clk_divider("lcdif_axi_podf", "lcdif_axi_sel", base + 0x3c, 16, 3);
@@ -332,6 +360,11 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
332 /* Set initial power mode */ 360 /* Set initial power mode */
333 imx6_set_lpm(WAIT_CLOCKED); 361 imx6_set_lpm(WAIT_CLOCKED);
334 362
363 /* Ensure that CH0 handshake is bypassed. */
364 reg = readl_relaxed(base + CCM_CCDR_OFFSET);
365 reg |= 1 << CCDR_CH0_HS_BYP;
366 writel_relaxed(reg, base + CCM_CCDR_OFFSET);
367
335 np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-gpt"); 368 np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-gpt");
336 base = of_iomap(np, 0); 369 base = of_iomap(np, 0);
337 WARN_ON(!base); 370 WARN_ON(!base);
diff --git a/arch/arm/mach-imx/lpddr2_freq_imx6.S b/arch/arm/mach-imx/lpddr2_freq_imx6.S
new file mode 100644
index 000000000000..091bfae96478
--- /dev/null
+++ b/arch/arm/mach-imx/lpddr2_freq_imx6.S
@@ -0,0 +1,483 @@
1/*
2 * Copyright (C) 2012-2013 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#include <linux/linkage.h>
20
21 .macro mx6sl_switch_to_24MHz
22
23 /*
24 * Set MMDC clock to be sourced from PLL3.
25 * Ensure first periph2_clk2 is sourced from PLL3.
26 * Set the PERIPH2_CLK2_PODF to divide by 2.
27 */
28 ldr r6, [r2, #0x14]
29 bic r6, r6, #0x7
30 orr r6, r6, #0x1
31 str r6, [r2, #0x14]
32
33 /* Select PLL3 to source MMDC. */
34 ldr r6, [r2, #0x18]
35 bic r6, r6, #0x100000
36 str r6, [r2, #0x18]
37
38 /* Swtich periph2_clk_sel to run from PLL3. */
39 ldr r6, [r2, #0x14]
40 orr r6, r6, #0x4000000
41 str r6, [r2, #0x14]
42
43periph2_clk_switch1:
44 ldr r6, [r2, #0x48]
45 cmp r6, #0
46 bne periph2_clk_switch1
47
48 /*
49 * Need to clock gate the 528 PFDs before
50 * powering down PLL2.
51 * Only the PLL2_PFD2_400M should be ON
52 * at this time, so only clock gate that one.
53 */
54 ldr r6, [r3, #0x100]
55 orr r6, r6, #0x800000
56 str r6, [r3, #0x100]
57
58 /*
59 * Set PLL2 to bypass state. We should be here
60 * only if MMDC is not sourced from PLL2.
61 */
62 ldr r6, [r3, #0x30]
63 orr r6, r6, #0x10000
64 str r6, [r3, #0x30]
65
66 ldr r6, [r3, #0x30]
67 orr r6, r6, #0x1000
68 str r6, [r3, #0x30]
69
70 /* Ensure pre_periph2_clk_mux is set to pll2 */
71 ldr r6, [r2, #0x18]
72 bic r6, r6, #0x600000
73 str r6, [r2, #0x18]
74
75 /* Set MMDC clock to be sourced from the bypassed PLL2. */
76 ldr r6, [r2, #0x14]
77 bic r6, r6, #0x4000000
78 str r6, [r2, #0x14]
79
80periph2_clk_switch2:
81 ldr r6, [r2, #0x48]
82 cmp r6, #0
83 bne periph2_clk_switch2
84
85 /*
86 * Now move MMDC back to periph2_clk2 source.
87 * after selecting PLL2 as the option.
88 * Select PLL2 as the source.
89 */
90 ldr r6, [r2, #0x18]
91 orr r6, r6, #0x100000
92 str r6, [r2, #0x18]
93
94 /* set periph2_clk2_podf to divide by 1. */
95 ldr r6, [r2, #0x14]
96 bic r6, r6, #0x7
97 str r6, [r2, #0x14]
98
99 /* Now move periph2_clk to periph2_clk2 source */
100 ldr r6, [r2, #0x14]
101 orr r6, r6, #0x4000000
102 str r6, [r2, #0x14]
103
104periph2_clk_switch3:
105 ldr r6, [r2, #0x48]
106 cmp r6, #0
107 bne periph2_clk_switch3
108
109 /* Now set the MMDC PODF back to 1.*/
110 ldr r6, [r2, #0x14]
111 bic r6, r6, #0x38
112 str r6, [r2, #0x14]
113
114mmdc_podf0:
115 ldr r6, [r2, #0x48]
116 cmp r6, #0
117 bne mmdc_podf0
118
119 .endm
120
121 .macro ddr_switch_400MHz
122
123 /* Set MMDC divider first, in case PLL3 is at 480MHz. */
124 ldr r6, [r3, #0x10]
125 and r6, r6, #0x10000
126 cmp r6, #0x10000
127 beq pll3_in_bypass
128
129 /* Set MMDC divder to divide by 2. */
130 ldr r6, [r2, #0x14]
131 bic r6, r6, #0x38
132 orr r6, r6, #0x8
133 str r6, [r2, #0x14]
134
135mmdc_podf:
136 ldr r6, [r2, #0x48]
137 cmp r6, #0
138 bne mmdc_podf
139
140pll3_in_bypass:
141 /*
142 * Check if we are switching between
143 * 400Mhz <-> 100MHz.If so, we should
144 * try to source MMDC from PLL2_200M.
145 */
146 cmp r1, #0
147 beq not_low_bus_freq
148
149 /* Ensure that MMDC is sourced from PLL2 mux first. */
150 ldr r6, [r2, #0x14]
151 bic r6, r6, #0x4000000
152 str r6, [r2, #0x14]
153
154periph2_clk_switch4:
155 ldr r6, [r2, #0x48]
156 cmp r6, #0
157 bne periph2_clk_switch4
158
159not_low_bus_freq:
160 /* Now ensure periph2_clk2_sel mux is set to PLL3 */
161 ldr r6, [r2, #0x18]
162 bic r6, r6, #0x100000
163 str r6, [r2, #0x18]
164
165 /* Now switch MMDC to PLL3. */
166 ldr r6, [r2, #0x14]
167 orr r6, r6, #0x4000000
168 str r6, [r2, #0x14]
169
170periph2_clk_switch5:
171 ldr r6, [r2, #0x48]
172 cmp r6, #0
173 bne periph2_clk_switch5
174
175 /*
176 * Check if PLL2 is already unlocked.
177 * If so do nothing with PLL2.
178 */
179 cmp r1, #0
180 beq pll2_already_on
181
182 /* Now power up PLL2 and unbypass it. */
183 ldr r6, [r3, #0x30]
184 bic r6, r6, #0x1000
185 str r6, [r3, #0x30]
186
187 /* Make sure PLL2 has locked.*/
188wait_for_pll_lock:
189 ldr r6, [r3, #0x30]
190 and r6, r6, #0x80000000
191 cmp r6, #0x80000000
192 bne wait_for_pll_lock
193
194 ldr r6, [r3, #0x30]
195 bic r6, r6, #0x10000
196 str r6, [r3, #0x30]
197
198 /*
199 * Need to enable the 528 PFDs after
200 * powering up PLL2.
201 * Only the PLL2_PFD2_400M should be ON
202 * as it feeds the MMDC. Rest should have
203 * been managed by clock code.
204 */
205 ldr r6, [r3, #0x100]
206 bic r6, r6, #0x800000
207 str r6, [r3, #0x100]
208
209pll2_already_on:
210 /*
211 * Now switch MMDC clk back to pll2_mux option.
212 * Ensure pre_periph2_clk2 is set to pll2_pfd_400M.
213 * If switching to audio DDR freq, set the
214 * pre_periph2_clk2 to PLL2_PFD_200M
215 */
216 ldr r6, =400000000
217 cmp r6, r0
218 bne use_pll2_pfd_200M
219
220 ldr r6, [r2, #0x18]
221 bic r6, r6, #0x600000
222 orr r6, r6, #0x200000
223 str r6, [r2, #0x18]
224 ldr r6, =400000000
225 b cont2
226
227use_pll2_pfd_200M:
228 ldr r6, [r2, #0x18]
229 orr r6, r6, #0x600000
230 str r6, [r2, #0x18]
231 ldr r6, =200000000
232
233cont2:
234 ldr r4, [r2, #0x14]
235 bic r4, r4, #0x4000000
236 str r4, [r2, #0x14]
237
238periph2_clk_switch6:
239 ldr r4, [r2, #0x48]
240 cmp r4, #0
241 bne periph2_clk_switch6
242
243change_divider_only:
244 /*
245 * Calculate the MMDC divider
246 * based on the requested freq.
247 */
248 ldr r4, =0
249Loop2:
250 sub r6, r6, r0
251 cmp r6, r0
252 blt Div_Found
253 add r4, r4, #1
254 bgt Loop2
255
256 /* Shift divider into correct offset. */
257 lsl r4, r4, #3
258Div_Found:
259 /* Set the MMDC PODF. */
260 ldr r6, [r2, #0x14]
261 bic r6, r6, #0x38
262 orr r6, r6, r4
263 str r6, [r2, #0x14]
264
265mmdc_podf1:
266 ldr r6, [r2, #0x48]
267 cmp r6, #0
268 bne mmdc_podf1
269
270 .endm
271
272 .macro mmdc_clk_lower_100MHz
273
274 /*
275 * Prior to reducing the DDR frequency (at 528/400 MHz),
276 * read the Measure unit count bits (MU_UNIT_DEL_NUM)
277 */
278 ldr r5, =0x8B8
279 ldr r6, [r8, r5]
280 /* Original MU unit count */
281 mov r6, r6, LSR #16
282 ldr r4, =0x3FF
283 and r6, r6, r4
284 /* Original MU unit count * 2 */
285 mov r7, r6, LSL #1
286 /*
287 * Bypass the automatic measure unit when below 100 MHz
288 * by setting the Measure unit bypass enable bit (MU_BYP_EN)
289 */
290 ldr r6, [r8, r5]
291 orr r6, r6, #0x400
292 str r6, [r8, r5]
293 /*
294 * Double the measure count value read in step 1 and program it in the
295 * measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit
296 * Register for the reduced frequency operation below 100 MHz
297 */
298 ldr r6, [r8, r5]
299 ldr r4, =0x3FF
300 bic r6, r6, r4
301 orr r6, r6, r7
302 str r6, [r8, r5]
303 /* Now perform a Force Measurement. */
304 ldr r6, [r8, r5]
305 orr r6, r6, #0x800
306 str r6, [r8, r5]
307 /* Wait for FRC_MSR to clear. */
308force_measure:
309 ldr r6, [r8, r5]
310 and r6, r6, #0x800
311 cmp r6, #0x0
312 bne force_measure
313
314 .endm
315
316 .macro mmdc_clk_above_100MHz
317
318 /* Make sure that the PHY measurement unit is NOT in bypass mode */
319 ldr r5, =0x8B8
320 ldr r6, [r8, r5]
321 bic r6, r6, #0x400
322 str r6, [r8, r5]
323 /* Now perform a Force Measurement. */
324 ldr r6, [r8, r5]
325 orr r6, r6, #0x800
326 str r6, [r8, r5]
327 /* Wait for FRC_MSR to clear. */
328force_measure1:
329 ldr r6, [r8, r5]
330 and r6, r6, #0x800
331 cmp r6, #0x0
332 bne force_measure1
333 .endm
334
335/*
336 * mx6_lpddr2_freq_change
337 *
338 * Make sure DDR is in self-refresh.
339 * IRQs are already disabled.
340 * r0 : DDR freq.
341 * r1: low_bus_freq_mode flag
342 * r2: Pointer to array containing addresses of registers.
343 */
344ENTRY(mx6_lpddr2_freq_change)
345
346 push {r4-r10}
347
348 mov r4, r2
349 ldr r3, [r4] @ANATOP_BASE_ADDR
350 ldr r2, [r4, #0x4] @CCM_BASE_ADDR
351 ldr r8, [r4, #0x8] @MMDC_P0_BASE_ADDR
352 ldr r7, [r4, #0x8] @L2_BASE_ADDR
353
354lpddr2_freq_change:
355 adr r9, lpddr2_freq_change
356
357 /* Prime all TLB entries. */
358 ldr r6, [r9]
359 ldr r6, [r8]
360 ldr r6, [r3]
361 ldr r6, [r2]
362
363 /* Drain all the L1 buffers. */
364 dsb
365
366#ifdef CONFIG_CACHE_L2X0
367 /*
368 * Need to make sure the buffers in L2 are drained.
369 * Performing a sync operation does this.
370 */
371 mov r6, #0x0
372 str r6, [r7, #0x730]
373#endif
374
375 /*
376 * The second dsb might be needed to keep cache sync (device write)
377 * ordering with the memory accesses before it.
378 */
379 dsb
380 isb
381
382 /* Disable Automatic power savings. */
383 ldr r6, [r8, #0x404]
384 orr r6, r6, #0x01
385 str r6, [r8, #0x404]
386
387 /* MMDC0_MDPDC disable power down timer */
388 ldr r6, [r8, #0x4]
389 bic r6, r6, #0xff00
390 str r6, [r8, #0x4]
391
392 /* Delay for a while */
393 ldr r10, =10
394delay1:
395 ldr r7, =0
396cont1:
397 ldr r6, [r8, r7]
398 add r7, r7, #4
399 cmp r7, #16
400 bne cont1
401 sub r10, r10, #1
402 cmp r10, #0
403 bgt delay1
404
405 /* Make the DDR explicitly enter self-refresh. */
406 ldr r6, [r8, #0x404]
407 orr r6, r6, #0x200000
408 str r6, [r8, #0x404]
409
410poll_dvfs_set_1:
411 ldr r6, [r8, #0x404]
412 and r6, r6, #0x2000000
413 cmp r6, #0x2000000
414 bne poll_dvfs_set_1
415
416 /* set SBS step-by-step mode */
417 ldr r6, [r8, #0x410]
418 orr r6, r6, #0x100
419 str r6, [r8, #0x410]
420
421 ldr r10, =100000000
422 cmp r0, r10
423 bgt set_ddr_mu_above_100
424 mmdc_clk_lower_100MHz
425
426set_ddr_mu_above_100:
427 ldr r10, =24000000
428 cmp r0, r10
429 beq set_to_24MHz
430
431 ddr_switch_400MHz
432
433 ldr r10,=100000000
434 cmp r0, r10
435 blt done
436 mmdc_clk_above_100MHz
437
438 b done
439
440set_to_24MHz:
441 mx6sl_switch_to_24MHz
442
443done:
444 /* clear DVFS - exit from self refresh mode */
445 ldr r6, [r8, #0x404]
446 bic r6, r6, #0x200000
447 str r6, [r8, #0x404]
448
449poll_dvfs_clear_1:
450 ldr r6, [r8, #0x404]
451 and r6, r6, #0x2000000
452 cmp r6, #0x2000000
453 beq poll_dvfs_clear_1
454
455 /* Enable Automatic power savings. */
456 ldr r6, [r8, #0x404]
457 bic r6, r6, #0x01
458 str r6, [r8, #0x404]
459
460 ldr r10, =24000000
461 cmp r0, r10
462 beq skip_power_down
463
464 /* Enable MMDC power down timer. */
465 ldr r6, [r8, #0x4]
466 orr r6, r6, #0x5500
467 str r6, [r8, #0x4]
468
469skip_power_down:
470 /* clear SBS - unblock DDR accesses */
471 ldr r6, [r8, #0x410]
472 bic r6, r6, #0x100
473 str r6, [r8, #0x410]
474
475 pop {r4-r10}
476
477 /* Restore registers */
478 mov pc, lr
479
480 .type mx6_lpddr2_do_iram, #object
481ENTRY(mx6_lpddr2_do_iram)
482 .word mx6_lpddr2_freq_change
483 .size mx6_lpddr2_freq_change, . - mx6_lpddr2_freq_change
diff --git a/include/dt-bindings/clock/imx6sl-clock.h b/include/dt-bindings/clock/imx6sl-clock.h
index 118b730bc635..b04e64a2ec2a 100644
--- a/include/dt-bindings/clock/imx6sl-clock.h
+++ b/include/dt-bindings/clock/imx6sl-clock.h
@@ -71,8 +71,8 @@
71#define IMX6SL_CLK_PERIPH 58 71#define IMX6SL_CLK_PERIPH 58
72#define IMX6SL_CLK_PERIPH2 59 72#define IMX6SL_CLK_PERIPH2 59
73#define IMX6SL_CLK_OCRAM_PODF 60 73#define IMX6SL_CLK_OCRAM_PODF 60
74#define IMX6SL_CLK_PERIPH_CLK2_PODF 61 74#define IMX6SL_CLK_PERIPH_CLK2 61
75#define IMX6SL_CLK_PERIPH2_CLK2_PODF 62 75#define IMX6SL_CLK_PERIPH2_CLK2 62
76#define IMX6SL_CLK_IPG 63 76#define IMX6SL_CLK_IPG 63
77#define IMX6SL_CLK_CSI_PODF 64 77#define IMX6SL_CLK_CSI_PODF 64
78#define IMX6SL_CLK_LCDIF_AXI_PODF 65 78#define IMX6SL_CLK_LCDIF_AXI_PODF 65