1/* 2 * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License along 14 * with this program; if not, write to the Free Software Foundation, Inc., 15 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 16 */ 17 18#include <linux/clk.h> 19#include <linux/clkdev.h> 20#include <linux/clk-provider.h> 21#include <linux/err.h> 22#include <linux/init.h> 23#include <linux/of.h> 24#include <linux/of_address.h> 25#include <dt-bindings/clock/imx1-clock.h> 26 27#include "clk.h" 28#include "common.h" 29#include "hardware.h" 30 31static const char *prem_sel_clks[] = { "clk32_premult", "clk16m", }; 32static const char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m", 33 "prem", "fclk", }; 34 35static struct clk *clk[IMX1_CLK_MAX]; 36static struct clk_onecell_data clk_data; 37 38static void __iomem *ccm __initdata; 39#define CCM_CSCR (ccm + 0x0000) 40#define CCM_MPCTL0 (ccm + 0x0004) 41#define CCM_SPCTL0 (ccm + 0x000c) 42#define CCM_PCDR (ccm + 0x0020) 43#define SCM_GCCR (ccm + 0x0810) 44 45static void __init _mx1_clocks_init(unsigned long fref) 46{ 47 clk[IMX1_CLK_DUMMY] = imx_clk_fixed("dummy", 0); 48 clk[IMX1_CLK_CLK32] = imx_obtain_fixed_clock("clk32", fref); 49 clk[IMX1_CLK_CLK16M_EXT] = imx_clk_fixed("clk16m_ext", 16000000); 50 clk[IMX1_CLK_CLK16M] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17); 51 clk[IMX1_CLK_CLK32_PREMULT] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1); 52 clk[IMX1_CLK_PREM] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks, ARRAY_SIZE(prem_sel_clks)); 53 clk[IMX1_CLK_MPLL] = imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0); 54 clk[IMX1_CLK_MPLL_GATE] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0); 55 clk[IMX1_CLK_SPLL] = imx_clk_pllv1("spll", "prem", CCM_SPCTL0); 56 clk[IMX1_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1); 57 clk[IMX1_CLK_MCU] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1); 58 clk[IMX1_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 15, 1); 59 clk[IMX1_CLK_HCLK] = imx_clk_divider("hclk", "spll_gate", CCM_CSCR, 10, 4); 60 clk[IMX1_CLK_CLK48M] = imx_clk_divider("clk48m", "spll_gate", CCM_CSCR, 26, 3); 61 clk[IMX1_CLK_PER1] = imx_clk_divider("per1", "spll_gate", CCM_PCDR, 0, 4); 62 clk[IMX1_CLK_PER2] = imx_clk_divider("per2", "spll_gate", CCM_PCDR, 4, 4); 63 clk[IMX1_CLK_PER3] = imx_clk_divider("per3", "spll_gate", CCM_PCDR, 16, 7); 64 clk[IMX1_CLK_CLKO] = imx_clk_mux("clko", CCM_CSCR, 29, 3, clko_sel_clks, ARRAY_SIZE(clko_sel_clks)); 65 clk[IMX1_CLK_UART3_GATE] = imx_clk_gate("uart3_gate", "hclk", SCM_GCCR, 6); 66 clk[IMX1_CLK_SSI2_GATE] = imx_clk_gate("ssi2_gate", "hclk", SCM_GCCR, 5); 67 clk[IMX1_CLK_BROM_GATE] = imx_clk_gate("brom_gate", "hclk", SCM_GCCR, 4); 68 clk[IMX1_CLK_DMA_GATE] = imx_clk_gate("dma_gate", "hclk", SCM_GCCR, 3); 69 clk[IMX1_CLK_CSI_GATE] = imx_clk_gate("csi_gate", "hclk", SCM_GCCR, 2); 70 clk[IMX1_CLK_MMA_GATE] = imx_clk_gate("mma_gate", "hclk", SCM_GCCR, 1); 71 clk[IMX1_CLK_USBD_GATE] = imx_clk_gate("usbd_gate", "clk48m", SCM_GCCR, 0); 72 73 imx_check_clocks(clk, ARRAY_SIZE(clk)); 74} 75 76int __init mx1_clocks_init(unsigned long fref) 77{ 78 ccm = MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR); 79 80 _mx1_clocks_init(fref); 81 82 clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx-gpt.0"); 83 clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx-gpt.0"); 84 clk_register_clkdev(clk[IMX1_CLK_DMA_GATE], "ahb", "imx1-dma"); 85 clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-dma"); 86 clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.0"); 87 clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-uart.0"); 88 clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.1"); 89 clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-uart.1"); 90 clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.2"); 91 clk_register_clkdev(clk[IMX1_CLK_UART3_GATE], "ipg", "imx1-uart.2"); 92 clk_register_clkdev(clk[IMX1_CLK_HCLK], NULL, "imx1-i2c.0"); 93 clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-cspi.0"); 94 clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-cspi.0"); 95 clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-cspi.1"); 96 clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-cspi.1"); 97 clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-fb.0"); 98 clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-fb.0"); 99 clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ahb", "imx1-fb.0"); 100 101 mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT); 102 103 return 0; 104} 105 106static void __init mx1_clocks_init_dt(struct device_node *np) 107{ 108 ccm = of_iomap(np, 0); 109 BUG_ON(!ccm); 110 111 _mx1_clocks_init(32768); 112 113 clk_data.clks = clk; 114 clk_data.clk_num = ARRAY_SIZE(clk); 115 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 116} 117CLK_OF_DECLARE(imx1_ccm, "fsl,imx1-ccm", mx1_clocks_init_dt); 118