From patchwork Mon Mar 19 13:36:04 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sascha Hauer X-Patchwork-Id: 147522 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 50B7DB6EF3 for ; Tue, 20 Mar 2012 00:40:06 +1100 (EST) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1S9cmf-0003mi-VA; Mon, 19 Mar 2012 13:38:01 +0000 Received: from bombadil.infradead.org ([2001:4830:2446:ff00:4687:fcff:fea6:5117]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1S9clW-0003CN-63 for linux-arm-kernel@merlin.infradead.org; Mon, 19 Mar 2012 13:36:50 +0000 Received: from metis.ext.pengutronix.de ([2001:6f8:1178:4:290:27ff:fe1d:cc33]) by bombadil.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1S9clU-0005K9-1S for linux-arm-kernel@lists.infradead.org; Mon, 19 Mar 2012 13:36:48 +0000 Received: from dude.hi.pengutronix.de ([2001:6f8:1178:2:21e:67ff:fe11:9c5c]) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1S9cku-0008QB-Eu; Mon, 19 Mar 2012 14:36:12 +0100 Received: from sha by dude.hi.pengutronix.de with local (Exim 4.77) (envelope-from ) id 1S9cks-0006kE-Vm; Mon, 19 Mar 2012 14:36:10 +0100 From: Sascha Hauer To: Subject: [PATCH 6/8] ARM i.MX21: implement clocks using common clock framework Date: Mon, 19 Mar 2012 14:36:04 +0100 Message-Id: <1332164166-6055-7-git-send-email-s.hauer@pengutronix.de> X-Mailer: git-send-email 1.7.9.1 In-Reply-To: <1332164166-6055-1-git-send-email-s.hauer@pengutronix.de> References: <1332164166-6055-1-git-send-email-s.hauer@pengutronix.de> X-SA-Exim-Connect-IP: 2001:6f8:1178:2:21e:67ff:fe11:9c5c X-SA-Exim-Mail-From: sha@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20120319_093648_482954_AFE12EA3 X-CRM114-Status: GOOD ( 20.05 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on bombadil.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Mike Turquette , Sascha Hauer , Shawn Guo , Fabio Estevam , Richard Zhao X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/Kconfig | 1 + arch/arm/mach-imx/Makefile | 2 +- arch/arm/mach-imx/clk-imx21.c | 177 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-imx/clk-imx21.c diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 4cd86fb..8b4b4e3 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -46,6 +46,7 @@ config SOC_IMX1 config SOC_IMX21 bool select MACH_MX21 + select COMMON_CLK select CPU_ARM926T select ARCH_MXC_AUDMUX_V1 select IMX_HAVE_DMA_V1 diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index cec4843..0a0bd05 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -1,7 +1,7 @@ obj-$(CONFIG_IMX_HAVE_DMA_V1) += dma-v1.o obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o -obj-$(CONFIG_SOC_IMX21) += clock-imx21.o mm-imx21.o +obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o obj-$(CONFIG_SOC_IMX25) += clock-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c new file mode 100644 index 0000000..0807965 --- /dev/null +++ b/arch/arm/mach-imx/clk-imx21.c @@ -0,0 +1,177 @@ +/* + * Copyright 2012 Sascha Hauer , Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "clk.h" + +#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off))) + +/* Register offsets */ +#define CCM_CSCR IO_ADDR_CCM(0x0) +#define CCM_MPCTL0 IO_ADDR_CCM(0x4) +#define CCM_MPCTL1 IO_ADDR_CCM(0x8) +#define CCM_SPCTL0 IO_ADDR_CCM(0xc) +#define CCM_SPCTL1 IO_ADDR_CCM(0x10) +#define CCM_OSC26MCTL IO_ADDR_CCM(0x14) +#define CCM_PCDR0 IO_ADDR_CCM(0x18) +#define CCM_PCDR1 IO_ADDR_CCM(0x1c) +#define CCM_PCCR0 IO_ADDR_CCM(0x20) +#define CCM_PCCR1 IO_ADDR_CCM(0x24) +#define CCM_CCSR IO_ADDR_CCM(0x28) +#define CCM_PMCTL IO_ADDR_CCM(0x2c) +#define CCM_PMCOUNT IO_ADDR_CCM(0x30) +#define CCM_WKGDCTL IO_ADDR_CCM(0x34) + +static char *mpll_sel_clks[] = { "fpm", "ckih", }; +static char *spll_sel_clks[] = { "fpm", "ckih", }; + +struct clkl { + struct clk_lookup lookup; + const char *clkname; +}; + +#define clkdev(d, n, c) \ + { \ + .lookup.dev_id = d, \ + .lookup.con_id = n, \ + .clkname = c, \ + }, + +static struct clkl lookups[] = { + clkdev("imx21-uart.0", "per", "per1") + clkdev("imx21-uart.0", "ipg", "uart1_ipg_gate") + clkdev("imx21-uart.1", "per", "per1") + clkdev("imx21-uart.1", "ipg", "uart2_ipg_gate") + clkdev("imx21-uart.2", "per", "per1") + clkdev("imx21-uart.2", "ipg", "uart3_ipg_gate") + clkdev("imx21-uart.3", "per", "per1") + clkdev("imx21-uart.3", "ipg", "uart4_ipg_gate") + clkdev("imx-gpt.0", "ipg", "gpt1_ipg_gate") + clkdev("imx-gpt.0", "per", "per1") + clkdev("imx-gpt.1", "ipg", "gpt2_ipg_gate") + clkdev("imx-gpt.1", "per", "per1") + clkdev("imx-gpt.2", "ipg", "gpt3_ipg_gate") + clkdev("imx-gpt.2", "per", "per1") + clkdev("mxc_pwm.0", "pwm", "pwm_ipg_gate") + clkdev("imx21-cspi.0", "per", "per2") + clkdev("imx21-cspi.0", "ipg", "cspi1_ipg_gate") + clkdev("imx21-cspi.1", "per", "per2") + clkdev("imx21-cspi.1", "ipg", "cspi2_ipg_gate") + clkdev("imx21-cspi.2", "per", "per2") + clkdev("imx21-cspi.2", "ipg", "cspi3_ipg_gate") + clkdev("imx-fb.0", "per", "per3") + clkdev("imx-fb.0", "ipg", "lcdc_ipg_gate") + clkdev("imx-fb.0", "ahb", "lcdc_hclk_gate") + clkdev("imx21-hcd.0", "per", "usb_gate") + clkdev("imx21-hcd.0", "ahb", "usb_hclk_gate") + clkdev("mxc_nand.0", NULL, "nfc_gate") + clkdev("imx-dma", "ahb", "dma_hclk_gate") + clkdev("imx-dma", "ipg", "dma_gate") + clkdev("imx2-wdt.0", NULL, "wdog_gate") + clkdev("imx-i2c.0", NULL, "i2c_gate") + clkdev("mxc-keypad", NULL, "kpp_gate") + clkdev("mxc_w1.0", NULL, "owire_gate") + clkdev(NULL, "brom", "brom_gate") + clkdev(NULL, "emma", "emma_gate") + clkdev(NULL, "slcdc", "slcdc_gate") + clkdev(NULL, "gpio", "gpio_gate") + clkdev(NULL, "rtc", "rtc_gate") + clkdev(NULL, "csi", "csi") + clkdev(NULL, "ssi1", "ssi1_gate") + clkdev(NULL, "ssi2", "ssi2_gate") + clkdev(NULL, "sdhc1", "sdhc1") + clkdev(NULL, "sdhc2", "sdhc2") +}; + +/* + * must be called very early to get information about the + * available clock rate when the timer framework starts + */ +int __init mx21_clocks_init(unsigned long lref, unsigned long href) +{ + int i; + + imx_clk_fixed("ckil", lref); + imx_clk_fixed("ckih", href); + imx_clk_fixed_factor("fpm", "ckil", 512, 1); + imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, ARRAY_SIZE(mpll_sel_clks)); + imx_clk_mux("spll_sel", CCM_CSCR, 17, 1, spll_sel_clks, ARRAY_SIZE(spll_sel_clks)); + imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0); + imx_clk_pllv1("spll", "spll_sel", CCM_SPCTL0); + imx_clk_divider("fclk", "mpll", CCM_CSCR, 29, 3); + imx_clk_divider("hclk", "fclk", CCM_CSCR, 10, 4); + imx_clk_divider("ipg", "hclk", CCM_CSCR, 9, 1); + imx_clk_divider("per1", "mpll", CCM_PCDR1, 0, 6); + imx_clk_divider("per2", "mpll", CCM_PCDR1, 8, 6); + imx_clk_divider("per3", "mpll", CCM_PCDR1, 16, 6); + imx_clk_divider("per4", "mpll", CCM_PCDR1, 24, 6); + imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR0, 0); + imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR0, 1); + imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR0, 2); + imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR0, 3); + imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR1, 25); + imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR1, 26); + imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR1, 27); + imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR1, 28); + imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 9); + imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 10); + imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 18); + imx_clk_gate("lcdc_hclk_gate", "hclk", CCM_PCCR0, 26); + imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR1, 23); + imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 5); + imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 4); + imx_clk_gate("per4_gate", "per4", CCM_PCCR0, 22); + imx_clk_gate("csi_hclk_gate", "hclk", CCM_PCCR0, 31); + imx_clk_divider("usb_div", "spll", CCM_CSCR, 26, 3); + imx_clk_gate("usb_gate", "usb_div", CCM_PCCR0, 14); + imx_clk_gate("usb_hclk_gate", "hclk", CCM_PCCR0, 24); + imx_clk_gate("ssi1_gate", "ipg", CCM_PCCR0, 6); + imx_clk_gate("ssi2_gate", "ipg", CCM_PCCR0, 7); + imx_clk_divider("nfc_div", "ipg", CCM_PCDR0, 12, 4); + imx_clk_gate("nfc_gate", "nfc_div", CCM_PCCR0, 19); + imx_clk_gate("dma_gate", "ipg", CCM_PCCR0, 13); + imx_clk_gate("dma_hclk_gate", "hclk", CCM_PCCR0, 30); + imx_clk_gate("brom_gate", "hclk", CCM_PCCR0, 28); + imx_clk_gate("emma_gate", "ipg", CCM_PCCR0, 15); + imx_clk_gate("emma_hclk_gate", "hclk", CCM_PCCR0, 27); + imx_clk_gate("slcdc_gate", "ipg", CCM_PCCR0, 25); + imx_clk_gate("slcdc_hclk_gate", "hclk", CCM_PCCR0, 21); + imx_clk_gate("wdog_gate", "ipg", CCM_PCCR1, 24); + imx_clk_gate("gpio_gate", "ipg", CCM_PCCR0, 11); + imx_clk_gate("i2c_gate", "ipg", CCM_PCCR0, 12); + imx_clk_gate("kpp_gate", "ipg", CCM_PCCR1, 30); + imx_clk_gate("owire_gate", "ipg", CCM_PCCR1, 31); + imx_clk_gate("rtc_gate", "ipg", CCM_PCCR1, 29); + + for (i = 0; i < ARRAY_SIZE(lookups); i++) { + struct clkl *l = &lookups[i]; + l->lookup.clk = __clk_lookup(l->clkname); + clkdev_add(&l->lookup); + } + + mxc_timer_init(NULL, MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), + MX21_INT_GPT1); + return 0; +}