From patchwork Wed Dec 14 09:23:57 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Zhao X-Patchwork-Id: 5683 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 4BFC123E10 for ; Wed, 14 Dec 2011 09:27:13 +0000 (UTC) Received: from mail-ey0-f180.google.com (mail-ey0-f180.google.com [209.85.215.180]) by fiordland.canonical.com (Postfix) with ESMTP id 35226A183DF for ; Wed, 14 Dec 2011 09:27:13 +0000 (UTC) Received: by eaak10 with SMTP id k10so261856eaa.11 for ; Wed, 14 Dec 2011 01:27:13 -0800 (PST) Received: by 10.204.156.208 with SMTP id y16mr387963bkw.72.1323854832954; Wed, 14 Dec 2011 01:27:12 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.205.129.2 with SMTP id hg2cs2801bkc; Wed, 14 Dec 2011 01:27:12 -0800 (PST) Received: by 10.236.129.202 with SMTP id h50mr10641939yhi.1.1323854830723; Wed, 14 Dec 2011 01:27:10 -0800 (PST) Received: from TX2EHSOBE009.bigfish.com (tx2ehsobe004.messaging.microsoft.com. [65.55.88.14]) by mx.google.com with ESMTPS id l30si1566590yhm.136.2011.12.14.01.27.09 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 14 Dec 2011 01:27:10 -0800 (PST) Received-SPF: neutral (google.com: 65.55.88.14 is neither permitted nor denied by best guess record for domain of richard.zhao@linaro.org) client-ip=65.55.88.14; Authentication-Results: mx.google.com; spf=neutral (google.com: 65.55.88.14 is neither permitted nor denied by best guess record for domain of richard.zhao@linaro.org) smtp.mail=richard.zhao@linaro.org Received: from mail151-tx2-R.bigfish.com (10.9.14.243) by TX2EHSOBE009.bigfish.com (10.9.40.29) with Microsoft SMTP Server id 14.1.225.23; Wed, 14 Dec 2011 09:27:11 +0000 Received: from mail151-tx2 (localhost [127.0.0.1]) by mail151-tx2-R.bigfish.com (Postfix) with ESMTP id B8FD360026D; Wed, 14 Dec 2011 09:27:11 +0000 (UTC) X-SpamScore: 0 X-BigFish: VS0(zzzz1202hzz8275dhz2dh87h2a8h668h839h61h) X-Spam-TCS-SCL: 0:0 X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-FB-DOMAIN-IP-MATCH: fail Received: from mail151-tx2 (localhost.localdomain [127.0.0.1]) by mail151-tx2 (MessageSwitch) id 1323854672372881_24357; Wed, 14 Dec 2011 09:24:32 +0000 (UTC) Received: from TX2EHSMHS020.bigfish.com (unknown [10.9.14.239]) by mail151-tx2.bigfish.com (Postfix) with ESMTP id 4434C400048; Wed, 14 Dec 2011 09:24:32 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by TX2EHSMHS020.bigfish.com (10.9.99.120) with Microsoft SMTP Server (TLS) id 14.1.225.23; Wed, 14 Dec 2011 09:24:31 +0000 Received: from az33smr01.freescale.net (10.64.34.199) by 039-SN1MMR1-003.039d.mgd.msft.net (10.84.1.16) with Microsoft SMTP Server id 14.1.355.3; Wed, 14 Dec 2011 03:24:28 -0600 Received: from b20223-02.ap.freescale.net (b20223-02.ap.freescale.net [10.192.242.124]) by az33smr01.freescale.net (8.13.1/8.13.0) with ESMTP id pBE9O2Px004480; Wed, 14 Dec 2011 03:24:25 -0600 (CST) From: Richard Zhao To: CC: , , , , , , , Sascha Hauer Subject: [RFC V2 7/8] ARM i.MX51/53: reimplement clock support Date: Wed, 14 Dec 2011 17:23:57 +0800 Message-ID: <1323854638-3455-8-git-send-email-richard.zhao@linaro.org> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1323854638-3455-1-git-send-email-richard.zhao@linaro.org> References: <1323854638-3455-1-git-send-email-richard.zhao@linaro.org> MIME-Version: 1.0 X-OriginatorOrg: sigmatel.com Reimplement i.MX51/53 clock support. This is tested with a babbage board and a loco board up to the point that UARTs, FEC and USB work. There are surely bugs left in the code, but I found several in the old code while reimplementing it, so who cares... The implementation is mostly based on the datasheet and not the old code. Signed-off-by: Sascha Hauer Signed-off-by: Richard Zhao --- arch/arm/mach-mx5/Kconfig | 14 + arch/arm/mach-mx5/Makefile | 2 +- arch/arm/mach-mx5/clock-imx51-imx53.c | 640 ++++++++++++++++++++++++++++++++ arch/arm/plat-mxc/include/mach/clock.h | 3 + 4 files changed, 658 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-mx5/clock-imx51-imx53.c diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig index af0c212..924930b 100644 --- a/arch/arm/mach-mx5/Kconfig +++ b/arch/arm/mach-mx5/Kconfig @@ -31,6 +31,13 @@ config SOC_IMX51 select ARCH_MXC_AUDMUX_V2 select ARCH_HAS_CPUFREQ select ARCH_MX51 + select GENERIC_CLK + select GENERIC_CLK_FIXED + select GENERIC_CLK_DIVIDER + select GENERIC_CLK_MUX + select GENERIC_CLK_DUMMY + select IMX_CLK_PLLV2 + select IMX_CLK_GATE2B config SOC_IMX53 bool @@ -39,6 +46,13 @@ config SOC_IMX53 select MXC_TZIC select ARCH_MXC_IOMUX_V3 select ARCH_MX53 + select GENERIC_CLK + select GENERIC_CLK_FIXED + select GENERIC_CLK_DIVIDER + select GENERIC_CLK_MUX + select GENERIC_CLK_DUMMY + select IMX_CLK_PLLV2 + select IMX_CLK_GATE2B #comment "i.MX50 machines:" diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile index 0fc6080..b26438d 100644 --- a/arch/arm/mach-mx5/Makefile +++ b/arch/arm/mach-mx5/Makefile @@ -3,7 +3,7 @@ # # Object file lists. -obj-y := cpu.o mm.o clock-mx51-mx53.o ehci.o system.o +obj-y := cpu.o mm.o clock-imx51-imx53.o ehci.o system.o obj-$(CONFIG_PM) += pm-imx5.o obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o diff --git a/arch/arm/mach-mx5/clock-imx51-imx53.c b/arch/arm/mach-mx5/clock-imx51-imx53.c new file mode 100644 index 0000000..8b7a218 --- /dev/null +++ b/arch/arm/mach-mx5/clock-imx51-imx53.c @@ -0,0 +1,640 @@ +/* + * Copyright 2010 Sascha Hauer, Pengutronix + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "crm_regs.h" + +struct clk_dummy { + struct clk clk; +}; + +static struct clk_hw_ops dumy_ops; +static struct clk_dummy dummy = { + .clk = { + .name = "dummy", + .ops = &dumy_ops, + }, +}; + +static DEFINE_CLK_FIXED(ckil, 0); +static DEFINE_CLK_FIXED(osc, 0); +static DEFINE_CLK_FIXED(ckih1, 0); +static DEFINE_CLK_FIXED(ckih2, 0); + +static DEFINE_CLK_PLLV2(pll1, &osc.clk, MX51_DPLL1_BASE); +static DEFINE_CLK_PLLV2(pll2, &osc.clk, MX51_DPLL2_BASE); +static DEFINE_CLK_PLLV2(pll3, &osc.clk, MX51_DPLL3_BASE); +static DEFINE_CLK_PLLV2(pll4, &osc.clk, MX53_DPLL4_BASE); + +static struct clk_dummy dummy; + +/* Low-power Audio Playback Mode clock */ +static struct clk *lp_apm_sel[] = { + &osc.clk, + NULL, +}; +static IMX_DEFINE_CLK_MUX(lp_apm, MXC_CCM_CCSR, 9, 1, lp_apm_sel); + +static IMX_DEFINE_CLK_DIVIDER(step_pll2_div, &pll2.clk, 0, MXC_CCM_CCSR, 5, 2); + +static IMX_DEFINE_CLK_DIVIDER(step_pll3_div, &pll3.clk, 0, MXC_CCM_CCSR, 3, 2); + +static struct clk *step_clk_sel[] = { + &lp_apm.clk, + NULL, + &step_pll2_div.clk, + &step_pll3_div.clk, +}; +static IMX_DEFINE_CLK_MUX(step_clk, MXC_CCM_CCSR, 7, 2, step_clk_sel); + +static struct clk *pll1_sw_sel[] = { + &pll1.clk, + &step_clk.clk, +}; +static IMX_DEFINE_CLK_MUX(pll1_sw, MXC_CCM_CCSR, 2, 1, pll1_sw_sel); + +static struct clk *pll2_sw_sel[] = { + &pll2.clk, + NULL, +}; +static IMX_DEFINE_CLK_MUX(pll2_sw, MXC_CCM_CCSR, 1, 1, pll2_sw_sel); + +static struct clk *pll3_sw_sel[] = { + &pll3.clk, + NULL, +}; +static IMX_DEFINE_CLK_MUX(pll3_sw, MXC_CCM_CCSR, 0, 1, pll3_sw_sel); + +static struct clk *pll4_sw_sel[] = { + &pll4.clk, + NULL, +}; +static IMX_DEFINE_CLK_MUX(pll4_sw, MXC_CCM_CCSR, 9, 1, pll4_sw_sel); + + +/* This is used multiple times */ +static struct clk *standard_pll_sel_clks[] = { + &pll1_sw.clk, + &pll2_sw.clk, + &pll3_sw.clk, + &lp_apm.clk, +}; + +static struct clk *periph_apm_sel[] = { + &pll1_sw.clk, + &pll3_sw.clk, + &lp_apm.clk, +}; +static IMX_DEFINE_CLK_MUX(periph_apm, MXC_CCM_CBCMR, 12, 2, periph_apm_sel); + +static struct clk *main_bus_sel[] = { + &pll2_sw.clk, + &periph_apm.clk, +}; +static IMX_DEFINE_CLK_MUX(main_bus, MXC_CCM_CBCDR, 25, 1, main_bus_sel); + +static IMX_DEFINE_CLK_DIVIDER(ahb_root, &main_bus.clk, 0, MXC_CCM_CBCDR, 10, 3); +static IMX_DEFINE_CLK_DIVIDER(ipg, &ahb_root.clk, 0, MXC_CCM_CBCDR, 8, 2); + +static struct clk *perclk_lp_apm_sel[] = { + &main_bus.clk, + &lp_apm.clk, +}; +static IMX_DEFINE_CLK_MUX(perclk_lp_apm, MXC_CCM_CBCMR, 1, 1, perclk_lp_apm_sel); + +static IMX_DEFINE_CLK_DIVIDER(perclk_pred1, &perclk_lp_apm.clk, 0, MXC_CCM_CBCDR, 6, 2); +static IMX_DEFINE_CLK_DIVIDER(perclk_pred2, &perclk_pred1.clk, 0, MXC_CCM_CBCDR, 3, 3); +static IMX_DEFINE_CLK_DIVIDER(perclk_podf, &perclk_pred2.clk, CLK_PARENT_SET_RATE, MXC_CCM_CBCDR, 0, 3); + +static struct clk *ipg_perclk_sel[] = { + &perclk_podf.clk, + &ipg.clk, +}; +static IMX_DEFINE_CLK_MUX(ipg_perclk, MXC_CCM_CBCMR, 0, 1, ipg_perclk_sel); + +static IMX_DEFINE_CLK_DIVIDER(axi_a, &main_bus.clk, 0, MXC_CCM_CBCDR, 16, 3); +static IMX_DEFINE_CLK_DIVIDER(axi_b, &main_bus.clk, 0, MXC_CCM_CBCDR, 19, 3); + +static struct clk *emi_slow_sel_clks[] = { + &main_bus.clk, + &ahb_root.clk, +}; +static IMX_DEFINE_CLK_MUX(emi_sel, MXC_CCM_CBCDR, 26, 1, emi_slow_sel_clks); +static IMX_DEFINE_CLK_DIVIDER(emi_slow_podf, &emi_sel.clk, 0, MXC_CCM_CBCDR, 22, 3); +static IMX_DEFINE_CLK_DIVIDER(nfc_podf, &emi_slow_podf.clk, 0, MXC_CCM_CBCDR, 13, 3); + +static struct clk *xpu_sel[] = { + &axi_a.clk, + &axi_b.clk, + &emi_slow_podf.clk, + &ahb_root.clk, +}; +static IMX_DEFINE_CLK_MUX(gpu2d, MXC_CCM_CBCMR, 16, 2, xpu_sel); +static IMX_DEFINE_CLK_MUX(arm_axi, MXC_CCM_CBCMR, 8, 2, xpu_sel); +static IMX_DEFINE_CLK_MUX(ipu_hsp, MXC_CCM_CBCMR, 6, 2, xpu_sel); +static IMX_DEFINE_CLK_MUX(gpu, MXC_CCM_CBCMR, 4, 2, xpu_sel); +static IMX_DEFINE_CLK_MUX(vpu_axi_root, MXC_CCM_CBCMR, 14, 2, xpu_sel); +static IMX_DEFINE_CLK_MUX(ddr_root, MXC_CCM_CBCMR, 10, 2, xpu_sel); + +static IMX_DEFINE_CLK_DIVIDER(ddr_hf_mx51, &pll1_sw.clk, 0, MXC_CCM_CBCDR, 27, 3); +static struct clk *ddr_hf_sel[] = { + &ddr_root.clk, + &ddr_hf_mx51.clk, +}; +static IMX_DEFINE_CLK_MUX(ddr_root_mx51, MXC_CCM_CBCDR, 30, 1, ddr_hf_sel); + +static IMX_DEFINE_CLK_MUX(uart_sel, MXC_CCM_CSCMR1, 24, 2, standard_pll_sel_clks); +static IMX_DEFINE_CLK_DIVIDER(uart_pred, &uart_sel.clk, 0, MXC_CCM_CSCDR1, 3, 3); +static IMX_DEFINE_CLK_DIVIDER(uart_root, &uart_pred.clk, CLK_PARENT_SET_RATE, MXC_CCM_CSCDR1, 0, 3); + +static IMX_DEFINE_CLK_MUX(esdhc1_sel, MXC_CCM_CSCMR1, 20, 2, standard_pll_sel_clks); +static IMX_DEFINE_CLK_DIVIDER(esdhc1_pred, &esdhc1_sel.clk, 0, MXC_CCM_CSCDR1, 16, 3); +static IMX_DEFINE_CLK_DIVIDER(esdhc1_podf, &esdhc1_pred.clk, CLK_PARENT_SET_RATE, MXC_CCM_CSCDR1, 11, 3); + +/* This is routed to esdhc3 in the i.MX53 datasheet */ +static IMX_DEFINE_CLK_MUX(esdhc2_sel, MXC_CCM_CSCMR1, 16, 2, standard_pll_sel_clks); +static IMX_DEFINE_CLK_DIVIDER(esdhc2_pred, &esdhc2_sel.clk, 0, MXC_CCM_CSCDR1, 22, 3); +static IMX_DEFINE_CLK_DIVIDER(esdhc2_podf, &esdhc2_pred.clk, CLK_PARENT_SET_RATE, MXC_CCM_CSCDR1, 19, 3); + +static struct clk *esdhc3_sel_clks[] = { + &esdhc1_podf.clk, + &esdhc2_podf.clk, +}; +static IMX_DEFINE_CLK_MUX(esdhc3_sel, MXC_CCM_CSCMR1, 19, 1, esdhc3_sel_clks); + +static struct clk *esdhc4_sel_clks[] = { + &esdhc1_podf.clk, + &esdhc2_podf.clk, +}; +static IMX_DEFINE_CLK_MUX(esdhc4_sel, MXC_CCM_CSCMR1, 18, 1, esdhc4_sel_clks); + +static struct clk *ssi_apm_sel[] = { + &ckih1.clk, + &lp_apm.clk, + &ckih2.clk, +}; +static IMX_DEFINE_CLK_MUX(ssi_lp_apm, MXC_CCM_CSCMR1, 8, 2, ssi_apm_sel); +static IMX_DEFINE_CLK_MUX(ssi1_clk_sel, MXC_CCM_CSCMR1, 14, 2, standard_pll_sel_clks); +static IMX_DEFINE_CLK_DIVIDER(ssi1_clk_pred, &ssi1_clk_sel.clk, 0, MXC_CCM_CS1CDR, 6, 3); +static IMX_DEFINE_CLK_DIVIDER(ssi1_clk, &ssi1_clk_pred.clk, CLK_PARENT_SET_RATE, MXC_CCM_CS1CDR, 0, 6); +static IMX_DEFINE_CLK_MUX(ssi2_clk_sel, MXC_CCM_CSCMR1, 12, 2, standard_pll_sel_clks); +static IMX_DEFINE_CLK_DIVIDER(ssi2_clk_pred, &ssi2_clk_sel.clk, 0, MXC_CCM_CS2CDR, 6, 3); +static IMX_DEFINE_CLK_DIVIDER(ssi2_clk, &ssi2_clk_pred.clk, CLK_PARENT_SET_RATE, MXC_CCM_CS2CDR, 0, 6); +static struct clk *ssi3_clk_sel[] = { + &ssi1_clk.clk, + &ssi2_clk.clk, +}; +static IMX_DEFINE_CLK_MUX(ssi3_clk, MXC_CCM_CSCMR1, 11, 1, ssi3_clk_sel); + +static IMX_DEFINE_CLK_MUX(ecspi_sel, MXC_CCM_CSCMR1, 4, 2, standard_pll_sel_clks); +static IMX_DEFINE_CLK_DIVIDER(ecspi_pred, &ecspi_sel.clk, 0, MXC_CCM_CSCDR2, 25, 3); +static IMX_DEFINE_CLK_DIVIDER(ecspi_podf, &ecspi_pred.clk, CLK_PARENT_SET_RATE, MXC_CCM_CSCDR2, 19, 6); + +static IMX_DEFINE_CLK_MUX(usboh3_sel, MXC_CCM_CSCMR1, 22, 2, standard_pll_sel_clks); +static IMX_DEFINE_CLK_DIVIDER(usboh3_pred, &usboh3_sel.clk, 0, MXC_CCM_CSCDR1, 8, 3); +static IMX_DEFINE_CLK_DIVIDER(usboh3_podf, &usboh3_pred.clk, CLK_PARENT_SET_RATE, MXC_CCM_CSCDR1, 6, 2); + +static IMX_DEFINE_CLK_DIVIDER(usb_phy_pred, &pll3_sw.clk, 0, MXC_CCM_CDCDR, 3, 3); +static IMX_DEFINE_CLK_DIVIDER(usb_phy_podf, &usb_phy_pred.clk, CLK_PARENT_SET_RATE, MXC_CCM_CDCDR, 0, 3); +static struct clk *usb_phy_sel_clks[] = { + &osc.clk, + &usb_phy_podf.clk, +}; +static IMX_DEFINE_CLK_MUX(usb_phy_sel, MXC_CCM_CSCMR1, 26, 1, usb_phy_sel_clks); + +static IMX_DEFINE_CLK_DIVIDER(cpu_podf, &pll1_sw.clk, 0, MXC_CCM_CACRR, 0, 3); + +static struct clk *ipu_di0_sel_clks[] = { + &pll3_sw.clk, + &osc.clk, + &ckih1.clk, + NULL, /* &tve_di.clk */ + NULL, /* ipp di0 (iomux) */ + NULL, /* ldp di0 */ +}; +static IMX_DEFINE_CLK_MUX(ipu_di0_sel, MXC_CCM_CSCMR2, 26, 3, ipu_di0_sel_clks); + +static struct clk *ipu_di1_sel_clks[] = { + &pll3_sw.clk, + &osc.clk, + &ckih1.clk, + NULL, /* &tve_di.clk */ + NULL, /* ipp di1 (iomux) */ + NULL, /* ldp di1 */ +}; +static IMX_DEFINE_CLK_MUX(ipu_di1_sel, MXC_CCM_CSCMR2, 29, 3, ipu_di1_sel_clks); + +static struct clk *tve_ext_sel_clks[] = { + &osc.clk, + &ckih1.clk, +}; +static IMX_DEFINE_CLK_MUX(tve_ext_sel, MXC_CCM_CSCMR1, 6, 1, tve_ext_sel_clks); + +static IMX_DEFINE_CLK_DIVIDER(tve_pred, &pll3_sw.clk, 0, MXC_CCM_CDCDR, 28, 3); + +static struct clk *tve_sel_clks[] = { + &tve_pred.clk, + &tve_ext_sel.clk, +}; +static IMX_DEFINE_CLK_MUX(tve_sel, MXC_CCM_CSCMR1, 7, 1, tve_sel_clks); + +static DEFINE_CLK_GATE2B(ahbmux1, &ipg.clk, MXC_CCM_CCGR0, 8); +static DEFINE_CLK_GATE2B(aips_tz1, &ipg.clk, MXC_CCM_CCGR0, 12); +static DEFINE_CLK_GATE2B(aips_tz2, &ipg.clk, MXC_CCM_CCGR0, 13); +static DEFINE_CLK_GATE2B(ahb_max, &ipg.clk, MXC_CCM_CCGR0, 14); +static DEFINE_CLK_GATE2B(iim_gate, &ipg.clk, MXC_CCM_CCGR0, 15); + +static DEFINE_CLK_GATE2B(uart1_ipg_gate, &ipg.clk, MXC_CCM_CCGR1, 3); +static DEFINE_CLK_GATE2B(uart1_per_gate, &uart_root.clk, MXC_CCM_CCGR1, 4); +static DEFINE_CLK_GATE2B(uart2_ipg_gate, &ipg.clk, MXC_CCM_CCGR1, 5); +static DEFINE_CLK_GATE2B(uart2_per_gate, &uart_root.clk, MXC_CCM_CCGR1, 6); +static DEFINE_CLK_GATE2B(uart3_ipg_gate, &ipg.clk, MXC_CCM_CCGR1, 7); +static DEFINE_CLK_GATE2B(uart3_per_gate, &uart_root.clk, MXC_CCM_CCGR1, 8); +static DEFINE_CLK_GATE2B(i2c1_gate, &ipg_perclk.clk, MXC_CCM_CCGR1, 9); +static DEFINE_CLK_GATE2B(i2c2_gate, &ipg_perclk.clk, MXC_CCM_CCGR1, 10); +static DEFINE_CLK_GATE2B(hsi2c_gate, &ipg.clk, MXC_CCM_CCGR1, 11); + +static DEFINE_CLK_GATE2B(mx51_usb_phy_gate, &usb_phy_sel.clk, MXC_CCM_CCGR2, 0); +static DEFINE_CLK_GATE2B(gpt_ipg_gate, &ipg.clk, MXC_CCM_CCGR2, 10); +static DEFINE_CLK_GATE2B(pwm1_ipg_gate, &ipg.clk, MXC_CCM_CCGR2, 5); +static DEFINE_CLK_GATE2B(pwm1_hf_gate, &ipg_perclk.clk, MXC_CCM_CCGR2, 6); +static DEFINE_CLK_GATE2B(pwm2_ipg_gate, &ipg.clk, MXC_CCM_CCGR2, 7); +static DEFINE_CLK_GATE2B(pwm2_hf_gate, &ipg_perclk.clk, MXC_CCM_CCGR2, 8); +static DEFINE_CLK_GATE2B(gpt_gate, &ipg.clk, MXC_CCM_CCGR2, 9); +static DEFINE_CLK_GATE2B(fec_gate, &ipg.clk, MXC_CCM_CCGR2, 12); +static DEFINE_CLK_GATE2B(usboh3_ahb_gate, &ipg.clk, MXC_CCM_CCGR2, 13); +static DEFINE_CLK_GATE2B(usboh3_gate, &usboh3_podf.clk, MXC_CCM_CCGR2, 14); +static DEFINE_CLK_GATE2B(tve_gate, &tve_sel.clk, MXC_CCM_CCGR2, 15); + +static DEFINE_CLK_GATE2B(esdhc1_ipg_gate, &ipg.clk, MXC_CCM_CCGR3, 0); +static DEFINE_CLK_GATE2B(esdhc1_per_gate, &esdhc1_podf.clk, MXC_CCM_CCGR3, 1); +static DEFINE_CLK_GATE2B(esdhc2_ipg_gate, &ipg.clk, MXC_CCM_CCGR3, 2); +static DEFINE_CLK_GATE2B(esdhc2_per_gate, &esdhc2_podf.clk, MXC_CCM_CCGR3, 3); +static DEFINE_CLK_GATE2B(esdhc3_ipg_gate, &ipg.clk, MXC_CCM_CCGR3, 4); +static DEFINE_CLK_GATE2B(esdhc3_per_gate, &esdhc3_sel.clk, MXC_CCM_CCGR3, 5); +static DEFINE_CLK_GATE2B(esdhc4_ipg_gate, &ipg.clk, MXC_CCM_CCGR3, 6); +static DEFINE_CLK_GATE2B(esdhc4_per_gate, &esdhc4_sel.clk, MXC_CCM_CCGR3, 7); +static DEFINE_CLK_GATE2B(ssi1_ipg_gate, &ipg.clk, MXC_CCM_CCGR3, 8); +static DEFINE_CLK_GATE2B(ssi1_gate, &ssi1_clk.clk, MXC_CCM_CCGR3, 9); +static DEFINE_CLK_GATE2B(ssi2_ipg_gate, &ipg.clk, MXC_CCM_CCGR3, 10); +static DEFINE_CLK_GATE2B(ssi2_gate, &ssi2_clk.clk, MXC_CCM_CCGR3, 11); +static DEFINE_CLK_GATE2B(ssi3_ipg_gate, &ipg.clk, MXC_CCM_CCGR3, 12); +static DEFINE_CLK_GATE2B(ssi3_gate, &ssi3_clk.clk, MXC_CCM_CCGR3, 13); + +static DEFINE_CLK_GATE2B(mx51_mipi_hsc1_gate, &ipg.clk, MXC_CCM_CCGR4, 3); +static DEFINE_CLK_GATE2B(mx51_mipi_hsc2_gate, &ipg.clk, MXC_CCM_CCGR4, 4); +static DEFINE_CLK_GATE2B(mx51_mipi_esc_gate, &ipg.clk, MXC_CCM_CCGR4, 5); +static DEFINE_CLK_GATE2B(mx51_mipi_hsp_gate, &ipg.clk, MXC_CCM_CCGR4, 6); + +static DEFINE_CLK_GATE2B(mx53_usb_phy1_gate, &usb_phy_sel.clk, MXC_CCM_CCGR4, 5); +static DEFINE_CLK_GATE2B(mx53_usb_phy2_gate, &usb_phy_sel.clk, MXC_CCM_CCGR4, 6); +static DEFINE_CLK_GATE2B(ecspi1_ipg_gate, &ipg.clk, MXC_CCM_CCGR4, 9); +static DEFINE_CLK_GATE2B(ecspi1_per_gate, &ecspi_podf.clk, MXC_CCM_CCGR4, 10); +static DEFINE_CLK_GATE2B(ecspi2_ipg_gate, &ipg.clk, MXC_CCM_CCGR4, 11); +static DEFINE_CLK_GATE2B(ecspi2_per_gate, &ecspi_podf.clk, MXC_CCM_CCGR4, 12); +static DEFINE_CLK_GATE2B(cspi_ipg_gate, &ipg.clk, MXC_CCM_CCGR4, 13); +static DEFINE_CLK_GATE2B(sdma_gate, &ipg.clk, MXC_CCM_CCGR4, 15); + +static DEFINE_CLK_GATE2B(ipu_gate, &ipu_hsp.clk, MXC_CCM_CCGR5, 5); +static DEFINE_CLK_GATE2B(emi_fast_gate, &dummy.clk, MXC_CCM_CCGR5, 7); +static DEFINE_CLK_GATE2B(emi_slow_gate, &emi_slow_podf.clk, MXC_CCM_CCGR5, 8); +static DEFINE_CLK_GATE2B(nfc_gate, &nfc_podf.clk, MXC_CCM_CCGR5, 10); + +static DEFINE_CLK_GATE2B(ipu_di0_gate, &ipu_di0_sel.clk, MXC_CCM_CCGR6, 5); +static DEFINE_CLK_GATE2B(ipu_di1_gate, &ipu_di1_sel.clk, MXC_CCM_CCGR6, 6); + +#define _REGISTER_CLKDEV(d, n, c) \ + { \ + .dev_id = d, \ + .con_id = n, \ + .clk = c, \ + }, + +static struct clk_lookup mx5_lookups[] = { + _REGISTER_CLKDEV("imx21-uart.0", NULL, &uart1_per_gate.clk) + _REGISTER_CLKDEV("imx21-uart.1", NULL, &uart2_per_gate.clk) + _REGISTER_CLKDEV("imx21-uart.2", NULL, &uart3_per_gate.clk) + _REGISTER_CLKDEV("mxc_pwm.0", "pwm", &pwm1_ipg_gate.clk) + _REGISTER_CLKDEV("mxc_pwm.1", "pwm", &pwm2_ipg_gate.clk) + _REGISTER_CLKDEV("imx-i2c.0", NULL, &i2c1_gate.clk) + _REGISTER_CLKDEV("imx-i2c.1", NULL, &i2c2_gate.clk) + _REGISTER_CLKDEV("mxc-ehci.0", "usb", &usboh3_gate.clk) + _REGISTER_CLKDEV("mxc-ehci.0", "usb_ahb", &usboh3_ahb_gate.clk) + _REGISTER_CLKDEV("mxc-ehci.0", "usb_phy1", &mx53_usb_phy1_gate.clk) + _REGISTER_CLKDEV("mxc-ehci.1", "usb", &usboh3_gate.clk) + _REGISTER_CLKDEV("mxc-ehci.1", "usb_ahb", &usboh3_ahb_gate.clk) + _REGISTER_CLKDEV("mxc-ehci.2", "usb", &usboh3_gate.clk) + _REGISTER_CLKDEV("mxc-ehci.2", "usb_ahb", &usboh3_ahb_gate.clk) + _REGISTER_CLKDEV("fsl-usb2-udc", "usb", &usboh3_gate.clk) + _REGISTER_CLKDEV("fsl-usb2-udc", "usb_ahb", &usboh3_ahb_gate.clk) + _REGISTER_CLKDEV("mxc_nand", NULL, &nfc_gate.clk) + _REGISTER_CLKDEV("imx-ssi.0", NULL, &ssi1_gate.clk) + _REGISTER_CLKDEV("imx-ssi.1", NULL, &ssi2_gate.clk) + _REGISTER_CLKDEV("imx-ssi.2", NULL, &ssi3_gate.clk) + _REGISTER_CLKDEV("imx-sdma", NULL, &sdma_gate.clk) + _REGISTER_CLKDEV("imx51-ecspi.0", NULL, &ecspi1_per_gate.clk) + _REGISTER_CLKDEV("imx51-ecspi.1", NULL, &ecspi2_per_gate.clk) + _REGISTER_CLKDEV("imx51-cspi.0", NULL, &cspi_ipg_gate.clk) + _REGISTER_CLKDEV(NULL, "cpu", &cpu_podf.clk) + _REGISTER_CLKDEV(NULL, "iim", &iim_gate.clk) + _REGISTER_CLKDEV("sdhci-esdhc-imx.0", NULL, &esdhc1_per_gate.clk) + _REGISTER_CLKDEV("sdhci-esdhc-imx.1", NULL, &esdhc2_per_gate.clk) + _REGISTER_CLKDEV("sdhci-esdhc-imx.2", NULL, &esdhc3_per_gate.clk) + _REGISTER_CLKDEV("sdhci-esdhc-imx.3", NULL, &esdhc4_per_gate.clk) + _REGISTER_CLKDEV("imx-ipuv3", NULL, &ipu_gate.clk) + _REGISTER_CLKDEV("imx-ipuv3", "di0", &ipu_di0_gate.clk) + _REGISTER_CLKDEV("imx-ipuv3", "di1", &ipu_di1_gate.clk) + _REGISTER_CLKDEV("imx2-wdt.0", NULL, &dummy.clk) + _REGISTER_CLKDEV("imx2-wdt.1", NULL, &dummy.clk) + _REGISTER_CLKDEV("imx-keypad", NULL, &dummy.clk) +}; + +static struct clk_lookup mx51_lookups[] = { + _REGISTER_CLKDEV("imx-i2c.2", NULL, &hsi2c_gate.clk) + _REGISTER_CLKDEV("imx27-fec.0", NULL, &fec_gate.clk) + _REGISTER_CLKDEV(NULL, "mipi_hsp", &mx51_mipi_hsp_gate.clk) +}; + +static struct clk_lookup mx53_lookups[] = { + _REGISTER_CLKDEV("imx25-fec.0", NULL, &fec_gate.clk) +}; + +struct clk *mx5_on_clocks[] = { + &uart1_ipg_gate.clk, + &uart2_ipg_gate.clk, + &uart3_ipg_gate.clk, + &gpt_ipg_gate.clk, + &esdhc1_ipg_gate.clk, + &esdhc2_ipg_gate.clk, + &esdhc3_ipg_gate.clk, + &esdhc4_ipg_gate.clk, + &ecspi1_ipg_gate.clk, + &ecspi2_ipg_gate.clk, + &cspi_ipg_gate.clk, +}; + +/* + * TODO: macro help limit the effect of clk api change. + * May be removed finally. + */ +#define _REGISTER_CLK(_clk, _ops, _flags) \ + &(_clk).clk, + +struct clk *mx5_clk_array[] = { + _REGISTER_CLK(ckil, &clk_fixed_ops, CLK_IS_ROOT) + _REGISTER_CLK(osc, &clk_fixed_ops, CLK_IS_ROOT) + _REGISTER_CLK(ckih1, &clk_fixed_ops, CLK_IS_ROOT) + _REGISTER_CLK(ckih2, &clk_fixed_ops, CLK_IS_ROOT) + _REGISTER_CLK(pll1, &clk_pllv2_ops, 0) + _REGISTER_CLK(pll2, &clk_pllv2_ops, 0) + _REGISTER_CLK(pll3, &clk_pllv2_ops, 0) + /* + * pll4 is only used by mx53. we put it here because + * tve_ext_sel use it early + */ + _REGISTER_CLK(pll4, &clk_pllv2_ops, 0) + _REGISTER_CLK(pll4_sw, &clk_mux_ops, 0) + _REGISTER_CLK(dummy, &clk_dummy_ops, CLK_IS_ROOT) + _REGISTER_CLK(lp_apm, &clk_mux_ops, 0) + _REGISTER_CLK(step_pll2_div, &clk_divider_ops, 0) + _REGISTER_CLK(step_pll3_div, &clk_divider_ops, 0) + _REGISTER_CLK(step_clk, &clk_mux_ops, 0) + _REGISTER_CLK(pll1_sw, &clk_mux_ops, 0) + _REGISTER_CLK(pll2_sw, &clk_mux_ops, 0) + _REGISTER_CLK(pll3_sw, &clk_mux_ops, 0) + _REGISTER_CLK(periph_apm, &clk_mux_ops, 0) + _REGISTER_CLK(main_bus, &clk_mux_ops, 0) + _REGISTER_CLK(ahb_root, &clk_divider_ops, 0) + _REGISTER_CLK(ipg, &clk_divider_ops, 0) + _REGISTER_CLK(perclk_lp_apm, &clk_mux_ops, 0) + _REGISTER_CLK(perclk_pred1, &clk_divider_ops, 0) + _REGISTER_CLK(perclk_pred2, &clk_divider_ops, 0) + _REGISTER_CLK(perclk_podf, &clk_divider_ops, HINT_PARENT_RATE_CHANGE) + _REGISTER_CLK(ipg_perclk, &clk_mux_ops, 0) + _REGISTER_CLK(axi_a, &clk_divider_ops, 0) + _REGISTER_CLK(axi_b, &clk_divider_ops, 0) + _REGISTER_CLK(gpu2d, &clk_mux_ops, 0) + _REGISTER_CLK(arm_axi, &clk_mux_ops, 0) + _REGISTER_CLK(ipu_hsp, &clk_mux_ops, 0) + _REGISTER_CLK(gpu, &clk_mux_ops, 0) + _REGISTER_CLK(vpu_axi_root, &clk_mux_ops, 0) + _REGISTER_CLK(ddr_root, &clk_mux_ops, 0) + _REGISTER_CLK(uart_sel, &clk_mux_ops, 0) + _REGISTER_CLK(uart_pred, &clk_divider_ops, 0) + _REGISTER_CLK(uart_root, &clk_divider_ops, HINT_PARENT_RATE_CHANGE) + _REGISTER_CLK(esdhc1_sel, &clk_mux_ops, 0) + _REGISTER_CLK(esdhc1_pred, &clk_divider_ops, 0) + _REGISTER_CLK(esdhc1_podf, &clk_divider_ops, HINT_PARENT_RATE_CHANGE) + _REGISTER_CLK(esdhc2_sel, &clk_mux_ops, 0) + _REGISTER_CLK(esdhc2_pred, &clk_divider_ops, 0) + _REGISTER_CLK(esdhc2_podf, &clk_divider_ops, HINT_PARENT_RATE_CHANGE) + _REGISTER_CLK(esdhc3_sel, &clk_mux_ops, 0) + _REGISTER_CLK(esdhc4_sel, &clk_mux_ops, 0) + _REGISTER_CLK(emi_sel, &clk_mux_ops, 0) + _REGISTER_CLK(emi_slow_podf, &clk_divider_ops, 0) + _REGISTER_CLK(nfc_podf, &clk_divider_ops, 0) + _REGISTER_CLK(ssi_lp_apm, &clk_mux_ops, 0) + _REGISTER_CLK(ssi1_clk_sel, &clk_mux_ops, 0) + _REGISTER_CLK(ssi1_clk_pred, &clk_divider_ops, 0) + _REGISTER_CLK(ssi1_clk, &clk_divider_ops, HINT_PARENT_RATE_CHANGE) + _REGISTER_CLK(ssi2_clk_sel, &clk_mux_ops, 0) + _REGISTER_CLK(ssi2_clk_pred, &clk_divider_ops, 0) + _REGISTER_CLK(ssi2_clk, &clk_divider_ops, HINT_PARENT_RATE_CHANGE) + _REGISTER_CLK(ssi3_clk, &clk_mux_ops, 0) + _REGISTER_CLK(ecspi_sel, &clk_mux_ops, 0) + _REGISTER_CLK(ecspi_pred, &clk_divider_ops, 0) + _REGISTER_CLK(ecspi_podf, &clk_divider_ops, HINT_PARENT_RATE_CHANGE) + _REGISTER_CLK(usboh3_sel, &clk_mux_ops, 0) + _REGISTER_CLK(usboh3_pred, &clk_divider_ops, 0) + _REGISTER_CLK(usboh3_podf, &clk_divider_ops, HINT_PARENT_RATE_CHANGE) + _REGISTER_CLK(usb_phy_pred, &clk_divider_ops, 0) + _REGISTER_CLK(usb_phy_podf, &clk_divider_ops, HINT_PARENT_RATE_CHANGE) + _REGISTER_CLK(usb_phy_sel, &clk_mux_ops, 0) + _REGISTER_CLK(cpu_podf, &clk_divider_ops, 0) + _REGISTER_CLK(ipu_di0_sel, &clk_mux_ops, 0) + _REGISTER_CLK(ipu_di1_sel, &clk_mux_ops, 0) + _REGISTER_CLK(tve_ext_sel, &clk_mux_ops, 0) + _REGISTER_CLK(tve_pred, &clk_divider_ops, 0) + _REGISTER_CLK(tve_sel, &clk_mux_ops, 0) + _REGISTER_CLK(ahbmux1, &clk_gate2b_ops, 0) + _REGISTER_CLK(aips_tz1, &clk_gate2b_ops, 0) + _REGISTER_CLK(aips_tz2, &clk_gate2b_ops, 0) + _REGISTER_CLK(ahb_max, &clk_gate2b_ops, 0) + _REGISTER_CLK(iim_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(uart1_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(uart1_per_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(uart2_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(uart2_per_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(uart3_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(uart3_per_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(i2c1_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(i2c2_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(gpt_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(pwm1_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(pwm1_hf_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(pwm2_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(pwm2_hf_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(gpt_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(fec_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(usboh3_ahb_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(usboh3_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(tve_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(esdhc1_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(esdhc1_per_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(esdhc2_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(esdhc2_per_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(esdhc3_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(esdhc3_per_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(esdhc4_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(esdhc4_per_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(ssi1_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(ssi1_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(ssi2_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(ssi2_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(ssi3_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(ssi3_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(ecspi1_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(ecspi1_per_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(ecspi2_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(ecspi2_per_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(cspi_ipg_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(sdma_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(ipu_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(emi_fast_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(emi_slow_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(nfc_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(ipu_di0_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(ipu_di1_gate, &clk_gate2b_ops, 0) +}; + +struct clk *mx51_clk_array[] = { + _REGISTER_CLK(ddr_hf_mx51, &clk_divider_ops, 0) + _REGISTER_CLK(ddr_root_mx51, &clk_mux_ops, 0) + _REGISTER_CLK(hsi2c_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(mx51_usb_phy_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(mx51_mipi_hsc1_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(mx51_mipi_hsc2_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(mx51_mipi_esc_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(mx51_mipi_hsp_gate, &clk_gate2b_ops, 0) +}; + +struct clk *mx53_clk_array[] = { + _REGISTER_CLK(mx53_usb_phy1_gate, &clk_gate2b_ops, 0) + _REGISTER_CLK(mx53_usb_phy2_gate, &clk_gate2b_ops, 0) +}; + +static void clk_register_array(struct clk **clks, int num) +{ + int i; + + for (i = 0; i < num; i++) + clk_init(NULL, clks[i]); +} + +static void clkdev_add_array(struct clk_lookup *lookup, int num) +{ + int i; + + for (i = 0; i < num; i++) + clkdev_add(&lookup[i]); +} + +static void mx5_clocks_common_init(unsigned long rate_ckil, unsigned long rate_osc, + unsigned long rate_ckih1, unsigned long rate_ckih2) +{ + int i; + + ckil.fixed_rate = rate_ckil; + osc.fixed_rate = rate_osc; + ckih1.fixed_rate = rate_ckih1; + ckih2.fixed_rate = rate_ckih2; + + clk_register_array(mx5_clk_array, ARRAY_SIZE(mx5_clk_array)); + clkdev_add_array(mx5_lookups, ARRAY_SIZE(mx5_lookups)); + + /* Set SDHC parents to be PLL2 */ + clk_set_parent(&esdhc1_sel.clk, &pll2_sw.clk); + clk_set_parent(&esdhc2_sel.clk, &pll2_sw.clk); + + /* keep device ipg clocks on until drivers handle it */ + for (i = 0; i < ARRAY_SIZE(mx5_on_clocks); i++) { + clk_prepare(mx5_on_clocks[i]); + clk_enable(mx5_on_clocks[i]); + } +} + +int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, + unsigned long rate_ckih1, unsigned long rate_ckih2) +{ + /* Clock tree has i.MX51 layout. i.MX53 needs some fixups */ + pll1.base = MX53_DPLL1_BASE; + pll2.base = MX53_DPLL2_BASE; + pll3.base = MX53_DPLL3_BASE; + esdhc3_per_gate.clk.parent = &esdhc2_podf.clk; + esdhc2_per_gate.clk.parent = &esdhc3_sel.clk; + tve_gate.clk.parent = &tve_pred.clk; + tve_pred.clk.parent = &tve_ext_sel.clk; + tve_ext_sel_clks[0] = &pll4_sw.clk; + tve_ext_sel_clks[1] = &ckih1.clk; + + mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2); + clk_register_array(mx53_clk_array, ARRAY_SIZE(mx53_clk_array)); + clkdev_add_array(mx53_lookups, ARRAY_SIZE(mx53_lookups)); + + /* set SDHC root clock to 200MHZ*/ + clk_set_rate(&esdhc1_podf.clk, 200000000); + clk_set_rate(&esdhc2_podf.clk, 200000000); + + /* System timer */ + mxc_timer_init(&gpt_gate.clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), + MX53_INT_GPT); + + clk_prepare(&iim_gate.clk); + clk_enable(&iim_gate.clk); + imx_print_silicon_rev("i.MX53", mx53_revision()); + clk_disable(&iim_gate.clk); + clk_unprepare(&iim_gate.clk); + + return 0; +} + +int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, + unsigned long rate_ckih1, unsigned long rate_ckih2) +{ + mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2); + clk_register_array(mx51_clk_array, ARRAY_SIZE(mx5_clk_array)); + clkdev_add_array(mx51_lookups, ARRAY_SIZE(mx51_lookups)); + + /* set SDHC root clock to 166.25MHZ*/ + clk_set_rate(&esdhc1_podf.clk, 166250000); + clk_set_rate(&esdhc2_podf.clk, 166250000); + + /* System timer */ + mxc_timer_init(&gpt_gate.clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), + MX51_INT_GPT); + + clk_prepare(&iim_gate.clk); + clk_enable(&iim_gate.clk); + imx_print_silicon_rev("i.MX51", mx51_revision()); + clk_disable(&iim_gate.clk); + + return 0; +} diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h index 500879b..e30e8fa 100644 --- a/arch/arm/plat-mxc/include/mach/clock.h +++ b/arch/arm/plat-mxc/include/mach/clock.h @@ -26,6 +26,8 @@ #ifndef CONFIG_GENERIC_CLK struct module; +#ifdef CONFIG_USE_COMMON_STRUCT_CLK +#else struct clk { int id; /* Source clock this clk depends on */ @@ -57,6 +59,7 @@ struct clk { /* Function ptr to set the parent clock of the clock. */ int (*set_parent) (struct clk *, struct clk *); }; +#endif int clk_register(struct clk *clk); void clk_unregister(struct clk *clk);