aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/clk-imx1.c
diff options
context:
space:
mode:
authorAlexander Shiyan <shc_work@mail.ru>2014-05-20 12:43:49 -0400
committerShawn Guo <shawn.guo@freescale.com>2014-07-18 04:10:03 -0400
commitac36187b373ff6be495c7b68ccea5eb0fe928442 (patch)
tree457ba690b14722f46deae01d2853b2e4d2f8e224 /arch/arm/mach-imx/clk-imx1.c
parentcd973e1cab4a3e9308887b3d5d9fc03fafd28583 (diff)
ARM: i.MX1 clk: Add devicetree support
This patch adds devicetree support CCM module for i.MX1 (MC9328MX1) CPUs. Signed-off-by: Alexander Shiyan <shc_work@mail.ru> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
Diffstat (limited to 'arch/arm/mach-imx/clk-imx1.c')
-rw-r--r--arch/arm/mach-imx/clk-imx1.c153
1 files changed, 82 insertions, 71 deletions
diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c
index 7f739be3de2c..e9c391b32092 100644
--- a/arch/arm/mach-imx/clk-imx1.c
+++ b/arch/arm/mach-imx/clk-imx1.c
@@ -15,100 +15,111 @@
15 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 15 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
16 */ 16 */
17 17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/clk.h> 18#include <linux/clk.h>
21#include <linux/io.h>
22#include <linux/clkdev.h> 19#include <linux/clkdev.h>
20#include <linux/clk-provider.h>
23#include <linux/err.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>
24 26
25#include "clk.h" 27#include "clk.h"
26#include "common.h" 28#include "common.h"
27#include "hardware.h" 29#include "hardware.h"
28 30
29/* CCM register addresses */
30#define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
31
32#define CCM_CSCR IO_ADDR_CCM(0x0)
33#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
34#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
35#define CCM_PCDR IO_ADDR_CCM(0x20)
36
37/* SCM register addresses */
38#define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off)))
39
40#define SCM_GCCR IO_ADDR_SCM(0xc)
41
42static const char *prem_sel_clks[] = { "clk32_premult", "clk16m", }; 31static const char *prem_sel_clks[] = { "clk32_premult", "clk16m", };
43static const char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m", 32static const char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m",
44 "prem", "fclk", }; 33 "prem", "fclk", };
45 34
46enum imx1_clks { 35static struct clk *clk[IMX1_CLK_MAX];
47 dummy, clk32, clk16m_ext, clk16m, clk32_premult, prem, mpll, mpll_gate, 36static struct clk_onecell_data clk_data;
48 spll, spll_gate, mcu, fclk, hclk, clk48m, per1, per2, per3, clko,
49 uart3_gate, ssi2_gate, brom_gate, dma_gate, csi_gate, mma_gate,
50 usbd_gate, clk_max
51};
52 37
53static struct clk *clk[clk_max]; 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)
54 44
55int __init mx1_clocks_init(unsigned long fref) 45static void __init _mx1_clocks_init(unsigned long fref)
56{ 46{
57 int i; 47 unsigned i;
58 48
59 clk[dummy] = imx_clk_fixed("dummy", 0); 49 clk[IMX1_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
60 clk[clk32] = imx_clk_fixed("clk32", fref); 50 clk[IMX1_CLK_CLK32] = imx_obtain_fixed_clock("clk32", fref);
61 clk[clk16m_ext] = imx_clk_fixed("clk16m_ext", 16000000); 51 clk[IMX1_CLK_CLK16M_EXT] = imx_clk_fixed("clk16m_ext", 16000000);
62 clk[clk16m] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17); 52 clk[IMX1_CLK_CLK16M] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17);
63 clk[clk32_premult] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1); 53 clk[IMX1_CLK_CLK32_PREMULT] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1);
64 clk[prem] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks, 54 clk[IMX1_CLK_PREM] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks, ARRAY_SIZE(prem_sel_clks));
65 ARRAY_SIZE(prem_sel_clks)); 55 clk[IMX1_CLK_MPLL] = imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0);
66 clk[mpll] = imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0); 56 clk[IMX1_CLK_MPLL_GATE] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0);
67 clk[mpll_gate] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0); 57 clk[IMX1_CLK_SPLL] = imx_clk_pllv1("spll", "prem", CCM_SPCTL0);
68 clk[spll] = imx_clk_pllv1("spll", "prem", CCM_SPCTL0); 58 clk[IMX1_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1);
69 clk[spll_gate] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1); 59 clk[IMX1_CLK_MCU] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1);
70 clk[mcu] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1); 60 clk[IMX1_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 15, 1);
71 clk[fclk] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 15, 1); 61 clk[IMX1_CLK_HCLK] = imx_clk_divider("hclk", "spll_gate", CCM_CSCR, 10, 4);
72 clk[hclk] = imx_clk_divider("hclk", "spll_gate", CCM_CSCR, 10, 4); 62 clk[IMX1_CLK_CLK48M] = imx_clk_divider("clk48m", "spll_gate", CCM_CSCR, 26, 3);
73 clk[clk48m] = imx_clk_divider("clk48m", "spll_gate", CCM_CSCR, 26, 3); 63 clk[IMX1_CLK_PER1] = imx_clk_divider("per1", "spll_gate", CCM_PCDR, 0, 4);
74 clk[per1] = imx_clk_divider("per1", "spll_gate", CCM_PCDR, 0, 4); 64 clk[IMX1_CLK_PER2] = imx_clk_divider("per2", "spll_gate", CCM_PCDR, 4, 4);
75 clk[per2] = imx_clk_divider("per2", "spll_gate", CCM_PCDR, 4, 4); 65 clk[IMX1_CLK_PER3] = imx_clk_divider("per3", "spll_gate", CCM_PCDR, 16, 7);
76 clk[per3] = imx_clk_divider("per3", "spll_gate", CCM_PCDR, 16, 7); 66 clk[IMX1_CLK_CLKO] = imx_clk_mux("clko", CCM_CSCR, 29, 3, clko_sel_clks, ARRAY_SIZE(clko_sel_clks));
77 clk[clko] = imx_clk_mux("clko", CCM_CSCR, 29, 3, clko_sel_clks, 67 clk[IMX1_CLK_UART3_GATE] = imx_clk_gate("uart3_gate", "hclk", SCM_GCCR, 6);
78 ARRAY_SIZE(clko_sel_clks)); 68 clk[IMX1_CLK_SSI2_GATE] = imx_clk_gate("ssi2_gate", "hclk", SCM_GCCR, 5);
79 clk[uart3_gate] = imx_clk_gate("uart3_gate", "hclk", SCM_GCCR, 6); 69 clk[IMX1_CLK_BROM_GATE] = imx_clk_gate("brom_gate", "hclk", SCM_GCCR, 4);
80 clk[ssi2_gate] = imx_clk_gate("ssi2_gate", "hclk", SCM_GCCR, 5); 70 clk[IMX1_CLK_DMA_GATE] = imx_clk_gate("dma_gate", "hclk", SCM_GCCR, 3);
81 clk[brom_gate] = imx_clk_gate("brom_gate", "hclk", SCM_GCCR, 4); 71 clk[IMX1_CLK_CSI_GATE] = imx_clk_gate("csi_gate", "hclk", SCM_GCCR, 2);
82 clk[dma_gate] = imx_clk_gate("dma_gate", "hclk", SCM_GCCR, 3); 72 clk[IMX1_CLK_MMA_GATE] = imx_clk_gate("mma_gate", "hclk", SCM_GCCR, 1);
83 clk[csi_gate] = imx_clk_gate("csi_gate", "hclk", SCM_GCCR, 2); 73 clk[IMX1_CLK_USBD_GATE] = imx_clk_gate("usbd_gate", "clk48m", SCM_GCCR, 0);
84 clk[mma_gate] = imx_clk_gate("mma_gate", "hclk", SCM_GCCR, 1);
85 clk[usbd_gate] = imx_clk_gate("usbd_gate", "clk48m", SCM_GCCR, 0);
86 74
87 for (i = 0; i < ARRAY_SIZE(clk); i++) 75 for (i = 0; i < ARRAY_SIZE(clk); i++)
88 if (IS_ERR(clk[i])) 76 if (IS_ERR(clk[i]))
89 pr_err("imx1 clk %d: register failed with %ld\n", 77 pr_err("imx1 clk %d: register failed with %ld\n",
90 i, PTR_ERR(clk[i])); 78 i, PTR_ERR(clk[i]));
91 79
92 clk_register_clkdev(clk[dma_gate], "ahb", "imx1-dma"); 80 clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx-gpt.0");
93 clk_register_clkdev(clk[hclk], "ipg", "imx1-dma"); 81 clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx-gpt.0");
94 clk_register_clkdev(clk[per1], "per", "imx-gpt.0"); 82}
95 clk_register_clkdev(clk[hclk], "ipg", "imx-gpt.0"); 83
96 clk_register_clkdev(clk[per1], "per", "imx1-uart.0"); 84int __init mx1_clocks_init(unsigned long fref)
97 clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.0"); 85{
98 clk_register_clkdev(clk[per1], "per", "imx1-uart.1"); 86 ccm = MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR);
99 clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.1"); 87
100 clk_register_clkdev(clk[per1], "per", "imx1-uart.2"); 88 _mx1_clocks_init(fref);
101 clk_register_clkdev(clk[uart3_gate], "ipg", "imx1-uart.2"); 89
102 clk_register_clkdev(clk[hclk], NULL, "imx1-i2c.0"); 90 clk_register_clkdev(clk[IMX1_CLK_DMA_GATE], "ahb", "imx1-dma");
103 clk_register_clkdev(clk[per2], "per", "imx1-cspi.0"); 91 clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-dma");
104 clk_register_clkdev(clk[dummy], "ipg", "imx1-cspi.0"); 92 clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.0");
105 clk_register_clkdev(clk[per2], "per", "imx1-cspi.1"); 93 clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-uart.0");
106 clk_register_clkdev(clk[dummy], "ipg", "imx1-cspi.1"); 94 clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.1");
107 clk_register_clkdev(clk[per2], "per", "imx1-fb.0"); 95 clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-uart.1");
108 clk_register_clkdev(clk[dummy], "ipg", "imx1-fb.0"); 96 clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.2");
109 clk_register_clkdev(clk[dummy], "ahb", "imx1-fb.0"); 97 clk_register_clkdev(clk[IMX1_CLK_UART3_GATE], "ipg", "imx1-uart.2");
98 clk_register_clkdev(clk[IMX1_CLK_HCLK], NULL, "imx1-i2c.0");
99 clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-cspi.0");
100 clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-cspi.0");
101 clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-cspi.1");
102 clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-cspi.1");
103 clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-fb.0");
104 clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-fb.0");
105 clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ahb", "imx1-fb.0");
110 106
111 mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT); 107 mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT);
112 108
113 return 0; 109 return 0;
114} 110}
111
112static void __init mx1_clocks_init_dt(struct device_node *np)
113{
114 ccm = of_iomap(np, 0);
115 BUG_ON(!ccm);
116
117 _mx1_clocks_init(32768);
118
119 clk_data.clks = clk;
120 clk_data.clk_num = ARRAY_SIZE(clk);
121 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
122
123 mxc_timer_init_dt(of_find_compatible_node(NULL, NULL, "fsl,imx1-gpt"));
124}
125CLK_OF_DECLARE(imx1_ccm, "fsl,imx1-ccm", mx1_clocks_init_dt);