Clock support is moving to the clk subsystem. These tegra, omap and imx
changes are for code that is still platform specific and not (yet)
part of that subsystem.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
iQIVAwUAUA2dh2CrR//JCVInAQLm6g//UD7Q6xc/1I9/k0c/V35o4FRgmOt9xIp2
ofsB801AnYOOusFWkcBa8xb6zFQuNQwR6OflkYBBV+31Zp2cNHgF9SVxaYlh43MD
iptUnCh8VzSEFFZGy1Vi3sdrKY5fw5dyffPjgv8HtWQzs4r8H+98UnNQFbkTwPft
9TxAeH73LRm4uNI/E8OerYN78TOefBK8p6HXyNW//MCzb59aG73/iD3EACrAmvyY
gtyhLMtPeZTUWh3Fy5vXd9cfCmzQOAH/ADeMxVyx2QFyb3vCcPoS8Z5plh3zIjMt
Ze0KlhHkB5lfBGBOB3gA/7ItlclhL2qLNkuhM2CBgYg+WTZ4OqaJCv80+OK8X4i5
XCVjuDG++CFH09jDnMPXeUBM6UHwRV3f/HIRhaL8nH+nq1mU5HzEGrvBZTnOIklI
XNoOpAMVPih64vH8PIQL/8oXT+cNHyVkmKA2uqRKq+mgqC+FIjG7EKBmIVORr7eI
HmDHtHpRZY9EpK/cfgykDl4ELDITEaaitxvk0uqchSj3SXjfmbBXNKKcInQhDKaZ
TKRMCgzeTu4NXSrRyHAP2toKUQNSziB7mwL7aHD6LMloqP1jBVOyZpxAIVwt19lZ
qBAAatYGYocbssypI/E4CptTn3uC3dQiXDHRNJkZC/4o5suZoW9wpT77yvQNR/YQ
GBO0bhQCI0Y=
=Cvpa
-----END PGP SIGNATURE-----
Merge tag 'clk' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull arm-soc clk changes from Arnd Bergmann:
"Clock support is moving to the clk subsystem. These tegra, omap and
imx changes are for code that is still platform specific and not (yet)
part of that subsystem."
Fix up conflicts in arch/arm/mach-{imx/clk-imx51-imx53.c,omap2/Makefile}
* tag 'clk' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (23 commits)
ARM: imx: clk-imx31: Fix clock id for rnga driver
ARM: imx: add missing item to the list of clock event modes
ARM: i.MX5x CSPI: Fixed clock name for CSPI
ARM: i.MX5x clocks: Fix GPT clocks
ARM: i.MX5x clocks: Fix parent for PWM clocks
ARM: i.MX5x clocks: Add EPIT support
ARM: mx27: Reenable silicon version print
ARM: clk-imx27: Fix rtc clock id
ARM: tegra: Provide clock for only one PWM controller
ARM: tegra: Fix PWM clock programming
ARM: OMAP3+: clock33xx: Add AM33XX clock tree data
ARM: OMAP3+: clock: Move common clksel_rate & clock data to common file
ARM: tegra: dma: rename driver name for clock to "tegra-apbdma"
ARM: tegra: Remove second instance of uart clk
crypto: add clk_prepare/clk_unprepare
ASoC: tegra: add clk_prepare/clk_unprepare
staging: nvec: add clk_prepare/clk_unprepare
spi/tegra: add clk_prepare/clk_unprepare
Input: tegra-kbc - add clk_prepare/clk_unprepare
USB: ehci-tegra: add clk_prepare/clk_unprepare
...
200 lines
10 KiB
C
200 lines
10 KiB
C
/*
|
|
* Copyright (C) 2012 Sascha Hauer <kernel@pengutronix.de>
|
|
*
|
|
* 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 <linux/module.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/clkdev.h>
|
|
#include <linux/io.h>
|
|
#include <linux/err.h>
|
|
#include <linux/of.h>
|
|
|
|
#include <mach/hardware.h>
|
|
#include <mach/mx31.h>
|
|
#include <mach/common.h>
|
|
|
|
#include "clk.h"
|
|
#include "crmregs-imx3.h"
|
|
|
|
static const char *mcu_main_sel[] = { "spll", "mpll", };
|
|
static const char *per_sel[] = { "per_div", "ipg", };
|
|
static const char *csi_sel[] = { "upll", "spll", };
|
|
static const char *fir_sel[] = { "mcu_main", "upll", "spll" };
|
|
|
|
enum mx31_clks {
|
|
ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, per_div,
|
|
per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre,
|
|
fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate,
|
|
iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate,
|
|
uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate,
|
|
mstick1_gate, mstick2_gate, csi_gate, rtc_gate, wdog_gate, pwm_gate,
|
|
sim_gate, ect_gate, usb_gate, kpp_gate, ipu_gate, uart3_gate,
|
|
uart4_gate, uart5_gate, owire_gate, ssi2_gate, cspi1_gate, cspi2_gate,
|
|
gacc_gate, emi_gate, rtic_gate, firi_gate, clk_max
|
|
};
|
|
|
|
static struct clk *clk[clk_max];
|
|
|
|
int __init mx31_clocks_init(unsigned long fref)
|
|
{
|
|
void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
|
|
int i;
|
|
|
|
clk[ckih] = imx_clk_fixed("ckih", fref);
|
|
clk[ckil] = imx_clk_fixed("ckil", 32768);
|
|
clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL);
|
|
clk[spll] = imx_clk_pllv1("spll", "ckih", base + MXC_CCM_SRPCTL);
|
|
clk[upll] = imx_clk_pllv1("upll", "ckih", base + MXC_CCM_UPCTL);
|
|
clk[mcu_main] = imx_clk_mux("mcu_main", base + MXC_CCM_PMCR0, 31, 1, mcu_main_sel, ARRAY_SIZE(mcu_main_sel));
|
|
clk[hsp] = imx_clk_divider("hsp", "mcu_main", base + MXC_CCM_PDR0, 11, 3);
|
|
clk[ahb] = imx_clk_divider("ahb", "mcu_main", base + MXC_CCM_PDR0, 3, 3);
|
|
clk[nfc] = imx_clk_divider("nfc", "ahb", base + MXC_CCM_PDR0, 8, 3);
|
|
clk[ipg] = imx_clk_divider("ipg", "ahb", base + MXC_CCM_PDR0, 6, 2);
|
|
clk[per_div] = imx_clk_divider("per_div", "upll", base + MXC_CCM_PDR0, 16, 5);
|
|
clk[per] = imx_clk_mux("per", base + MXC_CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel));
|
|
clk[csi] = imx_clk_mux("csi_sel", base + MXC_CCM_CCMR, 25, 1, csi_sel, ARRAY_SIZE(csi_sel));
|
|
clk[fir] = imx_clk_mux("fir_sel", base + MXC_CCM_CCMR, 11, 2, fir_sel, ARRAY_SIZE(fir_sel));
|
|
clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MXC_CCM_PDR0, 23, 9);
|
|
clk[usb_div_pre] = imx_clk_divider("usb_div_pre", "upll", base + MXC_CCM_PDR1, 30, 2);
|
|
clk[usb_div_post] = imx_clk_divider("usb_div_post", "usb_div_pre", base + MXC_CCM_PDR1, 27, 3);
|
|
clk[fir_div_pre] = imx_clk_divider("fir_div_pre", "fir_sel", base + MXC_CCM_PDR1, 24, 3);
|
|
clk[fir_div_post] = imx_clk_divider("fir_div_post", "fir_div_pre", base + MXC_CCM_PDR1, 23, 6);
|
|
clk[sdhc1_gate] = imx_clk_gate2("sdhc1_gate", "per", base + MXC_CCM_CGR0, 0);
|
|
clk[sdhc2_gate] = imx_clk_gate2("sdhc2_gate", "per", base + MXC_CCM_CGR0, 2);
|
|
clk[gpt_gate] = imx_clk_gate2("gpt_gate", "per", base + MXC_CCM_CGR0, 4);
|
|
clk[epit1_gate] = imx_clk_gate2("epit1_gate", "per", base + MXC_CCM_CGR0, 6);
|
|
clk[epit2_gate] = imx_clk_gate2("epit2_gate", "per", base + MXC_CCM_CGR0, 8);
|
|
clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MXC_CCM_CGR0, 10);
|
|
clk[ata_gate] = imx_clk_gate2("ata_gate", "ipg", base + MXC_CCM_CGR0, 12);
|
|
clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MXC_CCM_CGR0, 14);
|
|
clk[cspi3_gate] = imx_clk_gate2("cspi3_gate", "ipg", base + MXC_CCM_CGR0, 16);
|
|
clk[rng_gate] = imx_clk_gate2("rng_gate", "ipg", base + MXC_CCM_CGR0, 18);
|
|
clk[uart1_gate] = imx_clk_gate2("uart1_gate", "per", base + MXC_CCM_CGR0, 20);
|
|
clk[uart2_gate] = imx_clk_gate2("uart2_gate", "per", base + MXC_CCM_CGR0, 22);
|
|
clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "spll", base + MXC_CCM_CGR0, 24);
|
|
clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "per", base + MXC_CCM_CGR0, 26);
|
|
clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "per", base + MXC_CCM_CGR0, 28);
|
|
clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per", base + MXC_CCM_CGR0, 30);
|
|
clk[hantro_gate] = imx_clk_gate2("hantro_gate", "per", base + MXC_CCM_CGR1, 0);
|
|
clk[mstick1_gate] = imx_clk_gate2("mstick1_gate", "per", base + MXC_CCM_CGR1, 2);
|
|
clk[mstick2_gate] = imx_clk_gate2("mstick2_gate", "per", base + MXC_CCM_CGR1, 4);
|
|
clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", base + MXC_CCM_CGR1, 6);
|
|
clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MXC_CCM_CGR1, 8);
|
|
clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MXC_CCM_CGR1, 10);
|
|
clk[pwm_gate] = imx_clk_gate2("pwm_gate", "per", base + MXC_CCM_CGR1, 12);
|
|
clk[sim_gate] = imx_clk_gate2("sim_gate", "per", base + MXC_CCM_CGR1, 14);
|
|
clk[ect_gate] = imx_clk_gate2("ect_gate", "per", base + MXC_CCM_CGR1, 16);
|
|
clk[usb_gate] = imx_clk_gate2("usb_gate", "ahb", base + MXC_CCM_CGR1, 18);
|
|
clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MXC_CCM_CGR1, 20);
|
|
clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MXC_CCM_CGR1, 22);
|
|
clk[uart3_gate] = imx_clk_gate2("uart3_gate", "per", base + MXC_CCM_CGR1, 24);
|
|
clk[uart4_gate] = imx_clk_gate2("uart4_gate", "per", base + MXC_CCM_CGR1, 26);
|
|
clk[uart5_gate] = imx_clk_gate2("uart5_gate", "per", base + MXC_CCM_CGR1, 28);
|
|
clk[owire_gate] = imx_clk_gate2("owire_gate", "per", base + MXC_CCM_CGR1, 30);
|
|
clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "spll", base + MXC_CCM_CGR2, 0);
|
|
clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MXC_CCM_CGR2, 2);
|
|
clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MXC_CCM_CGR2, 4);
|
|
clk[gacc_gate] = imx_clk_gate2("gacc_gate", "per", base + MXC_CCM_CGR2, 6);
|
|
clk[emi_gate] = imx_clk_gate2("emi_gate", "ahb", base + MXC_CCM_CGR2, 8);
|
|
clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MXC_CCM_CGR2, 10);
|
|
clk[firi_gate] = imx_clk_gate2("firi_gate", "upll", base+MXC_CCM_CGR2, 12);
|
|
|
|
for (i = 0; i < ARRAY_SIZE(clk); i++)
|
|
if (IS_ERR(clk[i]))
|
|
pr_err("imx31 clk %d: register failed with %ld\n",
|
|
i, PTR_ERR(clk[i]));
|
|
|
|
clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
|
|
clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
|
|
clk_register_clkdev(clk[cspi1_gate], NULL, "imx31-cspi.0");
|
|
clk_register_clkdev(clk[cspi2_gate], NULL, "imx31-cspi.1");
|
|
clk_register_clkdev(clk[cspi3_gate], NULL, "imx31-cspi.2");
|
|
clk_register_clkdev(clk[pwm_gate], "pwm", NULL);
|
|
clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
|
|
clk_register_clkdev(clk[rtc_gate], NULL, "mxc_rtc");
|
|
clk_register_clkdev(clk[epit1_gate], "epit", NULL);
|
|
clk_register_clkdev(clk[epit2_gate], "epit", NULL);
|
|
clk_register_clkdev(clk[nfc], NULL, "mxc_nand.0");
|
|
clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
|
|
clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
|
|
clk_register_clkdev(clk[kpp_gate], "kpp", NULL);
|
|
clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.0");
|
|
clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.0");
|
|
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
|
|
clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.1");
|
|
clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.1");
|
|
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
|
|
clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.2");
|
|
clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.2");
|
|
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
|
|
clk_register_clkdev(clk[usb_div_post], "per", "fsl-usb2-udc");
|
|
clk_register_clkdev(clk[usb_gate], "ahb", "fsl-usb2-udc");
|
|
clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
|
|
clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
|
|
/* i.mx31 has the i.mx21 type uart */
|
|
clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
|
|
clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0");
|
|
clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1");
|
|
clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1");
|
|
clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2");
|
|
clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2");
|
|
clk_register_clkdev(clk[uart4_gate], "per", "imx21-uart.3");
|
|
clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.3");
|
|
clk_register_clkdev(clk[uart5_gate], "per", "imx21-uart.4");
|
|
clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.4");
|
|
clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0");
|
|
clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1");
|
|
clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2");
|
|
clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0");
|
|
clk_register_clkdev(clk[sdhc1_gate], NULL, "mxc-mmc.0");
|
|
clk_register_clkdev(clk[sdhc2_gate], NULL, "mxc-mmc.1");
|
|
clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0");
|
|
clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1");
|
|
clk_register_clkdev(clk[firi_gate], "firi", NULL);
|
|
clk_register_clkdev(clk[ata_gate], NULL, "pata_imx");
|
|
clk_register_clkdev(clk[rtic_gate], "rtic", NULL);
|
|
clk_register_clkdev(clk[rng_gate], NULL, "mxc_rnga");
|
|
clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma");
|
|
clk_register_clkdev(clk[iim_gate], "iim", NULL);
|
|
|
|
clk_set_parent(clk[csi], clk[upll]);
|
|
clk_prepare_enable(clk[emi_gate]);
|
|
clk_prepare_enable(clk[iim_gate]);
|
|
mx31_revision();
|
|
clk_disable_unprepare(clk[iim_gate]);
|
|
|
|
mxc_timer_init(MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), MX31_INT_GPT);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifdef CONFIG_OF
|
|
int __init mx31_clocks_init_dt(void)
|
|
{
|
|
struct device_node *np;
|
|
u32 fref = 26000000; /* default */
|
|
|
|
for_each_compatible_node(np, NULL, "fixed-clock") {
|
|
if (!of_device_is_compatible(np, "fsl,imx-osc26m"))
|
|
continue;
|
|
|
|
if (!of_property_read_u32(np, "clock-frequency", &fref))
|
|
break;
|
|
}
|
|
|
|
return mx31_clocks_init(fref);
|
|
}
|
|
#endif
|