PageRenderTime 92ms CodeModel.GetById 17ms app.highlight 66ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/arm/mach-mx5/clock-mx51-mx53.c

https://github.com/AICP/kernel_asus_grouper
C | 1611 lines | 1238 code | 271 blank | 102 comment | 155 complexity | b09aff364fdc93aae11d0069b14ff56b MD5 | raw file
   1/*
   2 * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
   3 * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
   4 *
   5 * The code contained herein is licensed under the GNU General Public
   6 * License. You may obtain a copy of the GNU General Public License
   7 * Version 2 or later at the following locations:
   8 *
   9 * http://www.opensource.org/licenses/gpl-license.html
  10 * http://www.gnu.org/copyleft/gpl.html
  11 */
  12
  13#include <linux/mm.h>
  14#include <linux/delay.h>
  15#include <linux/clk.h>
  16#include <linux/io.h>
  17#include <linux/clkdev.h>
  18
  19#include <asm/div64.h>
  20
  21#include <mach/hardware.h>
  22#include <mach/common.h>
  23#include <mach/clock.h>
  24
  25#include "crm_regs.h"
  26
  27/* External clock values passed-in by the board code */
  28static unsigned long external_high_reference, external_low_reference;
  29static unsigned long oscillator_reference, ckih2_reference;
  30
  31static struct clk osc_clk;
  32static struct clk pll1_main_clk;
  33static struct clk pll1_sw_clk;
  34static struct clk pll2_sw_clk;
  35static struct clk pll3_sw_clk;
  36static struct clk mx53_pll4_sw_clk;
  37static struct clk lp_apm_clk;
  38static struct clk periph_apm_clk;
  39static struct clk ahb_clk;
  40static struct clk ipg_clk;
  41static struct clk usboh3_clk;
  42static struct clk emi_fast_clk;
  43static struct clk ipu_clk;
  44static struct clk mipi_hsc1_clk;
  45static struct clk esdhc1_clk;
  46static struct clk esdhc2_clk;
  47static struct clk esdhc3_mx53_clk;
  48
  49#define MAX_DPLL_WAIT_TRIES	1000 /* 1000 * udelay(1) = 1ms */
  50
  51/* calculate best pre and post dividers to get the required divider */
  52static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post,
  53	u32 max_pre, u32 max_post)
  54{
  55	if (div >= max_pre * max_post) {
  56		*pre = max_pre;
  57		*post = max_post;
  58	} else if (div >= max_pre) {
  59		u32 min_pre, temp_pre, old_err, err;
  60		min_pre = DIV_ROUND_UP(div, max_post);
  61		old_err = max_pre;
  62		for (temp_pre = max_pre; temp_pre >= min_pre; temp_pre--) {
  63			err = div % temp_pre;
  64			if (err == 0) {
  65				*pre = temp_pre;
  66				break;
  67			}
  68			err = temp_pre - err;
  69			if (err < old_err) {
  70				old_err = err;
  71				*pre = temp_pre;
  72			}
  73		}
  74		*post = DIV_ROUND_UP(div, *pre);
  75	} else {
  76		*pre = div;
  77		*post = 1;
  78	}
  79}
  80
  81static void _clk_ccgr_setclk(struct clk *clk, unsigned mode)
  82{
  83	u32 reg = __raw_readl(clk->enable_reg);
  84
  85	reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
  86	reg |= mode << clk->enable_shift;
  87
  88	__raw_writel(reg, clk->enable_reg);
  89}
  90
  91static int _clk_ccgr_enable(struct clk *clk)
  92{
  93	_clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_ON);
  94	return 0;
  95}
  96
  97static void _clk_ccgr_disable(struct clk *clk)
  98{
  99	_clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_OFF);
 100}
 101
 102static int _clk_ccgr_enable_inrun(struct clk *clk)
 103{
 104	_clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
 105	return 0;
 106}
 107
 108static void _clk_ccgr_disable_inwait(struct clk *clk)
 109{
 110	_clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
 111}
 112
 113/*
 114 * For the 4-to-1 muxed input clock
 115 */
 116static inline u32 _get_mux(struct clk *parent, struct clk *m0,
 117			   struct clk *m1, struct clk *m2, struct clk *m3)
 118{
 119	if (parent == m0)
 120		return 0;
 121	else if (parent == m1)
 122		return 1;
 123	else if (parent == m2)
 124		return 2;
 125	else if (parent == m3)
 126		return 3;
 127	else
 128		BUG();
 129
 130	return -EINVAL;
 131}
 132
 133static inline void __iomem *_mx51_get_pll_base(struct clk *pll)
 134{
 135	if (pll == &pll1_main_clk)
 136		return MX51_DPLL1_BASE;
 137	else if (pll == &pll2_sw_clk)
 138		return MX51_DPLL2_BASE;
 139	else if (pll == &pll3_sw_clk)
 140		return MX51_DPLL3_BASE;
 141	else
 142		BUG();
 143
 144	return NULL;
 145}
 146
 147static inline void __iomem *_mx53_get_pll_base(struct clk *pll)
 148{
 149	if (pll == &pll1_main_clk)
 150		return MX53_DPLL1_BASE;
 151	else if (pll == &pll2_sw_clk)
 152		return MX53_DPLL2_BASE;
 153	else if (pll == &pll3_sw_clk)
 154		return MX53_DPLL3_BASE;
 155	else if (pll == &mx53_pll4_sw_clk)
 156		return MX53_DPLL4_BASE;
 157	else
 158		BUG();
 159
 160	return NULL;
 161}
 162
 163static inline void __iomem *_get_pll_base(struct clk *pll)
 164{
 165	if (cpu_is_mx51())
 166		return _mx51_get_pll_base(pll);
 167	else
 168		return _mx53_get_pll_base(pll);
 169}
 170
 171static unsigned long clk_pll_get_rate(struct clk *clk)
 172{
 173	long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
 174	unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
 175	void __iomem *pllbase;
 176	s64 temp;
 177	unsigned long parent_rate;
 178
 179	parent_rate = clk_get_rate(clk->parent);
 180
 181	pllbase = _get_pll_base(clk);
 182
 183	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
 184	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
 185	dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
 186
 187	if (pll_hfsm == 0) {
 188		dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
 189		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
 190		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
 191	} else {
 192		dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
 193		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
 194		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
 195	}
 196	pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
 197	mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
 198	mfi = (mfi <= 5) ? 5 : mfi;
 199	mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
 200	mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
 201	/* Sign extend to 32-bits */
 202	if (mfn >= 0x04000000) {
 203		mfn |= 0xFC000000;
 204		mfn_abs = -mfn;
 205	}
 206
 207	ref_clk = 2 * parent_rate;
 208	if (dbl != 0)
 209		ref_clk *= 2;
 210
 211	ref_clk /= (pdf + 1);
 212	temp = (u64) ref_clk * mfn_abs;
 213	do_div(temp, mfd + 1);
 214	if (mfn < 0)
 215		temp = -temp;
 216	temp = (ref_clk * mfi) + temp;
 217
 218	return temp;
 219}
 220
 221static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
 222{
 223	u32 reg;
 224	void __iomem *pllbase;
 225
 226	long mfi, pdf, mfn, mfd = 999999;
 227	s64 temp64;
 228	unsigned long quad_parent_rate;
 229	unsigned long pll_hfsm, dp_ctl;
 230	unsigned long parent_rate;
 231
 232	parent_rate = clk_get_rate(clk->parent);
 233
 234	pllbase = _get_pll_base(clk);
 235
 236	quad_parent_rate = 4 * parent_rate;
 237	pdf = mfi = -1;
 238	while (++pdf < 16 && mfi < 5)
 239		mfi = rate * (pdf+1) / quad_parent_rate;
 240	if (mfi > 15)
 241		return -EINVAL;
 242	pdf--;
 243
 244	temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
 245	do_div(temp64, quad_parent_rate/1000000);
 246	mfn = (long)temp64;
 247
 248	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
 249	/* use dpdck0_2 */
 250	__raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
 251	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
 252	if (pll_hfsm == 0) {
 253		reg = mfi << 4 | pdf;
 254		__raw_writel(reg, pllbase + MXC_PLL_DP_OP);
 255		__raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
 256		__raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
 257	} else {
 258		reg = mfi << 4 | pdf;
 259		__raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
 260		__raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
 261		__raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
 262	}
 263
 264	return 0;
 265}
 266
 267static int _clk_pll_enable(struct clk *clk)
 268{
 269	u32 reg;
 270	void __iomem *pllbase;
 271	int i = 0;
 272
 273	pllbase = _get_pll_base(clk);
 274	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
 275	if (reg & MXC_PLL_DP_CTL_UPEN)
 276		return 0;
 277
 278	reg |= MXC_PLL_DP_CTL_UPEN;
 279	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
 280
 281	/* Wait for lock */
 282	do {
 283		reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
 284		if (reg & MXC_PLL_DP_CTL_LRF)
 285			break;
 286
 287		udelay(1);
 288	} while (++i < MAX_DPLL_WAIT_TRIES);
 289
 290	if (i == MAX_DPLL_WAIT_TRIES) {
 291		pr_err("MX5: pll locking failed\n");
 292		return -EINVAL;
 293	}
 294
 295	return 0;
 296}
 297
 298static void _clk_pll_disable(struct clk *clk)
 299{
 300	u32 reg;
 301	void __iomem *pllbase;
 302
 303	pllbase = _get_pll_base(clk);
 304	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
 305	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
 306}
 307
 308static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
 309{
 310	u32 reg, step;
 311
 312	reg = __raw_readl(MXC_CCM_CCSR);
 313
 314	/* When switching from pll_main_clk to a bypass clock, first select a
 315	 * multiplexed clock in 'step_sel', then shift the glitchless mux
 316	 * 'pll1_sw_clk_sel'.
 317	 *
 318	 * When switching back, do it in reverse order
 319	 */
 320	if (parent == &pll1_main_clk) {
 321		/* Switch to pll1_main_clk */
 322		reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
 323		__raw_writel(reg, MXC_CCM_CCSR);
 324		/* step_clk mux switched to lp_apm, to save power. */
 325		reg = __raw_readl(MXC_CCM_CCSR);
 326		reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
 327		reg |= (MXC_CCM_CCSR_STEP_SEL_LP_APM <<
 328				MXC_CCM_CCSR_STEP_SEL_OFFSET);
 329	} else {
 330		if (parent == &lp_apm_clk) {
 331			step = MXC_CCM_CCSR_STEP_SEL_LP_APM;
 332		} else  if (parent == &pll2_sw_clk) {
 333			step = MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED;
 334		} else  if (parent == &pll3_sw_clk) {
 335			step = MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED;
 336		} else
 337			return -EINVAL;
 338
 339		reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
 340		reg |= (step << MXC_CCM_CCSR_STEP_SEL_OFFSET);
 341
 342		__raw_writel(reg, MXC_CCM_CCSR);
 343		/* Switch to step_clk */
 344		reg = __raw_readl(MXC_CCM_CCSR);
 345		reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
 346	}
 347	__raw_writel(reg, MXC_CCM_CCSR);
 348	return 0;
 349}
 350
 351static unsigned long clk_pll1_sw_get_rate(struct clk *clk)
 352{
 353	u32 reg, div;
 354	unsigned long parent_rate;
 355
 356	parent_rate = clk_get_rate(clk->parent);
 357
 358	reg = __raw_readl(MXC_CCM_CCSR);
 359
 360	if (clk->parent == &pll2_sw_clk) {
 361		div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
 362		       MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
 363	} else if (clk->parent == &pll3_sw_clk) {
 364		div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
 365		       MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
 366	} else
 367		div = 1;
 368	return parent_rate / div;
 369}
 370
 371static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
 372{
 373	u32 reg;
 374
 375	reg = __raw_readl(MXC_CCM_CCSR);
 376
 377	if (parent == &pll2_sw_clk)
 378		reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
 379	else
 380		reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
 381
 382	__raw_writel(reg, MXC_CCM_CCSR);
 383	return 0;
 384}
 385
 386static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
 387{
 388	u32 reg;
 389
 390	if (parent == &osc_clk)
 391		reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
 392	else
 393		return -EINVAL;
 394
 395	__raw_writel(reg, MXC_CCM_CCSR);
 396
 397	return 0;
 398}
 399
 400static unsigned long clk_cpu_get_rate(struct clk *clk)
 401{
 402	u32 cacrr, div;
 403	unsigned long parent_rate;
 404
 405	parent_rate = clk_get_rate(clk->parent);
 406	cacrr = __raw_readl(MXC_CCM_CACRR);
 407	div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
 408
 409	return parent_rate / div;
 410}
 411
 412static int clk_cpu_set_rate(struct clk *clk, unsigned long rate)
 413{
 414	u32 reg, cpu_podf;
 415	unsigned long parent_rate;
 416
 417	parent_rate = clk_get_rate(clk->parent);
 418	cpu_podf = parent_rate / rate - 1;
 419	/* use post divider to change freq */
 420	reg = __raw_readl(MXC_CCM_CACRR);
 421	reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK;
 422	reg |= cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET;
 423	__raw_writel(reg, MXC_CCM_CACRR);
 424
 425	return 0;
 426}
 427
 428static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
 429{
 430	u32 reg, mux;
 431	int i = 0;
 432
 433	mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
 434
 435	reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
 436	reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
 437	__raw_writel(reg, MXC_CCM_CBCMR);
 438
 439	/* Wait for lock */
 440	do {
 441		reg = __raw_readl(MXC_CCM_CDHIPR);
 442		if (!(reg &  MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY))
 443			break;
 444
 445		udelay(1);
 446	} while (++i < MAX_DPLL_WAIT_TRIES);
 447
 448	if (i == MAX_DPLL_WAIT_TRIES) {
 449		pr_err("MX5: Set parent for periph_apm clock failed\n");
 450		return -EINVAL;
 451	}
 452
 453	return 0;
 454}
 455
 456static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
 457{
 458	u32 reg;
 459
 460	reg = __raw_readl(MXC_CCM_CBCDR);
 461
 462	if (parent == &pll2_sw_clk)
 463		reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
 464	else if (parent == &periph_apm_clk)
 465		reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
 466	else
 467		return -EINVAL;
 468
 469	__raw_writel(reg, MXC_CCM_CBCDR);
 470
 471	return 0;
 472}
 473
 474static struct clk main_bus_clk = {
 475	.parent = &pll2_sw_clk,
 476	.set_parent = _clk_main_bus_set_parent,
 477};
 478
 479static unsigned long clk_ahb_get_rate(struct clk *clk)
 480{
 481	u32 reg, div;
 482	unsigned long parent_rate;
 483
 484	parent_rate = clk_get_rate(clk->parent);
 485
 486	reg = __raw_readl(MXC_CCM_CBCDR);
 487	div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
 488	       MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
 489	return parent_rate / div;
 490}
 491
 492
 493static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
 494{
 495	u32 reg, div;
 496	unsigned long parent_rate;
 497	int i = 0;
 498
 499	parent_rate = clk_get_rate(clk->parent);
 500
 501	div = parent_rate / rate;
 502	if (div > 8 || div < 1 || ((parent_rate / div) != rate))
 503		return -EINVAL;
 504
 505	reg = __raw_readl(MXC_CCM_CBCDR);
 506	reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
 507	reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
 508	__raw_writel(reg, MXC_CCM_CBCDR);
 509
 510	/* Wait for lock */
 511	do {
 512		reg = __raw_readl(MXC_CCM_CDHIPR);
 513		if (!(reg & MXC_CCM_CDHIPR_AHB_PODF_BUSY))
 514			break;
 515
 516		udelay(1);
 517	} while (++i < MAX_DPLL_WAIT_TRIES);
 518
 519	if (i == MAX_DPLL_WAIT_TRIES) {
 520		pr_err("MX5: clk_ahb_set_rate failed\n");
 521		return -EINVAL;
 522	}
 523
 524	return 0;
 525}
 526
 527static unsigned long _clk_ahb_round_rate(struct clk *clk,
 528						unsigned long rate)
 529{
 530	u32 div;
 531	unsigned long parent_rate;
 532
 533	parent_rate = clk_get_rate(clk->parent);
 534
 535	div = parent_rate / rate;
 536	if (div > 8)
 537		div = 8;
 538	else if (div == 0)
 539		div++;
 540	return parent_rate / div;
 541}
 542
 543
 544static int _clk_max_enable(struct clk *clk)
 545{
 546	u32 reg;
 547
 548	_clk_ccgr_enable(clk);
 549
 550	/* Handshake with MAX when LPM is entered. */
 551	reg = __raw_readl(MXC_CCM_CLPCR);
 552	if (cpu_is_mx51())
 553		reg &= ~MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS;
 554	else if (cpu_is_mx53())
 555		reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS;
 556	__raw_writel(reg, MXC_CCM_CLPCR);
 557
 558	return 0;
 559}
 560
 561static void _clk_max_disable(struct clk *clk)
 562{
 563	u32 reg;
 564
 565	_clk_ccgr_disable_inwait(clk);
 566
 567	/* No Handshake with MAX when LPM is entered as its disabled. */
 568	reg = __raw_readl(MXC_CCM_CLPCR);
 569	if (cpu_is_mx51())
 570		reg |= MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS;
 571	else if (cpu_is_mx53())
 572		reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS;
 573	__raw_writel(reg, MXC_CCM_CLPCR);
 574}
 575
 576static unsigned long clk_ipg_get_rate(struct clk *clk)
 577{
 578	u32 reg, div;
 579	unsigned long parent_rate;
 580
 581	parent_rate = clk_get_rate(clk->parent);
 582
 583	reg = __raw_readl(MXC_CCM_CBCDR);
 584	div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
 585	       MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
 586
 587	return parent_rate / div;
 588}
 589
 590static unsigned long clk_ipg_per_get_rate(struct clk *clk)
 591{
 592	u32 reg, prediv1, prediv2, podf;
 593	unsigned long parent_rate;
 594
 595	parent_rate = clk_get_rate(clk->parent);
 596
 597	if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
 598		/* the main_bus_clk is the one before the DVFS engine */
 599		reg = __raw_readl(MXC_CCM_CBCDR);
 600		prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
 601			   MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1;
 602		prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
 603			   MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1;
 604		podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
 605			MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1;
 606		return parent_rate / (prediv1 * prediv2 * podf);
 607	} else if (clk->parent == &ipg_clk)
 608		return parent_rate;
 609	else
 610		BUG();
 611}
 612
 613static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
 614{
 615	u32 reg;
 616
 617	reg = __raw_readl(MXC_CCM_CBCMR);
 618
 619	reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
 620	reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
 621
 622	if (parent == &ipg_clk)
 623		reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
 624	else if (parent == &lp_apm_clk)
 625		reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
 626	else if (parent != &main_bus_clk)
 627		return -EINVAL;
 628
 629	__raw_writel(reg, MXC_CCM_CBCMR);
 630
 631	return 0;
 632}
 633
 634#define clk_nfc_set_parent	NULL
 635
 636static unsigned long clk_nfc_get_rate(struct clk *clk)
 637{
 638	unsigned long rate;
 639	u32 reg, div;
 640
 641	reg = __raw_readl(MXC_CCM_CBCDR);
 642	div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >>
 643	       MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1;
 644	rate = clk_get_rate(clk->parent) / div;
 645	WARN_ON(rate == 0);
 646	return rate;
 647}
 648
 649static unsigned long clk_nfc_round_rate(struct clk *clk,
 650						unsigned long rate)
 651{
 652	u32 div;
 653	unsigned long parent_rate = clk_get_rate(clk->parent);
 654
 655	if (!rate)
 656		return -EINVAL;
 657
 658	div = parent_rate / rate;
 659
 660	if (parent_rate % rate)
 661		div++;
 662
 663	if (div > 8)
 664		return -EINVAL;
 665
 666	return parent_rate / div;
 667
 668}
 669
 670static int clk_nfc_set_rate(struct clk *clk, unsigned long rate)
 671{
 672	u32 reg, div;
 673
 674	div = clk_get_rate(clk->parent) / rate;
 675	if (div == 0)
 676		div++;
 677	if (((clk_get_rate(clk->parent) / div) != rate) || (div > 8))
 678		return -EINVAL;
 679
 680	reg = __raw_readl(MXC_CCM_CBCDR);
 681	reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK;
 682	reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET;
 683	__raw_writel(reg, MXC_CCM_CBCDR);
 684
 685	while (__raw_readl(MXC_CCM_CDHIPR) &
 686			MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY){
 687	}
 688
 689	return 0;
 690}
 691
 692static unsigned long get_high_reference_clock_rate(struct clk *clk)
 693{
 694	return external_high_reference;
 695}
 696
 697static unsigned long get_low_reference_clock_rate(struct clk *clk)
 698{
 699	return external_low_reference;
 700}
 701
 702static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
 703{
 704	return oscillator_reference;
 705}
 706
 707static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
 708{
 709	return ckih2_reference;
 710}
 711
 712static unsigned long clk_emi_slow_get_rate(struct clk *clk)
 713{
 714	u32 reg, div;
 715
 716	reg = __raw_readl(MXC_CCM_CBCDR);
 717	div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >>
 718	       MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1;
 719
 720	return clk_get_rate(clk->parent) / div;
 721}
 722
 723static unsigned long _clk_ddr_hf_get_rate(struct clk *clk)
 724{
 725	unsigned long rate;
 726	u32 reg, div;
 727
 728	reg = __raw_readl(MXC_CCM_CBCDR);
 729	div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >>
 730		MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1;
 731	rate = clk_get_rate(clk->parent) / div;
 732
 733	return rate;
 734}
 735
 736/* External high frequency clock */
 737static struct clk ckih_clk = {
 738	.get_rate = get_high_reference_clock_rate,
 739};
 740
 741static struct clk ckih2_clk = {
 742	.get_rate = get_ckih2_reference_clock_rate,
 743};
 744
 745static struct clk osc_clk = {
 746	.get_rate = get_oscillator_reference_clock_rate,
 747};
 748
 749/* External low frequency (32kHz) clock */
 750static struct clk ckil_clk = {
 751	.get_rate = get_low_reference_clock_rate,
 752};
 753
 754static struct clk pll1_main_clk = {
 755	.parent = &osc_clk,
 756	.get_rate = clk_pll_get_rate,
 757	.enable = _clk_pll_enable,
 758	.disable = _clk_pll_disable,
 759};
 760
 761/* Clock tree block diagram (WIP):
 762 * 	CCM: Clock Controller Module
 763 *
 764 * PLL output -> |
 765 *               | CCM Switcher -> CCM_CLK_ROOT_GEN ->
 766 * PLL bypass -> |
 767 *
 768 */
 769
 770/* PLL1 SW supplies to ARM core */
 771static struct clk pll1_sw_clk = {
 772	.parent = &pll1_main_clk,
 773	.set_parent = _clk_pll1_sw_set_parent,
 774	.get_rate = clk_pll1_sw_get_rate,
 775};
 776
 777/* PLL2 SW supplies to AXI/AHB/IP buses */
 778static struct clk pll2_sw_clk = {
 779	.parent = &osc_clk,
 780	.get_rate = clk_pll_get_rate,
 781	.set_rate = _clk_pll_set_rate,
 782	.set_parent = _clk_pll2_sw_set_parent,
 783	.enable = _clk_pll_enable,
 784	.disable = _clk_pll_disable,
 785};
 786
 787/* PLL3 SW supplies to serial clocks like USB, SSI, etc. */
 788static struct clk pll3_sw_clk = {
 789	.parent = &osc_clk,
 790	.set_rate = _clk_pll_set_rate,
 791	.get_rate = clk_pll_get_rate,
 792	.enable = _clk_pll_enable,
 793	.disable = _clk_pll_disable,
 794};
 795
 796/* PLL4 SW supplies to LVDS Display Bridge(LDB) */
 797static struct clk mx53_pll4_sw_clk = {
 798	.parent = &osc_clk,
 799	.set_rate = _clk_pll_set_rate,
 800	.enable = _clk_pll_enable,
 801	.disable = _clk_pll_disable,
 802};
 803
 804/* Low-power Audio Playback Mode clock */
 805static struct clk lp_apm_clk = {
 806	.parent = &osc_clk,
 807	.set_parent = _clk_lp_apm_set_parent,
 808};
 809
 810static struct clk periph_apm_clk = {
 811	.parent = &pll1_sw_clk,
 812	.set_parent = _clk_periph_apm_set_parent,
 813};
 814
 815static struct clk cpu_clk = {
 816	.parent = &pll1_sw_clk,
 817	.get_rate = clk_cpu_get_rate,
 818	.set_rate = clk_cpu_set_rate,
 819};
 820
 821static struct clk ahb_clk = {
 822	.parent = &main_bus_clk,
 823	.get_rate = clk_ahb_get_rate,
 824	.set_rate = _clk_ahb_set_rate,
 825	.round_rate = _clk_ahb_round_rate,
 826};
 827
 828static struct clk iim_clk = {
 829	.parent = &ipg_clk,
 830	.enable_reg = MXC_CCM_CCGR0,
 831	.enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
 832};
 833
 834/* Main IP interface clock for access to registers */
 835static struct clk ipg_clk = {
 836	.parent = &ahb_clk,
 837	.get_rate = clk_ipg_get_rate,
 838};
 839
 840static struct clk ipg_perclk = {
 841	.parent = &lp_apm_clk,
 842	.get_rate = clk_ipg_per_get_rate,
 843	.set_parent = _clk_ipg_per_set_parent,
 844};
 845
 846static struct clk ahb_max_clk = {
 847	.parent = &ahb_clk,
 848	.enable_reg = MXC_CCM_CCGR0,
 849	.enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
 850	.enable = _clk_max_enable,
 851	.disable = _clk_max_disable,
 852};
 853
 854static struct clk aips_tz1_clk = {
 855	.parent = &ahb_clk,
 856	.secondary = &ahb_max_clk,
 857	.enable_reg = MXC_CCM_CCGR0,
 858	.enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
 859	.enable = _clk_ccgr_enable,
 860	.disable = _clk_ccgr_disable_inwait,
 861};
 862
 863static struct clk aips_tz2_clk = {
 864	.parent = &ahb_clk,
 865	.secondary = &ahb_max_clk,
 866	.enable_reg = MXC_CCM_CCGR0,
 867	.enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
 868	.enable = _clk_ccgr_enable,
 869	.disable = _clk_ccgr_disable_inwait,
 870};
 871
 872static struct clk gpc_dvfs_clk = {
 873	.enable_reg = MXC_CCM_CCGR5,
 874	.enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
 875	.enable = _clk_ccgr_enable,
 876	.disable = _clk_ccgr_disable,
 877};
 878
 879static struct clk gpt_32k_clk = {
 880	.id = 0,
 881	.parent = &ckil_clk,
 882};
 883
 884static struct clk dummy_clk = {
 885	.id = 0,
 886};
 887
 888static struct clk emi_slow_clk = {
 889	.parent = &pll2_sw_clk,
 890	.enable_reg = MXC_CCM_CCGR5,
 891	.enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
 892	.enable = _clk_ccgr_enable,
 893	.disable = _clk_ccgr_disable_inwait,
 894	.get_rate = clk_emi_slow_get_rate,
 895};
 896
 897static int clk_ipu_enable(struct clk *clk)
 898{
 899	u32 reg;
 900
 901	_clk_ccgr_enable(clk);
 902
 903	/* Enable handshake with IPU when certain clock rates are changed */
 904	reg = __raw_readl(MXC_CCM_CCDR);
 905	reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
 906	__raw_writel(reg, MXC_CCM_CCDR);
 907
 908	/* Enable handshake with IPU when LPM is entered */
 909	reg = __raw_readl(MXC_CCM_CLPCR);
 910	reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
 911	__raw_writel(reg, MXC_CCM_CLPCR);
 912
 913	return 0;
 914}
 915
 916static void clk_ipu_disable(struct clk *clk)
 917{
 918	u32 reg;
 919
 920	_clk_ccgr_disable(clk);
 921
 922	/* Disable handshake with IPU whe dividers are changed */
 923	reg = __raw_readl(MXC_CCM_CCDR);
 924	reg |= MXC_CCM_CCDR_IPU_HS_MASK;
 925	__raw_writel(reg, MXC_CCM_CCDR);
 926
 927	/* Disable handshake with IPU when LPM is entered */
 928	reg = __raw_readl(MXC_CCM_CLPCR);
 929	reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
 930	__raw_writel(reg, MXC_CCM_CLPCR);
 931}
 932
 933static struct clk ahbmux1_clk = {
 934	.parent = &ahb_clk,
 935	.secondary = &ahb_max_clk,
 936	.enable_reg = MXC_CCM_CCGR0,
 937	.enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
 938	.enable = _clk_ccgr_enable,
 939	.disable = _clk_ccgr_disable_inwait,
 940};
 941
 942static struct clk ipu_sec_clk = {
 943	.parent = &emi_fast_clk,
 944	.secondary = &ahbmux1_clk,
 945};
 946
 947static struct clk ddr_hf_clk = {
 948	.parent = &pll1_sw_clk,
 949	.get_rate = _clk_ddr_hf_get_rate,
 950};
 951
 952static struct clk ddr_clk = {
 953	.parent = &ddr_hf_clk,
 954};
 955
 956/* clock definitions for MIPI HSC unit which has been removed
 957 * from documentation, but not from hardware
 958 */
 959static int _clk_hsc_enable(struct clk *clk)
 960{
 961	u32 reg;
 962
 963	_clk_ccgr_enable(clk);
 964	/* Handshake with IPU when certain clock rates are changed. */
 965	reg = __raw_readl(MXC_CCM_CCDR);
 966	reg &= ~MXC_CCM_CCDR_HSC_HS_MASK;
 967	__raw_writel(reg, MXC_CCM_CCDR);
 968
 969	reg = __raw_readl(MXC_CCM_CLPCR);
 970	reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
 971	__raw_writel(reg, MXC_CCM_CLPCR);
 972
 973	return 0;
 974}
 975
 976static void _clk_hsc_disable(struct clk *clk)
 977{
 978	u32 reg;
 979
 980	_clk_ccgr_disable(clk);
 981	/* No handshake with HSC as its not enabled. */
 982	reg = __raw_readl(MXC_CCM_CCDR);
 983	reg |= MXC_CCM_CCDR_HSC_HS_MASK;
 984	__raw_writel(reg, MXC_CCM_CCDR);
 985
 986	reg = __raw_readl(MXC_CCM_CLPCR);
 987	reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
 988	__raw_writel(reg, MXC_CCM_CLPCR);
 989}
 990
 991static struct clk mipi_hsp_clk = {
 992	.parent = &ipu_clk,
 993	.enable_reg = MXC_CCM_CCGR4,
 994	.enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
 995	.enable = _clk_hsc_enable,
 996	.disable = _clk_hsc_disable,
 997	.secondary = &mipi_hsc1_clk,
 998};
 999
1000#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s)	\
1001	static struct clk name = {			\
1002		.id		= i,			\
1003		.enable_reg	= er,			\
1004		.enable_shift	= es,			\
1005		.get_rate	= pfx##_get_rate,	\
1006		.set_rate	= pfx##_set_rate,	\
1007		.round_rate	= pfx##_round_rate,	\
1008		.set_parent	= pfx##_set_parent,	\
1009		.enable		= _clk_ccgr_enable,	\
1010		.disable	= _clk_ccgr_disable,	\
1011		.parent		= p,			\
1012		.secondary	= s,			\
1013	}
1014
1015#define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s)	\
1016	static struct clk name = {			\
1017		.id		= i,			\
1018		.enable_reg	= er,			\
1019		.enable_shift	= es,			\
1020		.get_rate	= pfx##_get_rate,	\
1021		.set_rate	= pfx##_set_rate,	\
1022		.set_parent	= pfx##_set_parent,	\
1023		.enable		= _clk_max_enable,	\
1024		.disable	= _clk_max_disable,	\
1025		.parent		= p,			\
1026		.secondary	= s,			\
1027	}
1028
1029#define CLK_GET_RATE(name, nr, bitsname)				\
1030static unsigned long clk_##name##_get_rate(struct clk *clk)		\
1031{									\
1032	u32 reg, pred, podf;						\
1033									\
1034	reg = __raw_readl(MXC_CCM_CSCDR##nr);				\
1035	pred = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK)	\
1036		>> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET;	\
1037	podf = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK)	\
1038		>> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET;	\
1039									\
1040	return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent),		\
1041			(pred + 1) * (podf + 1));			\
1042}
1043
1044#define CLK_SET_PARENT(name, nr, bitsname)				\
1045static int clk_##name##_set_parent(struct clk *clk, struct clk *parent)	\
1046{									\
1047	u32 reg, mux;							\
1048									\
1049	mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk,		\
1050			&pll3_sw_clk, &lp_apm_clk);			\
1051	reg = __raw_readl(MXC_CCM_CSCMR##nr) &				\
1052		~MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_MASK;		\
1053	reg |= mux << MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_OFFSET;	\
1054	__raw_writel(reg, MXC_CCM_CSCMR##nr);				\
1055									\
1056	return 0;							\
1057}
1058
1059#define CLK_SET_RATE(name, nr, bitsname)				\
1060static int clk_##name##_set_rate(struct clk *clk, unsigned long rate)	\
1061{									\
1062	u32 reg, div, parent_rate;					\
1063	u32 pre = 0, post = 0;						\
1064									\
1065	parent_rate = clk_get_rate(clk->parent);			\
1066	div = parent_rate / rate;					\
1067									\
1068	if ((parent_rate / div) != rate)				\
1069		return -EINVAL;						\
1070									\
1071	__calc_pre_post_dividers(div, &pre, &post,			\
1072		(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK >>	\
1073		MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET) + 1,	\
1074		(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK >>	\
1075		MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET) + 1);\
1076									\
1077	/* Set sdhc1 clock divider */					\
1078	reg = __raw_readl(MXC_CCM_CSCDR##nr) &				\
1079		~(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK	\
1080		| MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK);	\
1081	reg |= (post - 1) <<						\
1082		MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET;	\
1083	reg |= (pre - 1) <<						\
1084		MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET;	\
1085	__raw_writel(reg, MXC_CCM_CSCDR##nr);				\
1086									\
1087	return 0;							\
1088}
1089
1090/* UART */
1091CLK_GET_RATE(uart, 1, UART)
1092CLK_SET_PARENT(uart, 1, UART)
1093
1094static struct clk uart_root_clk = {
1095	.parent = &pll2_sw_clk,
1096	.get_rate = clk_uart_get_rate,
1097	.set_parent = clk_uart_set_parent,
1098};
1099
1100/* USBOH3 */
1101CLK_GET_RATE(usboh3, 1, USBOH3)
1102CLK_SET_PARENT(usboh3, 1, USBOH3)
1103
1104static struct clk usboh3_clk = {
1105	.parent = &pll2_sw_clk,
1106	.get_rate = clk_usboh3_get_rate,
1107	.set_parent = clk_usboh3_set_parent,
1108	.enable = _clk_ccgr_enable,
1109	.disable = _clk_ccgr_disable,
1110	.enable_reg = MXC_CCM_CCGR2,
1111	.enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
1112};
1113
1114static struct clk usb_ahb_clk = {
1115	.parent = &ipg_clk,
1116	.enable = _clk_ccgr_enable,
1117	.disable = _clk_ccgr_disable,
1118	.enable_reg = MXC_CCM_CCGR2,
1119	.enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
1120};
1121
1122static int clk_usb_phy1_set_parent(struct clk *clk, struct clk *parent)
1123{
1124	u32 reg;
1125
1126	reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
1127
1128	if (parent == &pll3_sw_clk)
1129		reg |= 1 << MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET;
1130
1131	__raw_writel(reg, MXC_CCM_CSCMR1);
1132
1133	return 0;
1134}
1135
1136static struct clk usb_phy1_clk = {
1137	.parent = &pll3_sw_clk,
1138	.set_parent = clk_usb_phy1_set_parent,
1139	.enable = _clk_ccgr_enable,
1140	.enable_reg = MXC_CCM_CCGR2,
1141	.enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
1142	.disable = _clk_ccgr_disable,
1143};
1144
1145/* eCSPI */
1146CLK_GET_RATE(ecspi, 2, CSPI)
1147CLK_SET_PARENT(ecspi, 1, CSPI)
1148
1149static struct clk ecspi_main_clk = {
1150	.parent = &pll3_sw_clk,
1151	.get_rate = clk_ecspi_get_rate,
1152	.set_parent = clk_ecspi_set_parent,
1153};
1154
1155/* eSDHC */
1156CLK_GET_RATE(esdhc1, 1, ESDHC1_MSHC1)
1157CLK_SET_PARENT(esdhc1, 1, ESDHC1_MSHC1)
1158CLK_SET_RATE(esdhc1, 1, ESDHC1_MSHC1)
1159
1160/* mx51 specific */
1161CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2)
1162CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2)
1163CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2)
1164
1165static int clk_esdhc3_set_parent(struct clk *clk, struct clk *parent)
1166{
1167	u32 reg;
1168
1169	reg = __raw_readl(MXC_CCM_CSCMR1);
1170	if (parent == &esdhc1_clk)
1171		reg &= ~MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
1172	else if (parent == &esdhc2_clk)
1173		reg |= MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
1174	else
1175		return -EINVAL;
1176	__raw_writel(reg, MXC_CCM_CSCMR1);
1177
1178	return 0;
1179}
1180
1181static int clk_esdhc4_set_parent(struct clk *clk, struct clk *parent)
1182{
1183	u32 reg;
1184
1185	reg = __raw_readl(MXC_CCM_CSCMR1);
1186	if (parent == &esdhc1_clk)
1187		reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
1188	else if (parent == &esdhc2_clk)
1189		reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
1190	else
1191		return -EINVAL;
1192	__raw_writel(reg, MXC_CCM_CSCMR1);
1193
1194	return 0;
1195}
1196
1197/* mx53 specific */
1198static int clk_esdhc2_mx53_set_parent(struct clk *clk, struct clk *parent)
1199{
1200	u32 reg;
1201
1202	reg = __raw_readl(MXC_CCM_CSCMR1);
1203	if (parent == &esdhc1_clk)
1204		reg &= ~MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL;
1205	else if (parent == &esdhc3_mx53_clk)
1206		reg |= MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL;
1207	else
1208		return -EINVAL;
1209	__raw_writel(reg, MXC_CCM_CSCMR1);
1210
1211	return 0;
1212}
1213
1214CLK_GET_RATE(esdhc3_mx53, 1, ESDHC3_MX53)
1215CLK_SET_PARENT(esdhc3_mx53, 1, ESDHC3_MX53)
1216CLK_SET_RATE(esdhc3_mx53, 1, ESDHC3_MX53)
1217
1218static int clk_esdhc4_mx53_set_parent(struct clk *clk, struct clk *parent)
1219{
1220	u32 reg;
1221
1222	reg = __raw_readl(MXC_CCM_CSCMR1);
1223	if (parent == &esdhc1_clk)
1224		reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
1225	else if (parent == &esdhc3_mx53_clk)
1226		reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
1227	else
1228		return -EINVAL;
1229	__raw_writel(reg, MXC_CCM_CSCMR1);
1230
1231	return 0;
1232}
1233
1234#define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s)		\
1235	static struct clk name = {					\
1236		.id		= i,					\
1237		.enable_reg	= er,					\
1238		.enable_shift	= es,					\
1239		.get_rate	= gr,					\
1240		.set_rate	= sr,					\
1241		.enable		= e,					\
1242		.disable	= d,					\
1243		.parent		= p,					\
1244		.secondary	= s,					\
1245	}
1246
1247#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s)			\
1248	DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, _clk_ccgr_enable, _clk_ccgr_disable, p, s)
1249
1250/* Shared peripheral bus arbiter */
1251DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET,
1252	NULL,  NULL, &ipg_clk, NULL);
1253
1254/* UART */
1255DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET,
1256	NULL,  NULL, &ipg_clk, &aips_tz1_clk);
1257DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET,
1258	NULL,  NULL, &ipg_clk, &aips_tz1_clk);
1259DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
1260	NULL,  NULL, &ipg_clk, &spba_clk);
1261DEFINE_CLOCK(uart4_ipg_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG4_OFFSET,
1262	NULL,  NULL, &ipg_clk, &spba_clk);
1263DEFINE_CLOCK(uart5_ipg_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG6_OFFSET,
1264	NULL,  NULL, &ipg_clk, &spba_clk);
1265DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
1266	NULL,  NULL, &uart_root_clk, &uart1_ipg_clk);
1267DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
1268	NULL,  NULL, &uart_root_clk, &uart2_ipg_clk);
1269DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
1270	NULL,  NULL, &uart_root_clk, &uart3_ipg_clk);
1271DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG5_OFFSET,
1272	NULL,  NULL, &uart_root_clk, &uart4_ipg_clk);
1273DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG7_OFFSET,
1274	NULL,  NULL, &uart_root_clk, &uart5_ipg_clk);
1275
1276/* GPT */
1277DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
1278	NULL,  NULL, &ipg_clk, NULL);
1279DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
1280	NULL,  NULL, &ipg_clk, &gpt_ipg_clk);
1281
1282DEFINE_CLOCK(pwm1_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG6_OFFSET,
1283	NULL, NULL, &ipg_clk, NULL);
1284DEFINE_CLOCK(pwm2_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG8_OFFSET,
1285	NULL, NULL, &ipg_clk, NULL);
1286
1287/* I2C */
1288DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET,
1289	NULL, NULL, &ipg_perclk, NULL);
1290DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG10_OFFSET,
1291	NULL, NULL, &ipg_perclk, NULL);
1292DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET,
1293	NULL, NULL, &ipg_clk, NULL);
1294DEFINE_CLOCK(i2c3_mx53_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET,
1295	NULL, NULL, &ipg_perclk, NULL);
1296
1297/* FEC */
1298DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
1299	NULL,  NULL, &ipg_clk, NULL);
1300
1301/* NFC */
1302DEFINE_CLOCK_CCGR(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET,
1303	clk_nfc, &emi_slow_clk, NULL);
1304
1305/* SSI */
1306DEFINE_CLOCK(ssi1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG8_OFFSET,
1307	NULL, NULL, &ipg_clk, NULL);
1308DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG9_OFFSET,
1309	NULL, NULL, &pll3_sw_clk, &ssi1_ipg_clk);
1310DEFINE_CLOCK(ssi2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG10_OFFSET,
1311	NULL, NULL, &ipg_clk, NULL);
1312DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG11_OFFSET,
1313	NULL, NULL, &pll3_sw_clk, &ssi2_ipg_clk);
1314DEFINE_CLOCK(ssi3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG12_OFFSET,
1315	NULL, NULL, &ipg_clk, NULL);
1316DEFINE_CLOCK(ssi3_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG13_OFFSET,
1317	NULL, NULL, &pll3_sw_clk, &ssi3_ipg_clk);
1318
1319/* eCSPI */
1320DEFINE_CLOCK_FULL(ecspi1_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
1321		NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
1322		&ipg_clk, &spba_clk);
1323DEFINE_CLOCK(ecspi1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG10_OFFSET,
1324		NULL, NULL, &ecspi_main_clk, &ecspi1_ipg_clk);
1325DEFINE_CLOCK_FULL(ecspi2_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG11_OFFSET,
1326		NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
1327		&ipg_clk, &aips_tz2_clk);
1328DEFINE_CLOCK(ecspi2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG12_OFFSET,
1329		NULL, NULL, &ecspi_main_clk, &ecspi2_ipg_clk);
1330
1331/* CSPI */
1332DEFINE_CLOCK(cspi_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
1333		NULL, NULL, &ipg_clk, &aips_tz2_clk);
1334DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET,
1335		NULL, NULL, &ipg_clk, &cspi_ipg_clk);
1336
1337/* SDMA */
1338DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET,
1339		NULL, NULL, &ahb_clk, NULL);
1340
1341/* eSDHC */
1342DEFINE_CLOCK_FULL(esdhc1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG0_OFFSET,
1343	NULL,  NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
1344DEFINE_CLOCK_MAX(esdhc1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG1_OFFSET,
1345	clk_esdhc1, &pll2_sw_clk, &esdhc1_ipg_clk);
1346DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET,
1347	NULL,  NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
1348DEFINE_CLOCK_FULL(esdhc3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG4_OFFSET,
1349	NULL,  NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
1350DEFINE_CLOCK_FULL(esdhc4_ipg_clk, 3, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG6_OFFSET,
1351	NULL,  NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
1352
1353/* mx51 specific */
1354DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET,
1355	clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk);
1356
1357static struct clk esdhc3_clk = {
1358	.id = 2,
1359	.parent = &esdhc1_clk,
1360	.set_parent = clk_esdhc3_set_parent,
1361	.enable_reg = MXC_CCM_CCGR3,
1362	.enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
1363	.enable  = _clk_max_enable,
1364	.disable = _clk_max_disable,
1365	.secondary = &esdhc3_ipg_clk,
1366};
1367static struct clk esdhc4_clk = {
1368	.id = 3,
1369	.parent = &esdhc1_clk,
1370	.set_parent = clk_esdhc4_set_parent,
1371	.enable_reg = MXC_CCM_CCGR3,
1372	.enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
1373	.enable  = _clk_max_enable,
1374	.disable = _clk_max_disable,
1375	.secondary = &esdhc4_ipg_clk,
1376};
1377
1378/* mx53 specific */
1379static struct clk esdhc2_mx53_clk = {
1380	.id = 2,
1381	.parent = &esdhc1_clk,
1382	.set_parent = clk_esdhc2_mx53_set_parent,
1383	.enable_reg = MXC_CCM_CCGR3,
1384	.enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
1385	.enable  = _clk_max_enable,
1386	.disable = _clk_max_disable,
1387	.secondary = &esdhc3_ipg_clk,
1388};
1389
1390DEFINE_CLOCK_MAX(esdhc3_mx53_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG5_OFFSET,
1391	clk_esdhc3_mx53, &pll2_sw_clk, &esdhc2_ipg_clk);
1392
1393static struct clk esdhc4_mx53_clk = {
1394	.id = 3,
1395	.parent = &esdhc1_clk,
1396	.set_parent = clk_esdhc4_mx53_set_parent,
1397	.enable_reg = MXC_CCM_CCGR3,
1398	.enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
1399	.enable  = _clk_max_enable,
1400	.disable = _clk_max_disable,
1401	.secondary = &esdhc4_ipg_clk,
1402};
1403
1404DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk);
1405DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk);
1406DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk);
1407
1408/* IPU */
1409DEFINE_CLOCK_FULL(ipu_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG5_OFFSET,
1410	NULL,  NULL, clk_ipu_enable, clk_ipu_disable, &ahb_clk, &ipu_sec_clk);
1411
1412DEFINE_CLOCK_FULL(emi_fast_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG7_OFFSET,
1413		NULL, NULL, _clk_ccgr_enable, _clk_ccgr_disable_inwait,
1414		&ddr_clk, NULL);
1415
1416DEFINE_CLOCK(ipu_di0_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG5_OFFSET,
1417		NULL, NULL, &pll3_sw_clk, NULL);
1418DEFINE_CLOCK(ipu_di1_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG6_OFFSET,
1419		NULL, NULL, &pll3_sw_clk, NULL);
1420
1421#define _REGISTER_CLOCK(d, n, c) \
1422       { \
1423		.dev_id = d, \
1424		.con_id = n, \
1425		.clk = &c,   \
1426       },
1427
1428static struct clk_lookup mx51_lookups[] = {
1429	/* i.mx51 has the i.mx21 type uart */
1430	_REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
1431	_REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
1432	_REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
1433	_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
1434	/* i.mx51 has the i.mx27 type fec */
1435	_REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
1436	_REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk)
1437	_REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk)
1438	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
1439	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
1440	_REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk)
1441	_REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk)
1442	_REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_ahb_clk)
1443	_REGISTER_CLOCK("mxc-ehci.0", "usb_phy1", usb_phy1_clk)
1444	_REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk)
1445	_REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_ahb_clk)
1446	_REGISTER_CLOCK("mxc-ehci.2", "usb", usboh3_clk)
1447	_REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_ahb_clk)
1448	_REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk)
1449	_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk)
1450	_REGISTER_CLOCK("imx-keypad", NULL, dummy_clk)
1451	_REGISTER_CLOCK("mxc_nand", NULL, nfc_clk)
1452	_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
1453	_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
1454	_REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
1455	/* i.mx51 has the i.mx35 type sdma */
1456	_REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
1457	_REGISTER_CLOCK(NULL, "ckih", ckih_clk)
1458	_REGISTER_CLOCK(NULL, "ckih2", ckih2_clk)
1459	_REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk)
1460	_REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk)
1461	_REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk)
1462	/* i.mx51 has the i.mx35 type cspi */
1463	_REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk)
1464	_REGISTER_CLOCK("sdhci-esdhc-imx51.0", NULL, esdhc1_clk)
1465	_REGISTER_CLOCK("sdhci-esdhc-imx51.1", NULL, esdhc2_clk)
1466	_REGISTER_CLOCK("sdhci-esdhc-imx51.2", NULL, esdhc3_clk)
1467	_REGISTER_CLOCK("sdhci-esdhc-imx51.3", NULL, esdhc4_clk)
1468	_REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk)
1469	_REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
1470	_REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
1471	_REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk)
1472	_REGISTER_CLOCK(NULL, "mipi_hsp", mipi_hsp_clk)
1473	_REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk)
1474	_REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)
1475	_REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk)
1476	_REGISTER_CLOCK(NULL, "gpc_dvfs", gpc_dvfs_clk)
1477};
1478
1479static struct clk_lookup mx53_lookups[] = {
1480	/* i.mx53 has the i.mx21 type uart */
1481	_REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
1482	_REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
1483	_REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
1484	_REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
1485	_REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
1486	_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
1487	/* i.mx53 has the i.mx25 type fec */
1488	_REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk)
1489	_REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
1490	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
1491	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
1492	_REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_mx53_clk)
1493	/* i.mx53 has the i.mx51 type ecspi */
1494	_REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk)
1495	_REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk)
1496	/* i.mx53 has the i.mx25 type cspi */
1497	_REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk)
1498	_REGISTER_CLOCK("sdhci-esdhc-imx53.0", NULL, esdhc1_clk)
1499	_REGISTER_CLOCK("sdhci-esdhc-imx53.1", NULL, esdhc2_mx53_clk)
1500	_REGISTER_CLOCK("sdhci-esdhc-imx53.2", NULL, esdhc3_mx53_clk)
1501	_REGISTER_CLOCK("sdhci-esdhc-imx53.3", NULL, esdhc4_mx53_clk)
1502	_REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
1503	_REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk)
1504	/* i.mx53 has the i.mx35 type sdma */
1505	_REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
1506	_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
1507	_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
1508	_REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
1509	_REGISTER_CLOCK("imx-keypad", NULL, dummy_clk)
1510};
1511
1512static void clk_tree_init(void)
1513{
1514	u32 reg;
1515
1516	ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
1517
1518	/*
1519	 * Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
1520	 * 8MHz, its derived from lp_apm.
1521	 *
1522	 * FIXME: Verify if true for all boards
1523	 */
1524	reg = __raw_readl(MXC_CCM_CBCDR);
1525	reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
1526	reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
1527	reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
1528	reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
1529	__raw_writel(reg, MXC_CCM_CBCDR);
1530}
1531
1532int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
1533			unsigned long ckih1, unsigned long ckih2)
1534{
1535	int i;
1536
1537	external_low_reference = ckil;
1538	external_high_reference = ckih1;
1539	ckih2_reference = ckih2;
1540	oscillator_reference = osc;
1541
1542	for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++)
1543		clkdev_add(&mx51_lookups[i]);
1544
1545	clk_tree_init();
1546
1547	clk_enable(&cpu_clk);
1548	clk_enable(&main_bus_clk);
1549
1550	clk_enable(&iim_clk);
1551	mx51_revision();
1552	clk_disable(&iim_clk);
1553	mx51_display_revision();
1554
1555	/* move usb_phy_clk to 24MHz */
1556	clk_set_parent(&usb_phy1_clk, &osc_clk);
1557
1558	/* set the usboh3_clk parent to pll2_sw_clk */
1559	clk_set_parent(&usboh3_clk, &pll2_sw_clk);
1560
1561	/* Set SDHC parents to be PLL2 */
1562	clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
1563	clk_set_parent(&esdhc2_clk, &pll2_sw_clk);
1564
1565	/* set SDHC root clock as 166.25MHZ*/
1566	clk_set_rate(&esdhc1_clk, 166250000);
1567	clk_set_rate(&esdhc2_clk, 166250000);
1568
1569	/* System timer */
1570	mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
1571		MX51_MXC_INT_GPT);
1572	return 0;
1573}
1574
1575int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
1576			unsigned long ckih1, unsigned long ckih2)
1577{
1578	int i;
1579
1580	external_low_reference = ckil;
1581	external_high_reference = ckih1;
1582	ckih2_reference = ckih2;
1583	oscillator_reference = osc;
1584
1585	for (i = 0; i < ARRAY_SIZE(mx53_lookups); i++)
1586		clkdev_add(&mx53_lookups[i]);
1587
1588	clk_tree_init();
1589
1590	clk_set_parent(&uart_root_clk, &pll3_sw_clk);
1591	clk_enable(&cpu_clk);
1592	clk_enable(&main_bus_clk);
1593
1594	clk_enable(&iim_clk);
1595	mx53_revision();
1596	clk_disable(&iim_clk);
1597	mx53_display_revision();
1598
1599	/* Set SDHC parents to be PLL2 */
1600	clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
1601	clk_set_parent(&esdhc3_mx53_clk, &pll2_sw_clk);
1602
1603	/* set SDHC root clock as 200MHZ*/
1604	clk_set_rate(&esdhc1_clk, 200000000);
1605	clk_set_rate(&esdhc3_mx53_clk, 200000000);
1606
1607	/* System timer */
1608	mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
1609		MX53_INT_GPT);
1610	return 0;
1611}