From e187942b9a8552b1ada3475af42aabe2f4335a62 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 9 Nov 2016 08:13:58 -0800 Subject: i.MX: Move clk code from 'mach-imx' to 'drivers' Move clk code from 'mach-imx' to 'drivers' to keep the code tree structure closer to that of analogous one from Linux kernel and, arguably although subjective, to keep 'mach-imx' less cluttered. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/clk/imx/clk-imx31.c | 146 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 drivers/clk/imx/clk-imx31.c (limited to 'drivers/clk/imx/clk-imx31.c') diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c new file mode 100644 index 0000000000..8d135c9a1f --- /dev/null +++ b/drivers/clk/imx/clk-imx31.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2012 Sascha Hauer + * + * 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" + +/* Register addresses */ +#define CCM_CCMR 0x00 +#define CCM_PDR0 0x04 +#define CCM_PDR1 0x08 +//#define CCM_RCSR 0x0C +#define CCM_MPCTL 0x10 +#define CCM_UPCTL 0x14 +#define CCM_SRPCTL 0x18 +#define CCM_COSR 0x1C +#define CCM_CGR0 0x20 +#define CCM_CGR1 0x24 +#define CCM_CGR2 0x28 +#define CCM_WIMR 0x2C +#define CCM_LDC 0x30 +#define CCM_DCVR0 0x34 +#define CCM_DCVR1 0x38 +#define CCM_DCVR2 0x3C +#define CCM_DCVR3 0x40 +#define CCM_LTR0 0x44 +#define CCM_LTR1 0x48 +#define CCM_LTR2 0x4C +#define CCM_LTR3 0x50 +#define CCM_LTBR0 0x54 +#define CCM_LTBR1 0x58 +#define CCM_PMCR0 0x5C +#define CCM_PMCR1 0x60 +#define CCM_PDR2 0x64 + +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 *clks[clk_max]; + +static const char *mcu_main_sel[] = { + "spll", + "mpll", +}; + +static const char *per_sel[] = { + "per_div", + "ipg", +}; + +static int imx31_ccm_probe(struct device_d *dev) +{ + struct resource *iores; + void __iomem *base; + + iores = dev_request_mem_resource(dev, 0); + if (IS_ERR(iores)) + return PTR_ERR(iores); + base = IOMEM(iores->start); + + writel(0xffffffff, base + CCM_CGR0); + writel(0xffffffff, base + CCM_CGR1); + writel(0xffffffff, base + CCM_CGR2); + + clks[ckih] = clk_fixed("ckih", 26000000); + clks[ckil] = clk_fixed("ckil", 32768); + clks[mpll] = imx_clk_pllv1("mpll", "ckih", base + CCM_MPCTL); + clks[spll] = imx_clk_pllv1("spll", "ckih", base + CCM_SRPCTL); + clks[upll] = imx_clk_pllv1("upll", "ckih", base + CCM_UPCTL); + clks[mcu_main] = imx_clk_mux("mcu_main", base + CCM_PMCR0, 31, 1, + mcu_main_sel, ARRAY_SIZE(mcu_main_sel)); + clks[hsp] = imx_clk_divider("hsp", "mcu_main", base + CCM_PDR0, 11, 3); + clks[ahb] = imx_clk_divider("ahb", "mcu_main", base + CCM_PDR0, 3, 3); + clks[nfc] = imx_clk_divider("nfc", "ahb", base + CCM_PDR0, 8, 3); + clks[ipg] = imx_clk_divider("ipg", "ahb", base + CCM_PDR0, 6, 2); + clks[per_div] = imx_clk_divider("per_div", "upll", base + CCM_PDR0, 16, 5); + clks[per] = imx_clk_mux("per", base + CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel)); + + clkdev_add_physbase(clks[per], MX31_UART1_BASE_ADDR, NULL); + clkdev_add_physbase(clks[per], MX31_UART2_BASE_ADDR, NULL); + clkdev_add_physbase(clks[per], MX31_UART3_BASE_ADDR, NULL); + clkdev_add_physbase(clks[per], MX31_UART4_BASE_ADDR, NULL); + clkdev_add_physbase(clks[per], MX31_UART5_BASE_ADDR, NULL); + clkdev_add_physbase(clks[per], MX31_I2C1_BASE_ADDR, NULL); + clkdev_add_physbase(clks[per], MX31_I2C2_BASE_ADDR, NULL); + clkdev_add_physbase(clks[per], MX31_I2C3_BASE_ADDR, NULL); + clkdev_add_physbase(clks[ipg], MX31_CSPI1_BASE_ADDR, NULL); + clkdev_add_physbase(clks[ipg], MX31_CSPI2_BASE_ADDR, NULL); + clkdev_add_physbase(clks[ipg], MX31_CSPI3_BASE_ADDR, NULL); + clkdev_add_physbase(clks[per], MX31_SDHC1_BASE_ADDR, NULL); + clkdev_add_physbase(clks[per], MX31_SDHC2_BASE_ADDR, NULL); + clkdev_add_physbase(clks[per], MX31_GPT1_BASE_ADDR, NULL); + clkdev_add_physbase(clks[hsp], MX31_IPU_CTRL_BASE_ADDR, NULL); + + return 0; +} + +static __maybe_unused struct of_device_id imx31_ccm_dt_ids[] = { + { + .compatible = "fsl,imx31-ccm", + }, { + /* sentinel */ + } +}; + +static struct driver_d imx31_ccm_driver = { + .probe = imx31_ccm_probe, + .name = "imx31-ccm", + .of_compatible = DRV_OF_COMPAT(imx31_ccm_dt_ids), +}; + +static int imx31_ccm_init(void) +{ + return platform_driver_register(&imx31_ccm_driver); +} +core_initcall(imx31_ccm_init); -- cgit v1.2.3