aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/imx
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-26 14:34:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-26 14:34:35 -0400
commit4aa705b18bf17c4ff33ff7bbcd3f0c596443fa81 (patch)
tree3b166bff290d123ccaa88598ad2d45be67f5b358 /drivers/clk/imx
parentc11d716218910c3aa2bac1bb641e6086ad649555 (diff)
parent2879e43f09122f8b3ef5456e3d7e48716b086e60 (diff)
Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform support updates from Kevin Hilman: "Our SoC branch usually contains expanded support for new SoCs and other core platform code. Some highlights from this round: - sunxi: SMP support for A23 SoC - socpga: big-endian support - pxa: conversion to common clock framework - bcm: SMP support for BCM63138 - imx: support new I.MX7D SoC - zte: basic support for ZX296702 SoC" * tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (134 commits) ARM: zx: Add basic defconfig support for ZX296702 ARM: dts: zx: add an initial zx296702 dts and doc clk: zx: add clock support to zx296702 dt-bindings: Add #defines for ZTE ZX296702 clocks ARM: socfpga: fix build error due to secondary_startup MAINTAINERS: ARM64: EXYNOS: Extend entry for ARM64 DTS ARM: ep93xx: simone: support for SPI-based MMC/SD cards MAINTAINERS: update Shawn's email to use kernel.org one ARM: socfpga: support suspend to ram ARM: socfpga: add CPU_METHOD_OF_DECLARE for Arria 10 ARM: socfpga: use CPU_METHOD_OF_DECLARE for socfpga_cyclone5 ARM: EXYNOS: register power domain driver from core_initcall ARM: EXYNOS: use PS_HOLD based poweroff for all supported SoCs ARM: SAMSUNG: Constify platform_device_id ARM: EXYNOS: Constify irq_domain_ops ARM: EXYNOS: add coupled cpuidle support for Exynos3250 ARM: EXYNOS: add exynos_get_boot_addr() helper ARM: EXYNOS: add exynos_set_boot_addr() helper ARM: EXYNOS: make exynos_core_restart() less verbose ARM: EXYNOS: fix exynos_boot_secondary() return value on timeout ...
Diffstat (limited to 'drivers/clk/imx')
-rw-r--r--drivers/clk/imx/Makefile26
-rw-r--r--drivers/clk/imx/clk-busy.c189
-rw-r--r--drivers/clk/imx/clk-cpu.c108
-rw-r--r--drivers/clk/imx/clk-fixup-div.c129
-rw-r--r--drivers/clk/imx/clk-fixup-mux.c108
-rw-r--r--drivers/clk/imx/clk-gate-exclusive.c94
-rw-r--r--drivers/clk/imx/clk-gate2.c160
-rw-r--r--drivers/clk/imx/clk-imx1.c122
-rw-r--r--drivers/clk/imx/clk-imx21.c175
-rw-r--r--drivers/clk/imx/clk-imx25.c262
-rw-r--r--drivers/clk/imx/clk-imx27.c263
-rw-r--r--drivers/clk/imx/clk-imx31.c221
-rw-r--r--drivers/clk/imx/clk-imx35.c310
-rw-r--r--drivers/clk/imx/clk-imx51-imx53.c570
-rw-r--r--drivers/clk/imx/clk-imx6q.c538
-rw-r--r--drivers/clk/imx/clk-imx6sl.c443
-rw-r--r--drivers/clk/imx/clk-imx6sx.c561
-rw-r--r--drivers/clk/imx/clk-imx7d.c860
-rw-r--r--drivers/clk/imx/clk-pfd.c158
-rw-r--r--drivers/clk/imx/clk-pllv1.c141
-rw-r--r--drivers/clk/imx/clk-pllv2.c266
-rw-r--r--drivers/clk/imx/clk-pllv3.c338
-rw-r--r--drivers/clk/imx/clk-vf610.c416
-rw-r--r--drivers/clk/imx/clk.c75
-rw-r--r--drivers/clk/imx/clk.h149
25 files changed, 6682 insertions, 0 deletions
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
new file mode 100644
index 000000000000..75fae169ce8f
--- /dev/null
+++ b/drivers/clk/imx/Makefile
@@ -0,0 +1,26 @@
1
2obj-y += \
3 clk.o \
4 clk-busy.o \
5 clk-cpu.o \
6 clk-fixup-div.o \
7 clk-fixup-mux.o \
8 clk-gate-exclusive.o \
9 clk-gate2.o \
10 clk-pllv1.o \
11 clk-pllv2.o \
12 clk-pllv3.o \
13 clk-pfd.o
14
15obj-$(CONFIG_SOC_IMX1) += clk-imx1.o
16obj-$(CONFIG_SOC_IMX21) += clk-imx21.o
17obj-$(CONFIG_SOC_IMX25) += clk-imx25.o
18obj-$(CONFIG_SOC_IMX27) += clk-imx27.o
19obj-$(CONFIG_SOC_IMX31) += clk-imx31.o
20obj-$(CONFIG_SOC_IMX35) += clk-imx35.o
21obj-$(CONFIG_SOC_IMX5) += clk-imx51-imx53.o
22obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o
23obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o
24obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o
25obj-$(CONFIG_SOC_IMX7D) += clk-imx7d.o
26obj-$(CONFIG_SOC_VF610) += clk-vf610.o
diff --git a/drivers/clk/imx/clk-busy.c b/drivers/clk/imx/clk-busy.c
new file mode 100644
index 000000000000..4bb1bc419b79
--- /dev/null
+++ b/drivers/clk/imx/clk-busy.c
@@ -0,0 +1,189 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/clk.h>
14#include <linux/clk-provider.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include <linux/jiffies.h>
18#include <linux/err.h>
19#include "clk.h"
20
21static int clk_busy_wait(void __iomem *reg, u8 shift)
22{
23 unsigned long timeout = jiffies + msecs_to_jiffies(10);
24
25 while (readl_relaxed(reg) & (1 << shift))
26 if (time_after(jiffies, timeout))
27 return -ETIMEDOUT;
28
29 return 0;
30}
31
32struct clk_busy_divider {
33 struct clk_divider div;
34 const struct clk_ops *div_ops;
35 void __iomem *reg;
36 u8 shift;
37};
38
39static inline struct clk_busy_divider *to_clk_busy_divider(struct clk_hw *hw)
40{
41 struct clk_divider *div = container_of(hw, struct clk_divider, hw);
42
43 return container_of(div, struct clk_busy_divider, div);
44}
45
46static unsigned long clk_busy_divider_recalc_rate(struct clk_hw *hw,
47 unsigned long parent_rate)
48{
49 struct clk_busy_divider *busy = to_clk_busy_divider(hw);
50
51 return busy->div_ops->recalc_rate(&busy->div.hw, parent_rate);
52}
53
54static long clk_busy_divider_round_rate(struct clk_hw *hw, unsigned long rate,
55 unsigned long *prate)
56{
57 struct clk_busy_divider *busy = to_clk_busy_divider(hw);
58
59 return busy->div_ops->round_rate(&busy->div.hw, rate, prate);
60}
61
62static int clk_busy_divider_set_rate(struct clk_hw *hw, unsigned long rate,
63 unsigned long parent_rate)
64{
65 struct clk_busy_divider *busy = to_clk_busy_divider(hw);
66 int ret;
67
68 ret = busy->div_ops->set_rate(&busy->div.hw, rate, parent_rate);
69 if (!ret)
70 ret = clk_busy_wait(busy->reg, busy->shift);
71
72 return ret;
73}
74
75static struct clk_ops clk_busy_divider_ops = {
76 .recalc_rate = clk_busy_divider_recalc_rate,
77 .round_rate = clk_busy_divider_round_rate,
78 .set_rate = clk_busy_divider_set_rate,
79};
80
81struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
82 void __iomem *reg, u8 shift, u8 width,
83 void __iomem *busy_reg, u8 busy_shift)
84{
85 struct clk_busy_divider *busy;
86 struct clk *clk;
87 struct clk_init_data init;
88
89 busy = kzalloc(sizeof(*busy), GFP_KERNEL);
90 if (!busy)
91 return ERR_PTR(-ENOMEM);
92
93 busy->reg = busy_reg;
94 busy->shift = busy_shift;
95
96 busy->div.reg = reg;
97 busy->div.shift = shift;
98 busy->div.width = width;
99 busy->div.lock = &imx_ccm_lock;
100 busy->div_ops = &clk_divider_ops;
101
102 init.name = name;
103 init.ops = &clk_busy_divider_ops;
104 init.flags = CLK_SET_RATE_PARENT;
105 init.parent_names = &parent_name;
106 init.num_parents = 1;
107
108 busy->div.hw.init = &init;
109
110 clk = clk_register(NULL, &busy->div.hw);
111 if (IS_ERR(clk))
112 kfree(busy);
113
114 return clk;
115}
116
117struct clk_busy_mux {
118 struct clk_mux mux;
119 const struct clk_ops *mux_ops;
120 void __iomem *reg;
121 u8 shift;
122};
123
124static inline struct clk_busy_mux *to_clk_busy_mux(struct clk_hw *hw)
125{
126 struct clk_mux *mux = container_of(hw, struct clk_mux, hw);
127
128 return container_of(mux, struct clk_busy_mux, mux);
129}
130
131static u8 clk_busy_mux_get_parent(struct clk_hw *hw)
132{
133 struct clk_busy_mux *busy = to_clk_busy_mux(hw);
134
135 return busy->mux_ops->get_parent(&busy->mux.hw);
136}
137
138static int clk_busy_mux_set_parent(struct clk_hw *hw, u8 index)
139{
140 struct clk_busy_mux *busy = to_clk_busy_mux(hw);
141 int ret;
142
143 ret = busy->mux_ops->set_parent(&busy->mux.hw, index);
144 if (!ret)
145 ret = clk_busy_wait(busy->reg, busy->shift);
146
147 return ret;
148}
149
150static struct clk_ops clk_busy_mux_ops = {
151 .get_parent = clk_busy_mux_get_parent,
152 .set_parent = clk_busy_mux_set_parent,
153};
154
155struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
156 u8 width, void __iomem *busy_reg, u8 busy_shift,
157 const char **parent_names, int num_parents)
158{
159 struct clk_busy_mux *busy;
160 struct clk *clk;
161 struct clk_init_data init;
162
163 busy = kzalloc(sizeof(*busy), GFP_KERNEL);
164 if (!busy)
165 return ERR_PTR(-ENOMEM);
166
167 busy->reg = busy_reg;
168 busy->shift = busy_shift;
169
170 busy->mux.reg = reg;
171 busy->mux.shift = shift;
172 busy->mux.mask = BIT(width) - 1;
173 busy->mux.lock = &imx_ccm_lock;
174 busy->mux_ops = &clk_mux_ops;
175
176 init.name = name;
177 init.ops = &clk_busy_mux_ops;
178 init.flags = 0;
179 init.parent_names = parent_names;
180 init.num_parents = num_parents;
181
182 busy->mux.hw.init = &init;
183
184 clk = clk_register(NULL, &busy->mux.hw);
185 if (IS_ERR(clk))
186 kfree(busy);
187
188 return clk;
189}
diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c
new file mode 100644
index 000000000000..9d46eac87f45
--- /dev/null
+++ b/drivers/clk/imx/clk-cpu.c
@@ -0,0 +1,108 @@
1/*
2 * Copyright (c) 2014 Lucas Stach <l.stach@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 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/slab.h>
15#include "clk.h"
16
17struct clk_cpu {
18 struct clk_hw hw;
19 struct clk *div;
20 struct clk *mux;
21 struct clk *pll;
22 struct clk *step;
23};
24
25static inline struct clk_cpu *to_clk_cpu(struct clk_hw *hw)
26{
27 return container_of(hw, struct clk_cpu, hw);
28}
29
30static unsigned long clk_cpu_recalc_rate(struct clk_hw *hw,
31 unsigned long parent_rate)
32{
33 struct clk_cpu *cpu = to_clk_cpu(hw);
34
35 return clk_get_rate(cpu->div);
36}
37
38static long clk_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
39 unsigned long *prate)
40{
41 struct clk_cpu *cpu = to_clk_cpu(hw);
42
43 return clk_round_rate(cpu->pll, rate);
44}
45
46static int clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
47 unsigned long parent_rate)
48{
49 struct clk_cpu *cpu = to_clk_cpu(hw);
50 int ret;
51
52 /* switch to PLL bypass clock */
53 ret = clk_set_parent(cpu->mux, cpu->step);
54 if (ret)
55 return ret;
56
57 /* reprogram PLL */
58 ret = clk_set_rate(cpu->pll, rate);
59 if (ret) {
60 clk_set_parent(cpu->mux, cpu->pll);
61 return ret;
62 }
63 /* switch back to PLL clock */
64 clk_set_parent(cpu->mux, cpu->pll);
65
66 /* Ensure the divider is what we expect */
67 clk_set_rate(cpu->div, rate);
68
69 return 0;
70}
71
72static const struct clk_ops clk_cpu_ops = {
73 .recalc_rate = clk_cpu_recalc_rate,
74 .round_rate = clk_cpu_round_rate,
75 .set_rate = clk_cpu_set_rate,
76};
77
78struct clk *imx_clk_cpu(const char *name, const char *parent_name,
79 struct clk *div, struct clk *mux, struct clk *pll,
80 struct clk *step)
81{
82 struct clk_cpu *cpu;
83 struct clk *clk;
84 struct clk_init_data init;
85
86 cpu = kzalloc(sizeof(*cpu), GFP_KERNEL);
87 if (!cpu)
88 return ERR_PTR(-ENOMEM);
89
90 cpu->div = div;
91 cpu->mux = mux;
92 cpu->pll = pll;
93 cpu->step = step;
94
95 init.name = name;
96 init.ops = &clk_cpu_ops;
97 init.flags = 0;
98 init.parent_names = &parent_name;
99 init.num_parents = 1;
100
101 cpu->hw.init = &init;
102
103 clk = clk_register(NULL, &cpu->hw);
104 if (IS_ERR(clk))
105 kfree(cpu);
106
107 return clk;
108}
diff --git a/drivers/clk/imx/clk-fixup-div.c b/drivers/clk/imx/clk-fixup-div.c
new file mode 100644
index 000000000000..21db020b1f2d
--- /dev/null
+++ b/drivers/clk/imx/clk-fixup-div.c
@@ -0,0 +1,129 @@
1/*
2 * Copyright (C) 2013 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk-provider.h>
13#include <linux/err.h>
14#include <linux/io.h>
15#include <linux/slab.h>
16#include "clk.h"
17
18#define to_clk_div(_hw) container_of(_hw, struct clk_divider, hw)
19#define div_mask(d) ((1 << (d->width)) - 1)
20
21/**
22 * struct clk_fixup_div - imx integer fixup divider clock
23 * @divider: the parent class
24 * @ops: pointer to clk_ops of parent class
25 * @fixup: a hook to fixup the write value
26 *
27 * The imx fixup divider clock is a subclass of basic clk_divider
28 * with an addtional fixup hook.
29 */
30struct clk_fixup_div {
31 struct clk_divider divider;
32 const struct clk_ops *ops;
33 void (*fixup)(u32 *val);
34};
35
36static inline struct clk_fixup_div *to_clk_fixup_div(struct clk_hw *hw)
37{
38 struct clk_divider *divider = to_clk_div(hw);
39
40 return container_of(divider, struct clk_fixup_div, divider);
41}
42
43static unsigned long clk_fixup_div_recalc_rate(struct clk_hw *hw,
44 unsigned long parent_rate)
45{
46 struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw);
47
48 return fixup_div->ops->recalc_rate(&fixup_div->divider.hw, parent_rate);
49}
50
51static long clk_fixup_div_round_rate(struct clk_hw *hw, unsigned long rate,
52 unsigned long *prate)
53{
54 struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw);
55
56 return fixup_div->ops->round_rate(&fixup_div->divider.hw, rate, prate);
57}
58
59static int clk_fixup_div_set_rate(struct clk_hw *hw, unsigned long rate,
60 unsigned long parent_rate)
61{
62 struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw);
63 struct clk_divider *div = to_clk_div(hw);
64 unsigned int divider, value;
65 unsigned long flags = 0;
66 u32 val;
67
68 divider = parent_rate / rate;
69
70 /* Zero based divider */
71 value = divider - 1;
72
73 if (value > div_mask(div))
74 value = div_mask(div);
75
76 spin_lock_irqsave(div->lock, flags);
77
78 val = readl(div->reg);
79 val &= ~(div_mask(div) << div->shift);
80 val |= value << div->shift;
81 fixup_div->fixup(&val);
82 writel(val, div->reg);
83
84 spin_unlock_irqrestore(div->lock, flags);
85
86 return 0;
87}
88
89static const struct clk_ops clk_fixup_div_ops = {
90 .recalc_rate = clk_fixup_div_recalc_rate,
91 .round_rate = clk_fixup_div_round_rate,
92 .set_rate = clk_fixup_div_set_rate,
93};
94
95struct clk *imx_clk_fixup_divider(const char *name, const char *parent,
96 void __iomem *reg, u8 shift, u8 width,
97 void (*fixup)(u32 *val))
98{
99 struct clk_fixup_div *fixup_div;
100 struct clk *clk;
101 struct clk_init_data init;
102
103 if (!fixup)
104 return ERR_PTR(-EINVAL);
105
106 fixup_div = kzalloc(sizeof(*fixup_div), GFP_KERNEL);
107 if (!fixup_div)
108 return ERR_PTR(-ENOMEM);
109
110 init.name = name;
111 init.ops = &clk_fixup_div_ops;
112 init.flags = CLK_SET_RATE_PARENT;
113 init.parent_names = parent ? &parent : NULL;
114 init.num_parents = parent ? 1 : 0;
115
116 fixup_div->divider.reg = reg;
117 fixup_div->divider.shift = shift;
118 fixup_div->divider.width = width;
119 fixup_div->divider.lock = &imx_ccm_lock;
120 fixup_div->divider.hw.init = &init;
121 fixup_div->ops = &clk_divider_ops;
122 fixup_div->fixup = fixup;
123
124 clk = clk_register(NULL, &fixup_div->divider.hw);
125 if (IS_ERR(clk))
126 kfree(fixup_div);
127
128 return clk;
129}
diff --git a/drivers/clk/imx/clk-fixup-mux.c b/drivers/clk/imx/clk-fixup-mux.c
new file mode 100644
index 000000000000..0d40b35c557c
--- /dev/null
+++ b/drivers/clk/imx/clk-fixup-mux.c
@@ -0,0 +1,108 @@
1/*
2 * Copyright (C) 2013 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk-provider.h>
13#include <linux/err.h>
14#include <linux/io.h>
15#include <linux/slab.h>
16#include "clk.h"
17
18#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
19
20/**
21 * struct clk_fixup_mux - imx integer fixup multiplexer clock
22 * @mux: the parent class
23 * @ops: pointer to clk_ops of parent class
24 * @fixup: a hook to fixup the write value
25 *
26 * The imx fixup multiplexer clock is a subclass of basic clk_mux
27 * with an addtional fixup hook.
28 */
29struct clk_fixup_mux {
30 struct clk_mux mux;
31 const struct clk_ops *ops;
32 void (*fixup)(u32 *val);
33};
34
35static inline struct clk_fixup_mux *to_clk_fixup_mux(struct clk_hw *hw)
36{
37 struct clk_mux *mux = to_clk_mux(hw);
38
39 return container_of(mux, struct clk_fixup_mux, mux);
40}
41
42static u8 clk_fixup_mux_get_parent(struct clk_hw *hw)
43{
44 struct clk_fixup_mux *fixup_mux = to_clk_fixup_mux(hw);
45
46 return fixup_mux->ops->get_parent(&fixup_mux->mux.hw);
47}
48
49static int clk_fixup_mux_set_parent(struct clk_hw *hw, u8 index)
50{
51 struct clk_fixup_mux *fixup_mux = to_clk_fixup_mux(hw);
52 struct clk_mux *mux = to_clk_mux(hw);
53 unsigned long flags = 0;
54 u32 val;
55
56 spin_lock_irqsave(mux->lock, flags);
57
58 val = readl(mux->reg);
59 val &= ~(mux->mask << mux->shift);
60 val |= index << mux->shift;
61 fixup_mux->fixup(&val);
62 writel(val, mux->reg);
63
64 spin_unlock_irqrestore(mux->lock, flags);
65
66 return 0;
67}
68
69static const struct clk_ops clk_fixup_mux_ops = {
70 .get_parent = clk_fixup_mux_get_parent,
71 .set_parent = clk_fixup_mux_set_parent,
72};
73
74struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
75 u8 shift, u8 width, const char **parents,
76 int num_parents, void (*fixup)(u32 *val))
77{
78 struct clk_fixup_mux *fixup_mux;
79 struct clk *clk;
80 struct clk_init_data init;
81
82 if (!fixup)
83 return ERR_PTR(-EINVAL);
84
85 fixup_mux = kzalloc(sizeof(*fixup_mux), GFP_KERNEL);
86 if (!fixup_mux)
87 return ERR_PTR(-ENOMEM);
88
89 init.name = name;
90 init.ops = &clk_fixup_mux_ops;
91 init.parent_names = parents;
92 init.num_parents = num_parents;
93 init.flags = 0;
94
95 fixup_mux->mux.reg = reg;
96 fixup_mux->mux.shift = shift;
97 fixup_mux->mux.mask = BIT(width) - 1;
98 fixup_mux->mux.lock = &imx_ccm_lock;
99 fixup_mux->mux.hw.init = &init;
100 fixup_mux->ops = &clk_mux_ops;
101 fixup_mux->fixup = fixup;
102
103 clk = clk_register(NULL, &fixup_mux->mux.hw);
104 if (IS_ERR(clk))
105 kfree(fixup_mux);
106
107 return clk;
108}
diff --git a/drivers/clk/imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c
new file mode 100644
index 000000000000..c12f5f2e04dc
--- /dev/null
+++ b/drivers/clk/imx/clk-gate-exclusive.c
@@ -0,0 +1,94 @@
1/*
2 * Copyright 2014 Freescale Semiconductor, Inc.
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
9#include <linux/clk-provider.h>
10#include <linux/err.h>
11#include <linux/io.h>
12#include <linux/slab.h>
13#include "clk.h"
14
15/**
16 * struct clk_gate_exclusive - i.MX specific gate clock which is mutually
17 * exclusive with other gate clocks
18 *
19 * @gate: the parent class
20 * @exclusive_mask: mask of gate bits which are mutually exclusive to this
21 * gate clock
22 *
23 * The imx exclusive gate clock is a subclass of basic clk_gate
24 * with an addtional mask to indicate which other gate bits in the same
25 * register is mutually exclusive to this gate clock.
26 */
27struct clk_gate_exclusive {
28 struct clk_gate gate;
29 u32 exclusive_mask;
30};
31
32static int clk_gate_exclusive_enable(struct clk_hw *hw)
33{
34 struct clk_gate *gate = container_of(hw, struct clk_gate, hw);
35 struct clk_gate_exclusive *exgate = container_of(gate,
36 struct clk_gate_exclusive, gate);
37 u32 val = readl(gate->reg);
38
39 if (val & exgate->exclusive_mask)
40 return -EBUSY;
41
42 return clk_gate_ops.enable(hw);
43}
44
45static void clk_gate_exclusive_disable(struct clk_hw *hw)
46{
47 clk_gate_ops.disable(hw);
48}
49
50static int clk_gate_exclusive_is_enabled(struct clk_hw *hw)
51{
52 return clk_gate_ops.is_enabled(hw);
53}
54
55static const struct clk_ops clk_gate_exclusive_ops = {
56 .enable = clk_gate_exclusive_enable,
57 .disable = clk_gate_exclusive_disable,
58 .is_enabled = clk_gate_exclusive_is_enabled,
59};
60
61struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
62 void __iomem *reg, u8 shift, u32 exclusive_mask)
63{
64 struct clk_gate_exclusive *exgate;
65 struct clk_gate *gate;
66 struct clk *clk;
67 struct clk_init_data init;
68
69 if (exclusive_mask == 0)
70 return ERR_PTR(-EINVAL);
71
72 exgate = kzalloc(sizeof(*exgate), GFP_KERNEL);
73 if (!exgate)
74 return ERR_PTR(-ENOMEM);
75 gate = &exgate->gate;
76
77 init.name = name;
78 init.ops = &clk_gate_exclusive_ops;
79 init.flags = CLK_SET_RATE_PARENT;
80 init.parent_names = parent ? &parent : NULL;
81 init.num_parents = parent ? 1 : 0;
82
83 gate->reg = reg;
84 gate->bit_idx = shift;
85 gate->lock = &imx_ccm_lock;
86 gate->hw.init = &init;
87 exgate->exclusive_mask = exclusive_mask;
88
89 clk = clk_register(NULL, &gate->hw);
90 if (IS_ERR(clk))
91 kfree(exgate);
92
93 return clk;
94}
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
new file mode 100644
index 000000000000..8935bff99fe7
--- /dev/null
+++ b/drivers/clk/imx/clk-gate2.c
@@ -0,0 +1,160 @@
1/*
2 * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
3 * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Gated clock implementation
10 */
11
12#include <linux/clk-provider.h>
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/io.h>
16#include <linux/err.h>
17#include <linux/string.h>
18#include "clk.h"
19
20/**
21 * DOC: basic gatable clock which can gate and ungate it's ouput
22 *
23 * Traits of this clock:
24 * prepare - clk_(un)prepare only ensures parent is (un)prepared
25 * enable - clk_enable and clk_disable are functional & control gating
26 * rate - inherits rate from parent. No clk_set_rate support
27 * parent - fixed parent. No clk_set_parent support
28 */
29
30struct clk_gate2 {
31 struct clk_hw hw;
32 void __iomem *reg;
33 u8 bit_idx;
34 u8 flags;
35 spinlock_t *lock;
36 unsigned int *share_count;
37};
38
39#define to_clk_gate2(_hw) container_of(_hw, struct clk_gate2, hw)
40
41static int clk_gate2_enable(struct clk_hw *hw)
42{
43 struct clk_gate2 *gate = to_clk_gate2(hw);
44 u32 reg;
45 unsigned long flags = 0;
46
47 spin_lock_irqsave(gate->lock, flags);
48
49 if (gate->share_count && (*gate->share_count)++ > 0)
50 goto out;
51
52 reg = readl(gate->reg);
53 reg |= 3 << gate->bit_idx;
54 writel(reg, gate->reg);
55
56out:
57 spin_unlock_irqrestore(gate->lock, flags);
58
59 return 0;
60}
61
62static void clk_gate2_disable(struct clk_hw *hw)
63{
64 struct clk_gate2 *gate = to_clk_gate2(hw);
65 u32 reg;
66 unsigned long flags = 0;
67
68 spin_lock_irqsave(gate->lock, flags);
69
70 if (gate->share_count) {
71 if (WARN_ON(*gate->share_count == 0))
72 goto out;
73 else if (--(*gate->share_count) > 0)
74 goto out;
75 }
76
77 reg = readl(gate->reg);
78 reg &= ~(3 << gate->bit_idx);
79 writel(reg, gate->reg);
80
81out:
82 spin_unlock_irqrestore(gate->lock, flags);
83}
84
85static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx)
86{
87 u32 val = readl(reg);
88
89 if (((val >> bit_idx) & 1) == 1)
90 return 1;
91
92 return 0;
93}
94
95static int clk_gate2_is_enabled(struct clk_hw *hw)
96{
97 struct clk_gate2 *gate = to_clk_gate2(hw);
98
99 return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
100}
101
102static void clk_gate2_disable_unused(struct clk_hw *hw)
103{
104 struct clk_gate2 *gate = to_clk_gate2(hw);
105 unsigned long flags = 0;
106 u32 reg;
107
108 spin_lock_irqsave(gate->lock, flags);
109
110 if (!gate->share_count || *gate->share_count == 0) {
111 reg = readl(gate->reg);
112 reg &= ~(3 << gate->bit_idx);
113 writel(reg, gate->reg);
114 }
115
116 spin_unlock_irqrestore(gate->lock, flags);
117}
118
119static struct clk_ops clk_gate2_ops = {
120 .enable = clk_gate2_enable,
121 .disable = clk_gate2_disable,
122 .disable_unused = clk_gate2_disable_unused,
123 .is_enabled = clk_gate2_is_enabled,
124};
125
126struct clk *clk_register_gate2(struct device *dev, const char *name,
127 const char *parent_name, unsigned long flags,
128 void __iomem *reg, u8 bit_idx,
129 u8 clk_gate2_flags, spinlock_t *lock,
130 unsigned int *share_count)
131{
132 struct clk_gate2 *gate;
133 struct clk *clk;
134 struct clk_init_data init;
135
136 gate = kzalloc(sizeof(struct clk_gate2), GFP_KERNEL);
137 if (!gate)
138 return ERR_PTR(-ENOMEM);
139
140 /* struct clk_gate2 assignments */
141 gate->reg = reg;
142 gate->bit_idx = bit_idx;
143 gate->flags = clk_gate2_flags;
144 gate->lock = lock;
145 gate->share_count = share_count;
146
147 init.name = name;
148 init.ops = &clk_gate2_ops;
149 init.flags = flags;
150 init.parent_names = parent_name ? &parent_name : NULL;
151 init.num_parents = parent_name ? 1 : 0;
152
153 gate->hw.init = &init;
154
155 clk = clk_register(dev, &gate->hw);
156 if (IS_ERR(clk))
157 kfree(gate);
158
159 return clk;
160}
diff --git a/drivers/clk/imx/clk-imx1.c b/drivers/clk/imx/clk-imx1.c
new file mode 100644
index 000000000000..c2647fa19f28
--- /dev/null
+++ b/drivers/clk/imx/clk-imx1.c
@@ -0,0 +1,122 @@
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#include <soc/imx/timer.h>
27#include <asm/irq.h>
28
29#include "clk.h"
30
31#define MX1_CCM_BASE_ADDR 0x0021b000
32#define MX1_TIM1_BASE_ADDR 0x00220000
33#define MX1_TIM1_INT (NR_IRQS_LEGACY + 59)
34
35static const char *prem_sel_clks[] = { "clk32_premult", "clk16m", };
36static const char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m",
37 "prem", "fclk", };
38
39static struct clk *clk[IMX1_CLK_MAX];
40static struct clk_onecell_data clk_data;
41
42static void __iomem *ccm __initdata;
43#define CCM_CSCR (ccm + 0x0000)
44#define CCM_MPCTL0 (ccm + 0x0004)
45#define CCM_SPCTL0 (ccm + 0x000c)
46#define CCM_PCDR (ccm + 0x0020)
47#define SCM_GCCR (ccm + 0x0810)
48
49static void __init _mx1_clocks_init(unsigned long fref)
50{
51 clk[IMX1_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
52 clk[IMX1_CLK_CLK32] = imx_obtain_fixed_clock("clk32", fref);
53 clk[IMX1_CLK_CLK16M_EXT] = imx_clk_fixed("clk16m_ext", 16000000);
54 clk[IMX1_CLK_CLK16M] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17);
55 clk[IMX1_CLK_CLK32_PREMULT] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1);
56 clk[IMX1_CLK_PREM] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks, ARRAY_SIZE(prem_sel_clks));
57 clk[IMX1_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX1, "mpll", "clk32_premult", CCM_MPCTL0);
58 clk[IMX1_CLK_MPLL_GATE] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0);
59 clk[IMX1_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX1, "spll", "prem", CCM_SPCTL0);
60 clk[IMX1_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1);
61 clk[IMX1_CLK_MCU] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1);
62 clk[IMX1_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 15, 1);
63 clk[IMX1_CLK_HCLK] = imx_clk_divider("hclk", "spll_gate", CCM_CSCR, 10, 4);
64 clk[IMX1_CLK_CLK48M] = imx_clk_divider("clk48m", "spll_gate", CCM_CSCR, 26, 3);
65 clk[IMX1_CLK_PER1] = imx_clk_divider("per1", "spll_gate", CCM_PCDR, 0, 4);
66 clk[IMX1_CLK_PER2] = imx_clk_divider("per2", "spll_gate", CCM_PCDR, 4, 4);
67 clk[IMX1_CLK_PER3] = imx_clk_divider("per3", "spll_gate", CCM_PCDR, 16, 7);
68 clk[IMX1_CLK_CLKO] = imx_clk_mux("clko", CCM_CSCR, 29, 3, clko_sel_clks, ARRAY_SIZE(clko_sel_clks));
69 clk[IMX1_CLK_UART3_GATE] = imx_clk_gate("uart3_gate", "hclk", SCM_GCCR, 6);
70 clk[IMX1_CLK_SSI2_GATE] = imx_clk_gate("ssi2_gate", "hclk", SCM_GCCR, 5);
71 clk[IMX1_CLK_BROM_GATE] = imx_clk_gate("brom_gate", "hclk", SCM_GCCR, 4);
72 clk[IMX1_CLK_DMA_GATE] = imx_clk_gate("dma_gate", "hclk", SCM_GCCR, 3);
73 clk[IMX1_CLK_CSI_GATE] = imx_clk_gate("csi_gate", "hclk", SCM_GCCR, 2);
74 clk[IMX1_CLK_MMA_GATE] = imx_clk_gate("mma_gate", "hclk", SCM_GCCR, 1);
75 clk[IMX1_CLK_USBD_GATE] = imx_clk_gate("usbd_gate", "clk48m", SCM_GCCR, 0);
76
77 imx_check_clocks(clk, ARRAY_SIZE(clk));
78}
79
80int __init mx1_clocks_init(unsigned long fref)
81{
82 ccm = ioremap(MX1_CCM_BASE_ADDR, SZ_4K);
83 BUG_ON(!ccm);
84
85 _mx1_clocks_init(fref);
86
87 clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx-gpt.0");
88 clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx-gpt.0");
89 clk_register_clkdev(clk[IMX1_CLK_DMA_GATE], "ahb", "imx1-dma");
90 clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-dma");
91 clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.0");
92 clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-uart.0");
93 clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.1");
94 clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-uart.1");
95 clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.2");
96 clk_register_clkdev(clk[IMX1_CLK_UART3_GATE], "ipg", "imx1-uart.2");
97 clk_register_clkdev(clk[IMX1_CLK_HCLK], NULL, "imx1-i2c.0");
98 clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-cspi.0");
99 clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-cspi.0");
100 clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-cspi.1");
101 clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-cspi.1");
102 clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-fb.0");
103 clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-fb.0");
104 clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ahb", "imx1-fb.0");
105
106 mxc_timer_init(MX1_TIM1_BASE_ADDR, MX1_TIM1_INT, GPT_TYPE_IMX1);
107
108 return 0;
109}
110
111static void __init mx1_clocks_init_dt(struct device_node *np)
112{
113 ccm = of_iomap(np, 0);
114 BUG_ON(!ccm);
115
116 _mx1_clocks_init(32768);
117
118 clk_data.clks = clk;
119 clk_data.clk_num = ARRAY_SIZE(clk);
120 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
121}
122CLK_OF_DECLARE(imx1_ccm, "fsl,imx1-ccm", mx1_clocks_init_dt);
diff --git a/drivers/clk/imx/clk-imx21.c b/drivers/clk/imx/clk-imx21.c
new file mode 100644
index 000000000000..dba987e3b89f
--- /dev/null
+++ b/drivers/clk/imx/clk-imx21.c
@@ -0,0 +1,175 @@
1/*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
4 * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/clkdev.h>
15#include <linux/of.h>
16#include <linux/of_address.h>
17#include <dt-bindings/clock/imx21-clock.h>
18#include <soc/imx/timer.h>
19#include <asm/irq.h>
20
21#include "clk.h"
22
23#define MX21_CCM_BASE_ADDR 0x10027000
24#define MX21_GPT1_BASE_ADDR 0x10003000
25#define MX21_INT_GPT1 (NR_IRQS_LEGACY + 26)
26
27static void __iomem *ccm __initdata;
28
29/* Register offsets */
30#define CCM_CSCR (ccm + 0x00)
31#define CCM_MPCTL0 (ccm + 0x04)
32#define CCM_SPCTL0 (ccm + 0x0c)
33#define CCM_PCDR0 (ccm + 0x18)
34#define CCM_PCDR1 (ccm + 0x1c)
35#define CCM_PCCR0 (ccm + 0x20)
36#define CCM_PCCR1 (ccm + 0x24)
37
38static const char *mpll_osc_sel_clks[] = { "ckih_gate", "ckih_div1p5", };
39static const char *mpll_sel_clks[] = { "fpm_gate", "mpll_osc_sel", };
40static const char *spll_sel_clks[] = { "fpm_gate", "mpll_osc_sel", };
41static const char *ssi_sel_clks[] = { "spll_gate", "mpll_gate", };
42
43static struct clk *clk[IMX21_CLK_MAX];
44static struct clk_onecell_data clk_data;
45
46static void __init _mx21_clocks_init(unsigned long lref, unsigned long href)
47{
48 BUG_ON(!ccm);
49
50 clk[IMX21_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
51 clk[IMX21_CLK_CKIL] = imx_obtain_fixed_clock("ckil", lref);
52 clk[IMX21_CLK_CKIH] = imx_obtain_fixed_clock("ckih", href);
53 clk[IMX21_CLK_FPM] = imx_clk_fixed_factor("fpm", "ckil", 512, 1);
54 clk[IMX21_CLK_CKIH_DIV1P5] = imx_clk_fixed_factor("ckih_div1p5", "ckih_gate", 2, 3);
55
56 clk[IMX21_CLK_MPLL_GATE] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0);
57 clk[IMX21_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1);
58 clk[IMX21_CLK_FPM_GATE] = imx_clk_gate("fpm_gate", "fpm", CCM_CSCR, 2);
59 clk[IMX21_CLK_CKIH_GATE] = imx_clk_gate_dis("ckih_gate", "ckih", CCM_CSCR, 3);
60 clk[IMX21_CLK_MPLL_OSC_SEL] = imx_clk_mux("mpll_osc_sel", CCM_CSCR, 4, 1, mpll_osc_sel_clks, ARRAY_SIZE(mpll_osc_sel_clks));
61 clk[IMX21_CLK_IPG] = imx_clk_divider("ipg", "hclk", CCM_CSCR, 9, 1);
62 clk[IMX21_CLK_HCLK] = imx_clk_divider("hclk", "fclk", CCM_CSCR, 10, 4);
63 clk[IMX21_CLK_MPLL_SEL] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, ARRAY_SIZE(mpll_sel_clks));
64 clk[IMX21_CLK_SPLL_SEL] = imx_clk_mux("spll_sel", CCM_CSCR, 17, 1, spll_sel_clks, ARRAY_SIZE(spll_sel_clks));
65 clk[IMX21_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", CCM_CSCR, 19, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
66 clk[IMX21_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", CCM_CSCR, 20, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
67 clk[IMX21_CLK_USB_DIV] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 26, 3);
68 clk[IMX21_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 29, 3);
69
70 clk[IMX21_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX21, "mpll", "mpll_sel", CCM_MPCTL0);
71
72 clk[IMX21_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX21, "spll", "spll_sel", CCM_SPCTL0);
73
74 clk[IMX21_CLK_NFC_DIV] = imx_clk_divider("nfc_div", "fclk", CCM_PCDR0, 12, 4);
75 clk[IMX21_CLK_SSI1_DIV] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6);
76 clk[IMX21_CLK_SSI2_DIV] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 6);
77
78 clk[IMX21_CLK_PER1] = imx_clk_divider("per1", "mpll_gate", CCM_PCDR1, 0, 6);
79 clk[IMX21_CLK_PER2] = imx_clk_divider("per2", "mpll_gate", CCM_PCDR1, 8, 6);
80 clk[IMX21_CLK_PER3] = imx_clk_divider("per3", "mpll_gate", CCM_PCDR1, 16, 6);
81 clk[IMX21_CLK_PER4] = imx_clk_divider("per4", "mpll_gate", CCM_PCDR1, 24, 6);
82
83 clk[IMX21_CLK_UART1_IPG_GATE] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR0, 0);
84 clk[IMX21_CLK_UART2_IPG_GATE] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR0, 1);
85 clk[IMX21_CLK_UART3_IPG_GATE] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR0, 2);
86 clk[IMX21_CLK_UART4_IPG_GATE] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR0, 3);
87 clk[IMX21_CLK_CSPI1_IPG_GATE] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 4);
88 clk[IMX21_CLK_CSPI2_IPG_GATE] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 5);
89 clk[IMX21_CLK_SSI1_GATE] = imx_clk_gate("ssi1_gate", "ipg", CCM_PCCR0, 6);
90 clk[IMX21_CLK_SSI2_GATE] = imx_clk_gate("ssi2_gate", "ipg", CCM_PCCR0, 7);
91 clk[IMX21_CLK_SDHC1_IPG_GATE] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 9);
92 clk[IMX21_CLK_SDHC2_IPG_GATE] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 10);
93 clk[IMX21_CLK_GPIO_GATE] = imx_clk_gate("gpio_gate", "ipg", CCM_PCCR0, 11);
94 clk[IMX21_CLK_I2C_GATE] = imx_clk_gate("i2c_gate", "ipg", CCM_PCCR0, 12);
95 clk[IMX21_CLK_DMA_GATE] = imx_clk_gate("dma_gate", "ipg", CCM_PCCR0, 13);
96 clk[IMX21_CLK_USB_GATE] = imx_clk_gate("usb_gate", "usb_div", CCM_PCCR0, 14);
97 clk[IMX21_CLK_EMMA_GATE] = imx_clk_gate("emma_gate", "ipg", CCM_PCCR0, 15);
98 clk[IMX21_CLK_SSI2_BAUD_GATE] = imx_clk_gate("ssi2_baud_gate", "ipg", CCM_PCCR0, 16);
99 clk[IMX21_CLK_SSI1_BAUD_GATE] = imx_clk_gate("ssi1_baud_gate", "ipg", CCM_PCCR0, 17);
100 clk[IMX21_CLK_LCDC_IPG_GATE] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 18);
101 clk[IMX21_CLK_NFC_GATE] = imx_clk_gate("nfc_gate", "nfc_div", CCM_PCCR0, 19);
102 clk[IMX21_CLK_SLCDC_HCLK_GATE] = imx_clk_gate("slcdc_hclk_gate", "hclk", CCM_PCCR0, 21);
103 clk[IMX21_CLK_PER4_GATE] = imx_clk_gate("per4_gate", "per4", CCM_PCCR0, 22);
104 clk[IMX21_CLK_BMI_GATE] = imx_clk_gate("bmi_gate", "hclk", CCM_PCCR0, 23);
105 clk[IMX21_CLK_USB_HCLK_GATE] = imx_clk_gate("usb_hclk_gate", "hclk", CCM_PCCR0, 24);
106 clk[IMX21_CLK_SLCDC_GATE] = imx_clk_gate("slcdc_gate", "hclk", CCM_PCCR0, 25);
107 clk[IMX21_CLK_LCDC_HCLK_GATE] = imx_clk_gate("lcdc_hclk_gate", "hclk", CCM_PCCR0, 26);
108 clk[IMX21_CLK_EMMA_HCLK_GATE] = imx_clk_gate("emma_hclk_gate", "hclk", CCM_PCCR0, 27);
109 clk[IMX21_CLK_BROM_GATE] = imx_clk_gate("brom_gate", "hclk", CCM_PCCR0, 28);
110 clk[IMX21_CLK_DMA_HCLK_GATE] = imx_clk_gate("dma_hclk_gate", "hclk", CCM_PCCR0, 30);
111 clk[IMX21_CLK_CSI_HCLK_GATE] = imx_clk_gate("csi_hclk_gate", "hclk", CCM_PCCR0, 31);
112
113 clk[IMX21_CLK_CSPI3_IPG_GATE] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR1, 23);
114 clk[IMX21_CLK_WDOG_GATE] = imx_clk_gate("wdog_gate", "ipg", CCM_PCCR1, 24);
115 clk[IMX21_CLK_GPT1_IPG_GATE] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR1, 25);
116 clk[IMX21_CLK_GPT2_IPG_GATE] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR1, 26);
117 clk[IMX21_CLK_GPT3_IPG_GATE] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR1, 27);
118 clk[IMX21_CLK_PWM_IPG_GATE] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR1, 28);
119 clk[IMX21_CLK_RTC_GATE] = imx_clk_gate("rtc_gate", "ipg", CCM_PCCR1, 29);
120 clk[IMX21_CLK_KPP_GATE] = imx_clk_gate("kpp_gate", "ipg", CCM_PCCR1, 30);
121 clk[IMX21_CLK_OWIRE_GATE] = imx_clk_gate("owire_gate", "ipg", CCM_PCCR1, 31);
122
123 imx_check_clocks(clk, ARRAY_SIZE(clk));
124}
125
126int __init mx21_clocks_init(unsigned long lref, unsigned long href)
127{
128 ccm = ioremap(MX21_CCM_BASE_ADDR, SZ_2K);
129
130 _mx21_clocks_init(lref, href);
131
132 clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.0");
133 clk_register_clkdev(clk[IMX21_CLK_UART1_IPG_GATE], "ipg", "imx21-uart.0");
134 clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.1");
135 clk_register_clkdev(clk[IMX21_CLK_UART2_IPG_GATE], "ipg", "imx21-uart.1");
136 clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.2");
137 clk_register_clkdev(clk[IMX21_CLK_UART3_IPG_GATE], "ipg", "imx21-uart.2");
138 clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.3");
139 clk_register_clkdev(clk[IMX21_CLK_UART4_IPG_GATE], "ipg", "imx21-uart.3");
140 clk_register_clkdev(clk[IMX21_CLK_GPT1_IPG_GATE], "ipg", "imx-gpt.0");
141 clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx-gpt.0");
142 clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.0");
143 clk_register_clkdev(clk[IMX21_CLK_CSPI1_IPG_GATE], "ipg", "imx21-cspi.0");
144 clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.1");
145 clk_register_clkdev(clk[IMX21_CLK_CSPI2_IPG_GATE], "ipg", "imx21-cspi.1");
146 clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.2");
147 clk_register_clkdev(clk[IMX21_CLK_CSPI3_IPG_GATE], "ipg", "imx21-cspi.2");
148 clk_register_clkdev(clk[IMX21_CLK_PER3], "per", "imx21-fb.0");
149 clk_register_clkdev(clk[IMX21_CLK_LCDC_IPG_GATE], "ipg", "imx21-fb.0");
150 clk_register_clkdev(clk[IMX21_CLK_LCDC_HCLK_GATE], "ahb", "imx21-fb.0");
151 clk_register_clkdev(clk[IMX21_CLK_USB_GATE], "per", "imx21-hcd.0");
152 clk_register_clkdev(clk[IMX21_CLK_USB_HCLK_GATE], "ahb", "imx21-hcd.0");
153 clk_register_clkdev(clk[IMX21_CLK_NFC_GATE], NULL, "imx21-nand.0");
154 clk_register_clkdev(clk[IMX21_CLK_DMA_HCLK_GATE], "ahb", "imx21-dma");
155 clk_register_clkdev(clk[IMX21_CLK_DMA_GATE], "ipg", "imx21-dma");
156 clk_register_clkdev(clk[IMX21_CLK_WDOG_GATE], NULL, "imx2-wdt.0");
157 clk_register_clkdev(clk[IMX21_CLK_I2C_GATE], NULL, "imx21-i2c.0");
158 clk_register_clkdev(clk[IMX21_CLK_OWIRE_GATE], NULL, "mxc_w1.0");
159
160 mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1, GPT_TYPE_IMX21);
161
162 return 0;
163}
164
165static void __init mx21_clocks_init_dt(struct device_node *np)
166{
167 ccm = of_iomap(np, 0);
168
169 _mx21_clocks_init(32768, 26000000);
170
171 clk_data.clks = clk;
172 clk_data.clk_num = ARRAY_SIZE(clk);
173 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
174}
175CLK_OF_DECLARE(imx27_ccm, "fsl,imx21-ccm", mx21_clocks_init_dt);
diff --git a/drivers/clk/imx/clk-imx25.c b/drivers/clk/imx/clk-imx25.c
new file mode 100644
index 000000000000..ec1a4c1dacf1
--- /dev/null
+++ b/drivers/clk/imx/clk-imx25.c
@@ -0,0 +1,262 @@
1/*
2 * Copyright (C) 2009 by Sascha Hauer, Pengutronix
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
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
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 * MA 02110-1301, USA.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/list.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24#include <linux/clkdev.h>
25#include <linux/err.h>
26#include <linux/of.h>
27#include <linux/of_address.h>
28#include <linux/of_irq.h>
29
30#include "clk.h"
31
32#define CCM_MPCTL 0x00
33#define CCM_UPCTL 0x04
34#define CCM_CCTL 0x08
35#define CCM_CGCR0 0x0C
36#define CCM_CGCR1 0x10
37#define CCM_CGCR2 0x14
38#define CCM_PCDR0 0x18
39#define CCM_PCDR1 0x1C
40#define CCM_PCDR2 0x20
41#define CCM_PCDR3 0x24
42#define CCM_RCSR 0x28
43#define CCM_CRDR 0x2C
44#define CCM_DCVR0 0x30
45#define CCM_DCVR1 0x34
46#define CCM_DCVR2 0x38
47#define CCM_DCVR3 0x3c
48#define CCM_LTR0 0x40
49#define CCM_LTR1 0x44
50#define CCM_LTR2 0x48
51#define CCM_LTR3 0x4c
52#define CCM_MCR 0x64
53
54#define ccm(x) (ccm_base + (x))
55
56static struct clk_onecell_data clk_data;
57
58static const char *cpu_sel_clks[] = { "mpll", "mpll_cpu_3_4", };
59static const char *per_sel_clks[] = { "ahb", "upll", };
60static const char *cko_sel_clks[] = { "dummy", "osc", "cpu", "ahb",
61 "ipg", "dummy", "dummy", "dummy",
62 "dummy", "dummy", "per0", "per2",
63 "per13", "per14", "usbotg_ahb", "dummy",};
64
65enum mx25_clks {
66 dummy, osc, mpll, upll, mpll_cpu_3_4, cpu_sel, cpu, ahb, usb_div, ipg,
67 per0_sel, per1_sel, per2_sel, per3_sel, per4_sel, per5_sel, per6_sel,
68 per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel,
69 per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5,
70 per6, per7, per8, per9, per10, per11, per12, per13, per14, per15,
71 csi_ipg_per, epit_ipg_per, esai_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per,
72 gpt_ipg_per, i2c_ipg_per, lcdc_ipg_per, nfc_ipg_per, owire_ipg_per,
73 pwm_ipg_per, sim1_ipg_per, sim2_ipg_per, ssi1_ipg_per, ssi2_ipg_per,
74 uart_ipg_per, ata_ahb, reserved1, csi_ahb, emi_ahb, esai_ahb, esdhc1_ahb,
75 esdhc2_ahb, fec_ahb, lcdc_ahb, rtic_ahb, sdma_ahb, slcdc_ahb, usbotg_ahb,
76 reserved2, reserved3, reserved4, reserved5, can1_ipg, can2_ipg, csi_ipg,
77 cspi1_ipg, cspi2_ipg, cspi3_ipg, dryice_ipg, ect_ipg, epit1_ipg, epit2_ipg,
78 reserved6, esdhc1_ipg, esdhc2_ipg, fec_ipg, reserved7, reserved8, reserved9,
79 gpt1_ipg, gpt2_ipg, gpt3_ipg, gpt4_ipg, reserved10, reserved11, reserved12,
80 iim_ipg, reserved13, reserved14, kpp_ipg, lcdc_ipg, reserved15, pwm1_ipg,
81 pwm2_ipg, pwm3_ipg, pwm4_ipg, rngb_ipg, reserved16, scc_ipg, sdma_ipg,
82 sim1_ipg, sim2_ipg, slcdc_ipg, spba_ipg, ssi1_ipg, ssi2_ipg, tsc_ipg,
83 uart1_ipg, uart2_ipg, uart3_ipg, uart4_ipg, uart5_ipg, reserved17,
84 wdt_ipg, cko_div, cko_sel, cko, clk_max
85};
86
87static struct clk *clk[clk_max];
88
89static int __init __mx25_clocks_init(unsigned long osc_rate,
90 void __iomem *ccm_base)
91{
92 BUG_ON(!ccm_base);
93
94 clk[dummy] = imx_clk_fixed("dummy", 0);
95 clk[osc] = imx_clk_fixed("osc", osc_rate);
96 clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "mpll", "osc", ccm(CCM_MPCTL));
97 clk[upll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "upll", "osc", ccm(CCM_UPCTL));
98 clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
99 clk[cpu_sel] = imx_clk_mux("cpu_sel", ccm(CCM_CCTL), 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
100 clk[cpu] = imx_clk_divider("cpu", "cpu_sel", ccm(CCM_CCTL), 30, 2);
101 clk[ahb] = imx_clk_divider("ahb", "cpu", ccm(CCM_CCTL), 28, 2);
102 clk[usb_div] = imx_clk_divider("usb_div", "upll", ccm(CCM_CCTL), 16, 6);
103 clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
104 clk[per0_sel] = imx_clk_mux("per0_sel", ccm(CCM_MCR), 0, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
105 clk[per1_sel] = imx_clk_mux("per1_sel", ccm(CCM_MCR), 1, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
106 clk[per2_sel] = imx_clk_mux("per2_sel", ccm(CCM_MCR), 2, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
107 clk[per3_sel] = imx_clk_mux("per3_sel", ccm(CCM_MCR), 3, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
108 clk[per4_sel] = imx_clk_mux("per4_sel", ccm(CCM_MCR), 4, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
109 clk[per5_sel] = imx_clk_mux("per5_sel", ccm(CCM_MCR), 5, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
110 clk[per6_sel] = imx_clk_mux("per6_sel", ccm(CCM_MCR), 6, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
111 clk[per7_sel] = imx_clk_mux("per7_sel", ccm(CCM_MCR), 7, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
112 clk[per8_sel] = imx_clk_mux("per8_sel", ccm(CCM_MCR), 8, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
113 clk[per9_sel] = imx_clk_mux("per9_sel", ccm(CCM_MCR), 9, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
114 clk[per10_sel] = imx_clk_mux("per10_sel", ccm(CCM_MCR), 10, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
115 clk[per11_sel] = imx_clk_mux("per11_sel", ccm(CCM_MCR), 11, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
116 clk[per12_sel] = imx_clk_mux("per12_sel", ccm(CCM_MCR), 12, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
117 clk[per13_sel] = imx_clk_mux("per13_sel", ccm(CCM_MCR), 13, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
118 clk[per14_sel] = imx_clk_mux("per14_sel", ccm(CCM_MCR), 14, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
119 clk[per15_sel] = imx_clk_mux("per15_sel", ccm(CCM_MCR), 15, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
120 clk[cko_div] = imx_clk_divider("cko_div", "cko_sel", ccm(CCM_MCR), 24, 6);
121 clk[cko_sel] = imx_clk_mux("cko_sel", ccm(CCM_MCR), 20, 4, cko_sel_clks, ARRAY_SIZE(cko_sel_clks));
122 clk[cko] = imx_clk_gate("cko", "cko_div", ccm(CCM_MCR), 30);
123 clk[per0] = imx_clk_divider("per0", "per0_sel", ccm(CCM_PCDR0), 0, 6);
124 clk[per1] = imx_clk_divider("per1", "per1_sel", ccm(CCM_PCDR0), 8, 6);
125 clk[per2] = imx_clk_divider("per2", "per2_sel", ccm(CCM_PCDR0), 16, 6);
126 clk[per3] = imx_clk_divider("per3", "per3_sel", ccm(CCM_PCDR0), 24, 6);
127 clk[per4] = imx_clk_divider("per4", "per4_sel", ccm(CCM_PCDR1), 0, 6);
128 clk[per5] = imx_clk_divider("per5", "per5_sel", ccm(CCM_PCDR1), 8, 6);
129 clk[per6] = imx_clk_divider("per6", "per6_sel", ccm(CCM_PCDR1), 16, 6);
130 clk[per7] = imx_clk_divider("per7", "per7_sel", ccm(CCM_PCDR1), 24, 6);
131 clk[per8] = imx_clk_divider("per8", "per8_sel", ccm(CCM_PCDR2), 0, 6);
132 clk[per9] = imx_clk_divider("per9", "per9_sel", ccm(CCM_PCDR2), 8, 6);
133 clk[per10] = imx_clk_divider("per10", "per10_sel", ccm(CCM_PCDR2), 16, 6);
134 clk[per11] = imx_clk_divider("per11", "per11_sel", ccm(CCM_PCDR2), 24, 6);
135 clk[per12] = imx_clk_divider("per12", "per12_sel", ccm(CCM_PCDR3), 0, 6);
136 clk[per13] = imx_clk_divider("per13", "per13_sel", ccm(CCM_PCDR3), 8, 6);
137 clk[per14] = imx_clk_divider("per14", "per14_sel", ccm(CCM_PCDR3), 16, 6);
138 clk[per15] = imx_clk_divider("per15", "per15_sel", ccm(CCM_PCDR3), 24, 6);
139 clk[csi_ipg_per] = imx_clk_gate("csi_ipg_per", "per0", ccm(CCM_CGCR0), 0);
140 clk[epit_ipg_per] = imx_clk_gate("epit_ipg_per", "per1", ccm(CCM_CGCR0), 1);
141 clk[esai_ipg_per] = imx_clk_gate("esai_ipg_per", "per2", ccm(CCM_CGCR0), 2);
142 clk[esdhc1_ipg_per] = imx_clk_gate("esdhc1_ipg_per", "per3", ccm(CCM_CGCR0), 3);
143 clk[esdhc2_ipg_per] = imx_clk_gate("esdhc2_ipg_per", "per4", ccm(CCM_CGCR0), 4);
144 clk[gpt_ipg_per] = imx_clk_gate("gpt_ipg_per", "per5", ccm(CCM_CGCR0), 5);
145 clk[i2c_ipg_per] = imx_clk_gate("i2c_ipg_per", "per6", ccm(CCM_CGCR0), 6);
146 clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per7", ccm(CCM_CGCR0), 7);
147 clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "per8", ccm(CCM_CGCR0), 8);
148 clk[owire_ipg_per] = imx_clk_gate("owire_ipg_per", "per9", ccm(CCM_CGCR0), 9);
149 clk[pwm_ipg_per] = imx_clk_gate("pwm_ipg_per", "per10", ccm(CCM_CGCR0), 10);
150 clk[sim1_ipg_per] = imx_clk_gate("sim1_ipg_per", "per11", ccm(CCM_CGCR0), 11);
151 clk[sim2_ipg_per] = imx_clk_gate("sim2_ipg_per", "per12", ccm(CCM_CGCR0), 12);
152 clk[ssi1_ipg_per] = imx_clk_gate("ssi1_ipg_per", "per13", ccm(CCM_CGCR0), 13);
153 clk[ssi2_ipg_per] = imx_clk_gate("ssi2_ipg_per", "per14", ccm(CCM_CGCR0), 14);
154 clk[uart_ipg_per] = imx_clk_gate("uart_ipg_per", "per15", ccm(CCM_CGCR0), 15);
155 clk[ata_ahb] = imx_clk_gate("ata_ahb", "ahb", ccm(CCM_CGCR0), 16);
156 /* CCM_CGCR0(17): reserved */
157 clk[csi_ahb] = imx_clk_gate("csi_ahb", "ahb", ccm(CCM_CGCR0), 18);
158 clk[emi_ahb] = imx_clk_gate("emi_ahb", "ahb", ccm(CCM_CGCR0), 19);
159 clk[esai_ahb] = imx_clk_gate("esai_ahb", "ahb", ccm(CCM_CGCR0), 20);
160 clk[esdhc1_ahb] = imx_clk_gate("esdhc1_ahb", "ahb", ccm(CCM_CGCR0), 21);
161 clk[esdhc2_ahb] = imx_clk_gate("esdhc2_ahb", "ahb", ccm(CCM_CGCR0), 22);
162 clk[fec_ahb] = imx_clk_gate("fec_ahb", "ahb", ccm(CCM_CGCR0), 23);
163 clk[lcdc_ahb] = imx_clk_gate("lcdc_ahb", "ahb", ccm(CCM_CGCR0), 24);
164 clk[rtic_ahb] = imx_clk_gate("rtic_ahb", "ahb", ccm(CCM_CGCR0), 25);
165 clk[sdma_ahb] = imx_clk_gate("sdma_ahb", "ahb", ccm(CCM_CGCR0), 26);
166 clk[slcdc_ahb] = imx_clk_gate("slcdc_ahb", "ahb", ccm(CCM_CGCR0), 27);
167 clk[usbotg_ahb] = imx_clk_gate("usbotg_ahb", "ahb", ccm(CCM_CGCR0), 28);
168 /* CCM_CGCR0(29-31): reserved */
169 /* CCM_CGCR1(0): reserved in datasheet, used as audmux in FSL kernel */
170 clk[can1_ipg] = imx_clk_gate("can1_ipg", "ipg", ccm(CCM_CGCR1), 2);
171 clk[can2_ipg] = imx_clk_gate("can2_ipg", "ipg", ccm(CCM_CGCR1), 3);
172 clk[csi_ipg] = imx_clk_gate("csi_ipg", "ipg", ccm(CCM_CGCR1), 4);
173 clk[cspi1_ipg] = imx_clk_gate("cspi1_ipg", "ipg", ccm(CCM_CGCR1), 5);
174 clk[cspi2_ipg] = imx_clk_gate("cspi2_ipg", "ipg", ccm(CCM_CGCR1), 6);
175 clk[cspi3_ipg] = imx_clk_gate("cspi3_ipg", "ipg", ccm(CCM_CGCR1), 7);
176 clk[dryice_ipg] = imx_clk_gate("dryice_ipg", "ipg", ccm(CCM_CGCR1), 8);
177 clk[ect_ipg] = imx_clk_gate("ect_ipg", "ipg", ccm(CCM_CGCR1), 9);
178 clk[epit1_ipg] = imx_clk_gate("epit1_ipg", "ipg", ccm(CCM_CGCR1), 10);
179 clk[epit2_ipg] = imx_clk_gate("epit2_ipg", "ipg", ccm(CCM_CGCR1), 11);
180 /* CCM_CGCR1(12): reserved in datasheet, used as esai in FSL kernel */
181 clk[esdhc1_ipg] = imx_clk_gate("esdhc1_ipg", "ipg", ccm(CCM_CGCR1), 13);
182 clk[esdhc2_ipg] = imx_clk_gate("esdhc2_ipg", "ipg", ccm(CCM_CGCR1), 14);
183 clk[fec_ipg] = imx_clk_gate("fec_ipg", "ipg", ccm(CCM_CGCR1), 15);
184 /* CCM_CGCR1(16): reserved in datasheet, used as gpio1 in FSL kernel */
185 /* CCM_CGCR1(17): reserved in datasheet, used as gpio2 in FSL kernel */
186 /* CCM_CGCR1(18): reserved in datasheet, used as gpio3 in FSL kernel */
187 clk[gpt1_ipg] = imx_clk_gate("gpt1_ipg", "ipg", ccm(CCM_CGCR1), 19);
188 clk[gpt2_ipg] = imx_clk_gate("gpt2_ipg", "ipg", ccm(CCM_CGCR1), 20);
189 clk[gpt3_ipg] = imx_clk_gate("gpt3_ipg", "ipg", ccm(CCM_CGCR1), 21);
190 clk[gpt4_ipg] = imx_clk_gate("gpt4_ipg", "ipg", ccm(CCM_CGCR1), 22);
191 /* CCM_CGCR1(23): reserved in datasheet, used as i2c1 in FSL kernel */
192 /* CCM_CGCR1(24): reserved in datasheet, used as i2c2 in FSL kernel */
193 /* CCM_CGCR1(25): reserved in datasheet, used as i2c3 in FSL kernel */
194 clk[iim_ipg] = imx_clk_gate("iim_ipg", "ipg", ccm(CCM_CGCR1), 26);
195 /* CCM_CGCR1(27): reserved in datasheet, used as iomuxc in FSL kernel */
196 /* CCM_CGCR1(28): reserved in datasheet, used as kpp in FSL kernel */
197 clk[kpp_ipg] = imx_clk_gate("kpp_ipg", "ipg", ccm(CCM_CGCR1), 28);
198 clk[lcdc_ipg] = imx_clk_gate("lcdc_ipg", "ipg", ccm(CCM_CGCR1), 29);
199 /* CCM_CGCR1(30): reserved in datasheet, used as owire in FSL kernel */
200 clk[pwm1_ipg] = imx_clk_gate("pwm1_ipg", "ipg", ccm(CCM_CGCR1), 31);
201 clk[pwm2_ipg] = imx_clk_gate("pwm2_ipg", "ipg", ccm(CCM_CGCR2), 0);
202 clk[pwm3_ipg] = imx_clk_gate("pwm3_ipg", "ipg", ccm(CCM_CGCR2), 1);
203 clk[pwm4_ipg] = imx_clk_gate("pwm4_ipg", "ipg", ccm(CCM_CGCR2), 2);
204 clk[rngb_ipg] = imx_clk_gate("rngb_ipg", "ipg", ccm(CCM_CGCR2), 3);
205 /* CCM_CGCR2(4): reserved in datasheet, used as rtic in FSL kernel */
206 clk[scc_ipg] = imx_clk_gate("scc_ipg", "ipg", ccm(CCM_CGCR2), 5);
207 clk[sdma_ipg] = imx_clk_gate("sdma_ipg", "ipg", ccm(CCM_CGCR2), 6);
208 clk[sim1_ipg] = imx_clk_gate("sim1_ipg", "ipg", ccm(CCM_CGCR2), 7);
209 clk[sim2_ipg] = imx_clk_gate("sim2_ipg", "ipg", ccm(CCM_CGCR2), 8);
210 clk[slcdc_ipg] = imx_clk_gate("slcdc_ipg", "ipg", ccm(CCM_CGCR2), 9);
211 clk[spba_ipg] = imx_clk_gate("spba_ipg", "ipg", ccm(CCM_CGCR2), 10);
212 clk[ssi1_ipg] = imx_clk_gate("ssi1_ipg", "ipg", ccm(CCM_CGCR2), 11);
213 clk[ssi2_ipg] = imx_clk_gate("ssi2_ipg", "ipg", ccm(CCM_CGCR2), 12);
214 clk[tsc_ipg] = imx_clk_gate("tsc_ipg", "ipg", ccm(CCM_CGCR2), 13);
215 clk[uart1_ipg] = imx_clk_gate("uart1_ipg", "ipg", ccm(CCM_CGCR2), 14);
216 clk[uart2_ipg] = imx_clk_gate("uart2_ipg", "ipg", ccm(CCM_CGCR2), 15);
217 clk[uart3_ipg] = imx_clk_gate("uart3_ipg", "ipg", ccm(CCM_CGCR2), 16);
218 clk[uart4_ipg] = imx_clk_gate("uart4_ipg", "ipg", ccm(CCM_CGCR2), 17);
219 clk[uart5_ipg] = imx_clk_gate("uart5_ipg", "ipg", ccm(CCM_CGCR2), 18);
220 /* CCM_CGCR2(19): reserved in datasheet, but used as wdt in FSL kernel */
221 clk[wdt_ipg] = imx_clk_gate("wdt_ipg", "ipg", ccm(CCM_CGCR2), 19);
222
223 imx_check_clocks(clk, ARRAY_SIZE(clk));
224
225 clk_prepare_enable(clk[emi_ahb]);
226
227 /* Clock source for gpt must be derived from AHB */
228 clk_set_parent(clk[per5_sel], clk[ahb]);
229
230 /*
231 * Let's initially set up CLKO parent as ipg, since this configuration
232 * is used on some imx25 board designs to clock the audio codec.
233 */
234 clk_set_parent(clk[cko_sel], clk[ipg]);
235
236 return 0;
237}
238
239static void __init mx25_clocks_init_dt(struct device_node *np)
240{
241 struct device_node *refnp;
242 unsigned long osc_rate = 24000000;
243 void __iomem *ccm;
244
245 /* retrieve the freqency of fixed clocks from device tree */
246 for_each_compatible_node(refnp, NULL, "fixed-clock") {
247 u32 rate;
248 if (of_property_read_u32(refnp, "clock-frequency", &rate))
249 continue;
250
251 if (of_device_is_compatible(refnp, "fsl,imx-osc"))
252 osc_rate = rate;
253 }
254
255 ccm = of_iomap(np, 0);
256 __mx25_clocks_init(osc_rate, ccm);
257
258 clk_data.clks = clk;
259 clk_data.clk_num = ARRAY_SIZE(clk);
260 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
261}
262CLK_OF_DECLARE(imx25_ccm, "fsl,imx25-ccm", mx25_clocks_init_dt);
diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c
new file mode 100644
index 000000000000..d9d50d54ef2a
--- /dev/null
+++ b/drivers/clk/imx/clk-imx27.c
@@ -0,0 +1,263 @@
1#include <linux/clk.h>
2#include <linux/clk-provider.h>
3#include <linux/clkdev.h>
4#include <linux/err.h>
5#include <linux/of.h>
6#include <linux/of_address.h>
7#include <dt-bindings/clock/imx27-clock.h>
8#include <soc/imx/revision.h>
9#include <soc/imx/timer.h>
10#include <asm/irq.h>
11
12#include "clk.h"
13
14#define MX27_CCM_BASE_ADDR 0x10027000
15#define MX27_GPT1_BASE_ADDR 0x10003000
16#define MX27_INT_GPT1 (NR_IRQS_LEGACY + 26)
17
18static void __iomem *ccm __initdata;
19
20/* Register offsets */
21#define CCM_CSCR (ccm + 0x00)
22#define CCM_MPCTL0 (ccm + 0x04)
23#define CCM_MPCTL1 (ccm + 0x08)
24#define CCM_SPCTL0 (ccm + 0x0c)
25#define CCM_SPCTL1 (ccm + 0x10)
26#define CCM_PCDR0 (ccm + 0x18)
27#define CCM_PCDR1 (ccm + 0x1c)
28#define CCM_PCCR0 (ccm + 0x20)
29#define CCM_PCCR1 (ccm + 0x24)
30#define CCM_CCSR (ccm + 0x28)
31
32static const char *vpu_sel_clks[] = { "spll", "mpll_main2", };
33static const char *cpu_sel_clks[] = { "mpll_main2", "mpll", };
34static const char *mpll_sel_clks[] = { "fpm", "mpll_osc_sel", };
35static const char *mpll_osc_sel_clks[] = { "ckih_gate", "ckih_div1p5", };
36static const char *clko_sel_clks[] = {
37 "ckil", "fpm", "ckih_gate", "ckih_gate",
38 "ckih_gate", "mpll", "spll", "cpu_div",
39 "ahb", "ipg", "per1_div", "per2_div",
40 "per3_div", "per4_div", "ssi1_div", "ssi2_div",
41 "nfc_div", "mshc_div", "vpu_div", "60m",
42 "32k", "usb_div", "dptc",
43};
44
45static const char *ssi_sel_clks[] = { "spll_gate", "mpll", };
46
47static struct clk *clk[IMX27_CLK_MAX];
48static struct clk_onecell_data clk_data;
49
50static void __init _mx27_clocks_init(unsigned long fref)
51{
52 BUG_ON(!ccm);
53
54 clk[IMX27_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
55 clk[IMX27_CLK_CKIH] = imx_clk_fixed("ckih", fref);
56 clk[IMX27_CLK_CKIL] = imx_clk_fixed("ckil", 32768);
57 clk[IMX27_CLK_FPM] = imx_clk_fixed_factor("fpm", "ckil", 1024, 1);
58 clk[IMX27_CLK_CKIH_DIV1P5] = imx_clk_fixed_factor("ckih_div1p5", "ckih_gate", 2, 3);
59 clk[IMX27_CLK_CKIH_GATE] = imx_clk_gate_dis("ckih_gate", "ckih", CCM_CSCR, 3);
60 clk[IMX27_CLK_MPLL_OSC_SEL] = imx_clk_mux("mpll_osc_sel", CCM_CSCR, 4, 1, mpll_osc_sel_clks, ARRAY_SIZE(mpll_osc_sel_clks));
61 clk[IMX27_CLK_MPLL_SEL] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, ARRAY_SIZE(mpll_sel_clks));
62 clk[IMX27_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX27, "mpll", "mpll_sel", CCM_MPCTL0);
63 clk[IMX27_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX27, "spll", "ckih_gate", CCM_SPCTL0);
64 clk[IMX27_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1);
65 clk[IMX27_CLK_MPLL_MAIN2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
66
67 if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
68 clk[IMX27_CLK_AHB] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 8, 2);
69 clk[IMX27_CLK_IPG] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
70 } else {
71 clk[IMX27_CLK_AHB] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 9, 4);
72 clk[IMX27_CLK_IPG] = imx_clk_divider("ipg", "ahb", CCM_CSCR, 8, 1);
73 }
74
75 clk[IMX27_CLK_MSHC_DIV] = imx_clk_divider("mshc_div", "ahb", CCM_PCDR0, 0, 6);
76 clk[IMX27_CLK_NFC_DIV] = imx_clk_divider("nfc_div", "ahb", CCM_PCDR0, 6, 4);
77 clk[IMX27_CLK_PER1_DIV] = imx_clk_divider("per1_div", "mpll_main2", CCM_PCDR1, 0, 6);
78 clk[IMX27_CLK_PER2_DIV] = imx_clk_divider("per2_div", "mpll_main2", CCM_PCDR1, 8, 6);
79 clk[IMX27_CLK_PER3_DIV] = imx_clk_divider("per3_div", "mpll_main2", CCM_PCDR1, 16, 6);
80 clk[IMX27_CLK_PER4_DIV] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6);
81 clk[IMX27_CLK_VPU_SEL] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks));
82 clk[IMX27_CLK_VPU_DIV] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 6);
83 clk[IMX27_CLK_USB_DIV] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 28, 3);
84 clk[IMX27_CLK_CPU_SEL] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
85 clk[IMX27_CLK_CLKO_SEL] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks));
86
87 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
88 clk[IMX27_CLK_CPU_DIV] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 12, 2);
89 else
90 clk[IMX27_CLK_CPU_DIV] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 13, 3);
91
92 clk[IMX27_CLK_CLKO_DIV] = imx_clk_divider("clko_div", "clko_sel", CCM_PCDR0, 22, 3);
93 clk[IMX27_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", CCM_CSCR, 22, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
94 clk[IMX27_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", CCM_CSCR, 23, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
95 clk[IMX27_CLK_SSI1_DIV] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6);
96 clk[IMX27_CLK_SSI2_DIV] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 6);
97 clk[IMX27_CLK_CLKO_EN] = imx_clk_gate("clko_en", "clko_div", CCM_PCCR0, 0);
98 clk[IMX27_CLK_SSI2_IPG_GATE] = imx_clk_gate("ssi2_ipg_gate", "ipg", CCM_PCCR0, 0);
99 clk[IMX27_CLK_SSI1_IPG_GATE] = imx_clk_gate("ssi1_ipg_gate", "ipg", CCM_PCCR0, 1);
100 clk[IMX27_CLK_SLCDC_IPG_GATE] = imx_clk_gate("slcdc_ipg_gate", "ipg", CCM_PCCR0, 2);
101 clk[IMX27_CLK_SDHC3_IPG_GATE] = imx_clk_gate("sdhc3_ipg_gate", "ipg", CCM_PCCR0, 3);
102 clk[IMX27_CLK_SDHC2_IPG_GATE] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 4);
103 clk[IMX27_CLK_SDHC1_IPG_GATE] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 5);
104 clk[IMX27_CLK_SCC_IPG_GATE] = imx_clk_gate("scc_ipg_gate", "ipg", CCM_PCCR0, 6);
105 clk[IMX27_CLK_SAHARA_IPG_GATE] = imx_clk_gate("sahara_ipg_gate", "ipg", CCM_PCCR0, 7);
106 clk[IMX27_CLK_RTIC_IPG_GATE] = imx_clk_gate("rtic_ipg_gate", "ipg", CCM_PCCR0, 8);
107 clk[IMX27_CLK_RTC_IPG_GATE] = imx_clk_gate("rtc_ipg_gate", "ipg", CCM_PCCR0, 9);
108 clk[IMX27_CLK_PWM_IPG_GATE] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR0, 11);
109 clk[IMX27_CLK_OWIRE_IPG_GATE] = imx_clk_gate("owire_ipg_gate", "ipg", CCM_PCCR0, 12);
110 clk[IMX27_CLK_MSHC_IPG_GATE] = imx_clk_gate("mshc_ipg_gate", "ipg", CCM_PCCR0, 13);
111 clk[IMX27_CLK_LCDC_IPG_GATE] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 14);
112 clk[IMX27_CLK_KPP_IPG_GATE] = imx_clk_gate("kpp_ipg_gate", "ipg", CCM_PCCR0, 15);
113 clk[IMX27_CLK_IIM_IPG_GATE] = imx_clk_gate("iim_ipg_gate", "ipg", CCM_PCCR0, 16);
114 clk[IMX27_CLK_I2C2_IPG_GATE] = imx_clk_gate("i2c2_ipg_gate", "ipg", CCM_PCCR0, 17);
115 clk[IMX27_CLK_I2C1_IPG_GATE] = imx_clk_gate("i2c1_ipg_gate", "ipg", CCM_PCCR0, 18);
116 clk[IMX27_CLK_GPT6_IPG_GATE] = imx_clk_gate("gpt6_ipg_gate", "ipg", CCM_PCCR0, 19);
117 clk[IMX27_CLK_GPT5_IPG_GATE] = imx_clk_gate("gpt5_ipg_gate", "ipg", CCM_PCCR0, 20);
118 clk[IMX27_CLK_GPT4_IPG_GATE] = imx_clk_gate("gpt4_ipg_gate", "ipg", CCM_PCCR0, 21);
119 clk[IMX27_CLK_GPT3_IPG_GATE] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR0, 22);
120 clk[IMX27_CLK_GPT2_IPG_GATE] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR0, 23);
121 clk[IMX27_CLK_GPT1_IPG_GATE] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR0, 24);
122 clk[IMX27_CLK_GPIO_IPG_GATE] = imx_clk_gate("gpio_ipg_gate", "ipg", CCM_PCCR0, 25);
123 clk[IMX27_CLK_FEC_IPG_GATE] = imx_clk_gate("fec_ipg_gate", "ipg", CCM_PCCR0, 26);
124 clk[IMX27_CLK_EMMA_IPG_GATE] = imx_clk_gate("emma_ipg_gate", "ipg", CCM_PCCR0, 27);
125 clk[IMX27_CLK_DMA_IPG_GATE] = imx_clk_gate("dma_ipg_gate", "ipg", CCM_PCCR0, 28);
126 clk[IMX27_CLK_CSPI3_IPG_GATE] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR0, 29);
127 clk[IMX27_CLK_CSPI2_IPG_GATE] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 30);
128 clk[IMX27_CLK_CSPI1_IPG_GATE] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 31);
129 clk[IMX27_CLK_MSHC_BAUD_GATE] = imx_clk_gate("mshc_baud_gate", "mshc_div", CCM_PCCR1, 2);
130 clk[IMX27_CLK_NFC_BAUD_GATE] = imx_clk_gate("nfc_baud_gate", "nfc_div", CCM_PCCR1, 3);
131 clk[IMX27_CLK_SSI2_BAUD_GATE] = imx_clk_gate("ssi2_baud_gate", "ssi2_div", CCM_PCCR1, 4);
132 clk[IMX27_CLK_SSI1_BAUD_GATE] = imx_clk_gate("ssi1_baud_gate", "ssi1_div", CCM_PCCR1, 5);
133 clk[IMX27_CLK_VPU_BAUD_GATE] = imx_clk_gate("vpu_baud_gate", "vpu_div", CCM_PCCR1, 6);
134 clk[IMX27_CLK_PER4_GATE] = imx_clk_gate("per4_gate", "per4_div", CCM_PCCR1, 7);
135 clk[IMX27_CLK_PER3_GATE] = imx_clk_gate("per3_gate", "per3_div", CCM_PCCR1, 8);
136 clk[IMX27_CLK_PER2_GATE] = imx_clk_gate("per2_gate", "per2_div", CCM_PCCR1, 9);
137 clk[IMX27_CLK_PER1_GATE] = imx_clk_gate("per1_gate", "per1_div", CCM_PCCR1, 10);
138 clk[IMX27_CLK_USB_AHB_GATE] = imx_clk_gate("usb_ahb_gate", "ahb", CCM_PCCR1, 11);
139 clk[IMX27_CLK_SLCDC_AHB_GATE] = imx_clk_gate("slcdc_ahb_gate", "ahb", CCM_PCCR1, 12);
140 clk[IMX27_CLK_SAHARA_AHB_GATE] = imx_clk_gate("sahara_ahb_gate", "ahb", CCM_PCCR1, 13);
141 clk[IMX27_CLK_RTIC_AHB_GATE] = imx_clk_gate("rtic_ahb_gate", "ahb", CCM_PCCR1, 14);
142 clk[IMX27_CLK_LCDC_AHB_GATE] = imx_clk_gate("lcdc_ahb_gate", "ahb", CCM_PCCR1, 15);
143 clk[IMX27_CLK_VPU_AHB_GATE] = imx_clk_gate("vpu_ahb_gate", "ahb", CCM_PCCR1, 16);
144 clk[IMX27_CLK_FEC_AHB_GATE] = imx_clk_gate("fec_ahb_gate", "ahb", CCM_PCCR1, 17);
145 clk[IMX27_CLK_EMMA_AHB_GATE] = imx_clk_gate("emma_ahb_gate", "ahb", CCM_PCCR1, 18);
146 clk[IMX27_CLK_EMI_AHB_GATE] = imx_clk_gate("emi_ahb_gate", "ahb", CCM_PCCR1, 19);
147 clk[IMX27_CLK_DMA_AHB_GATE] = imx_clk_gate("dma_ahb_gate", "ahb", CCM_PCCR1, 20);
148 clk[IMX27_CLK_CSI_AHB_GATE] = imx_clk_gate("csi_ahb_gate", "ahb", CCM_PCCR1, 21);
149 clk[IMX27_CLK_BROM_AHB_GATE] = imx_clk_gate("brom_ahb_gate", "ahb", CCM_PCCR1, 22);
150 clk[IMX27_CLK_ATA_AHB_GATE] = imx_clk_gate("ata_ahb_gate", "ahb", CCM_PCCR1, 23);
151 clk[IMX27_CLK_WDOG_IPG_GATE] = imx_clk_gate("wdog_ipg_gate", "ipg", CCM_PCCR1, 24);
152 clk[IMX27_CLK_USB_IPG_GATE] = imx_clk_gate("usb_ipg_gate", "ipg", CCM_PCCR1, 25);
153 clk[IMX27_CLK_UART6_IPG_GATE] = imx_clk_gate("uart6_ipg_gate", "ipg", CCM_PCCR1, 26);
154 clk[IMX27_CLK_UART5_IPG_GATE] = imx_clk_gate("uart5_ipg_gate", "ipg", CCM_PCCR1, 27);
155 clk[IMX27_CLK_UART4_IPG_GATE] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR1, 28);
156 clk[IMX27_CLK_UART3_IPG_GATE] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR1, 29);
157 clk[IMX27_CLK_UART2_IPG_GATE] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR1, 30);
158 clk[IMX27_CLK_UART1_IPG_GATE] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR1, 31);
159
160 imx_check_clocks(clk, ARRAY_SIZE(clk));
161
162 clk_register_clkdev(clk[IMX27_CLK_CPU_DIV], NULL, "cpu0");
163
164 clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]);
165
166 imx_print_silicon_rev("i.MX27", mx27_revision());
167}
168
169int __init mx27_clocks_init(unsigned long fref)
170{
171 ccm = ioremap(MX27_CCM_BASE_ADDR, SZ_4K);
172
173 _mx27_clocks_init(fref);
174
175 clk_register_clkdev(clk[IMX27_CLK_UART1_IPG_GATE], "ipg", "imx21-uart.0");
176 clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.0");
177 clk_register_clkdev(clk[IMX27_CLK_UART2_IPG_GATE], "ipg", "imx21-uart.1");
178 clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.1");
179 clk_register_clkdev(clk[IMX27_CLK_UART3_IPG_GATE], "ipg", "imx21-uart.2");
180 clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.2");
181 clk_register_clkdev(clk[IMX27_CLK_UART4_IPG_GATE], "ipg", "imx21-uart.3");
182 clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.3");
183 clk_register_clkdev(clk[IMX27_CLK_UART5_IPG_GATE], "ipg", "imx21-uart.4");
184 clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.4");
185 clk_register_clkdev(clk[IMX27_CLK_UART6_IPG_GATE], "ipg", "imx21-uart.5");
186 clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.5");
187 clk_register_clkdev(clk[IMX27_CLK_GPT1_IPG_GATE], "ipg", "imx-gpt.0");
188 clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx-gpt.0");
189 clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx21-mmc.0");
190 clk_register_clkdev(clk[IMX27_CLK_SDHC1_IPG_GATE], "ipg", "imx21-mmc.0");
191 clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx21-mmc.1");
192 clk_register_clkdev(clk[IMX27_CLK_SDHC2_IPG_GATE], "ipg", "imx21-mmc.1");
193 clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx21-mmc.2");
194 clk_register_clkdev(clk[IMX27_CLK_SDHC2_IPG_GATE], "ipg", "imx21-mmc.2");
195 clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx27-cspi.0");
196 clk_register_clkdev(clk[IMX27_CLK_CSPI1_IPG_GATE], "ipg", "imx27-cspi.0");
197 clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx27-cspi.1");
198 clk_register_clkdev(clk[IMX27_CLK_CSPI2_IPG_GATE], "ipg", "imx27-cspi.1");
199 clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx27-cspi.2");
200 clk_register_clkdev(clk[IMX27_CLK_CSPI3_IPG_GATE], "ipg", "imx27-cspi.2");
201 clk_register_clkdev(clk[IMX27_CLK_PER3_GATE], "per", "imx21-fb.0");
202 clk_register_clkdev(clk[IMX27_CLK_LCDC_IPG_GATE], "ipg", "imx21-fb.0");
203 clk_register_clkdev(clk[IMX27_CLK_LCDC_AHB_GATE], "ahb", "imx21-fb.0");
204 clk_register_clkdev(clk[IMX27_CLK_CSI_AHB_GATE], "ahb", "imx27-camera.0");
205 clk_register_clkdev(clk[IMX27_CLK_PER4_GATE], "per", "imx27-camera.0");
206 clk_register_clkdev(clk[IMX27_CLK_USB_DIV], "per", "imx-udc-mx27");
207 clk_register_clkdev(clk[IMX27_CLK_USB_IPG_GATE], "ipg", "imx-udc-mx27");
208 clk_register_clkdev(clk[IMX27_CLK_USB_AHB_GATE], "ahb", "imx-udc-mx27");
209 clk_register_clkdev(clk[IMX27_CLK_USB_DIV], "per", "mxc-ehci.0");
210 clk_register_clkdev(clk[IMX27_CLK_USB_IPG_GATE], "ipg", "mxc-ehci.0");
211 clk_register_clkdev(clk[IMX27_CLK_USB_AHB_GATE], "ahb", "mxc-ehci.0");
212 clk_register_clkdev(clk[IMX27_CLK_USB_DIV], "per", "mxc-ehci.1");
213 clk_register_clkdev(clk[IMX27_CLK_USB_IPG_GATE], "ipg", "mxc-ehci.1");
214 clk_register_clkdev(clk[IMX27_CLK_USB_AHB_GATE], "ahb", "mxc-ehci.1");
215 clk_register_clkdev(clk[IMX27_CLK_USB_DIV], "per", "mxc-ehci.2");
216 clk_register_clkdev(clk[IMX27_CLK_USB_IPG_GATE], "ipg", "mxc-ehci.2");
217 clk_register_clkdev(clk[IMX27_CLK_USB_AHB_GATE], "ahb", "mxc-ehci.2");
218 clk_register_clkdev(clk[IMX27_CLK_SSI1_IPG_GATE], NULL, "imx-ssi.0");
219 clk_register_clkdev(clk[IMX27_CLK_SSI2_IPG_GATE], NULL, "imx-ssi.1");
220 clk_register_clkdev(clk[IMX27_CLK_NFC_BAUD_GATE], NULL, "imx27-nand.0");
221 clk_register_clkdev(clk[IMX27_CLK_VPU_BAUD_GATE], "per", "coda-imx27.0");
222 clk_register_clkdev(clk[IMX27_CLK_VPU_AHB_GATE], "ahb", "coda-imx27.0");
223 clk_register_clkdev(clk[IMX27_CLK_DMA_AHB_GATE], "ahb", "imx27-dma");
224 clk_register_clkdev(clk[IMX27_CLK_DMA_IPG_GATE], "ipg", "imx27-dma");
225 clk_register_clkdev(clk[IMX27_CLK_FEC_IPG_GATE], "ipg", "imx27-fec.0");
226 clk_register_clkdev(clk[IMX27_CLK_FEC_AHB_GATE], "ahb", "imx27-fec.0");
227 clk_register_clkdev(clk[IMX27_CLK_WDOG_IPG_GATE], NULL, "imx2-wdt.0");
228 clk_register_clkdev(clk[IMX27_CLK_I2C1_IPG_GATE], NULL, "imx21-i2c.0");
229 clk_register_clkdev(clk[IMX27_CLK_I2C2_IPG_GATE], NULL, "imx21-i2c.1");
230 clk_register_clkdev(clk[IMX27_CLK_OWIRE_IPG_GATE], NULL, "mxc_w1.0");
231 clk_register_clkdev(clk[IMX27_CLK_KPP_IPG_GATE], NULL, "imx-keypad");
232 clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "emma-ahb", "imx27-camera.0");
233 clk_register_clkdev(clk[IMX27_CLK_EMMA_IPG_GATE], "emma-ipg", "imx27-camera.0");
234 clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "ahb", "m2m-emmaprp.0");
235 clk_register_clkdev(clk[IMX27_CLK_EMMA_IPG_GATE], "ipg", "m2m-emmaprp.0");
236
237 mxc_timer_init(MX27_GPT1_BASE_ADDR, MX27_INT_GPT1, GPT_TYPE_IMX21);
238
239 return 0;
240}
241
242static void __init mx27_clocks_init_dt(struct device_node *np)
243{
244 struct device_node *refnp;
245 u32 fref = 26000000; /* default */
246
247 for_each_compatible_node(refnp, NULL, "fixed-clock") {
248 if (!of_device_is_compatible(refnp, "fsl,imx-osc26m"))
249 continue;
250
251 if (!of_property_read_u32(refnp, "clock-frequency", &fref))
252 break;
253 }
254
255 ccm = of_iomap(np, 0);
256
257 _mx27_clocks_init(fref);
258
259 clk_data.clks = clk;
260 clk_data.clk_num = ARRAY_SIZE(clk);
261 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
262}
263CLK_OF_DECLARE(imx27_ccm, "fsl,imx27-ccm", mx27_clocks_init_dt);
diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c
new file mode 100644
index 000000000000..fe66c40b7be2
--- /dev/null
+++ b/drivers/clk/imx/clk-imx31.c
@@ -0,0 +1,221 @@
1/*
2 * Copyright (C) 2012 Sascha Hauer <kernel@pengutronix.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
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
14 * along with this program; if not, write to the Free Software
15 * Foundation.
16 */
17
18#include <linux/module.h>
19#include <linux/clk.h>
20#include <linux/clkdev.h>
21#include <linux/io.h>
22#include <linux/err.h>
23#include <linux/of.h>
24#include <soc/imx/revision.h>
25#include <soc/imx/timer.h>
26#include <asm/irq.h>
27
28#include "clk.h"
29
30#define MX31_CCM_BASE_ADDR 0x53f80000
31#define MX31_GPT1_BASE_ADDR 0x53f90000
32#define MX31_INT_GPT (NR_IRQS_LEGACY + 29)
33
34#define MXC_CCM_CCMR 0x00
35#define MXC_CCM_PDR0 0x04
36#define MXC_CCM_PDR1 0x08
37#define MXC_CCM_MPCTL 0x10
38#define MXC_CCM_UPCTL 0x14
39#define MXC_CCM_SRPCTL 0x18
40#define MXC_CCM_CGR0 0x20
41#define MXC_CCM_CGR1 0x24
42#define MXC_CCM_CGR2 0x28
43#define MXC_CCM_PMCR0 0x5c
44
45static const char *mcu_main_sel[] = { "spll", "mpll", };
46static const char *per_sel[] = { "per_div", "ipg", };
47static const char *csi_sel[] = { "upll", "spll", };
48static const char *fir_sel[] = { "mcu_main", "upll", "spll" };
49
50enum mx31_clks {
51 dummy, ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg,
52 per_div, per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre,
53 fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate,
54 iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate,
55 uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate,
56 mstick1_gate, mstick2_gate, csi_gate, rtc_gate, wdog_gate, pwm_gate,
57 sim_gate, ect_gate, usb_gate, kpp_gate, ipu_gate, uart3_gate,
58 uart4_gate, uart5_gate, owire_gate, ssi2_gate, cspi1_gate, cspi2_gate,
59 gacc_gate, emi_gate, rtic_gate, firi_gate, clk_max
60};
61
62static struct clk *clk[clk_max];
63static struct clk_onecell_data clk_data;
64
65int __init mx31_clocks_init(unsigned long fref)
66{
67 void __iomem *base;
68 struct device_node *np;
69
70 base = ioremap(MX31_CCM_BASE_ADDR, SZ_4K);
71 BUG_ON(!base);
72
73 clk[dummy] = imx_clk_fixed("dummy", 0);
74 clk[ckih] = imx_clk_fixed("ckih", fref);
75 clk[ckil] = imx_clk_fixed("ckil", 32768);
76 clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX31, "mpll", "ckih", base + MXC_CCM_MPCTL);
77 clk[spll] = imx_clk_pllv1(IMX_PLLV1_IMX31, "spll", "ckih", base + MXC_CCM_SRPCTL);
78 clk[upll] = imx_clk_pllv1(IMX_PLLV1_IMX31, "upll", "ckih", base + MXC_CCM_UPCTL);
79 clk[mcu_main] = imx_clk_mux("mcu_main", base + MXC_CCM_PMCR0, 31, 1, mcu_main_sel, ARRAY_SIZE(mcu_main_sel));
80 clk[hsp] = imx_clk_divider("hsp", "mcu_main", base + MXC_CCM_PDR0, 11, 3);
81 clk[ahb] = imx_clk_divider("ahb", "mcu_main", base + MXC_CCM_PDR0, 3, 3);
82 clk[nfc] = imx_clk_divider("nfc", "ahb", base + MXC_CCM_PDR0, 8, 3);
83 clk[ipg] = imx_clk_divider("ipg", "ahb", base + MXC_CCM_PDR0, 6, 2);
84 clk[per_div] = imx_clk_divider("per_div", "upll", base + MXC_CCM_PDR0, 16, 5);
85 clk[per] = imx_clk_mux("per", base + MXC_CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel));
86 clk[csi] = imx_clk_mux("csi_sel", base + MXC_CCM_CCMR, 25, 1, csi_sel, ARRAY_SIZE(csi_sel));
87 clk[fir] = imx_clk_mux("fir_sel", base + MXC_CCM_CCMR, 11, 2, fir_sel, ARRAY_SIZE(fir_sel));
88 clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MXC_CCM_PDR0, 23, 9);
89 clk[usb_div_pre] = imx_clk_divider("usb_div_pre", "upll", base + MXC_CCM_PDR1, 30, 2);
90 clk[usb_div_post] = imx_clk_divider("usb_div_post", "usb_div_pre", base + MXC_CCM_PDR1, 27, 3);
91 clk[fir_div_pre] = imx_clk_divider("fir_div_pre", "fir_sel", base + MXC_CCM_PDR1, 24, 3);
92 clk[fir_div_post] = imx_clk_divider("fir_div_post", "fir_div_pre", base + MXC_CCM_PDR1, 23, 6);
93 clk[sdhc1_gate] = imx_clk_gate2("sdhc1_gate", "per", base + MXC_CCM_CGR0, 0);
94 clk[sdhc2_gate] = imx_clk_gate2("sdhc2_gate", "per", base + MXC_CCM_CGR0, 2);
95 clk[gpt_gate] = imx_clk_gate2("gpt_gate", "per", base + MXC_CCM_CGR0, 4);
96 clk[epit1_gate] = imx_clk_gate2("epit1_gate", "per", base + MXC_CCM_CGR0, 6);
97 clk[epit2_gate] = imx_clk_gate2("epit2_gate", "per", base + MXC_CCM_CGR0, 8);
98 clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MXC_CCM_CGR0, 10);
99 clk[ata_gate] = imx_clk_gate2("ata_gate", "ipg", base + MXC_CCM_CGR0, 12);
100 clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MXC_CCM_CGR0, 14);
101 clk[cspi3_gate] = imx_clk_gate2("cspi3_gate", "ipg", base + MXC_CCM_CGR0, 16);
102 clk[rng_gate] = imx_clk_gate2("rng_gate", "ipg", base + MXC_CCM_CGR0, 18);
103 clk[uart1_gate] = imx_clk_gate2("uart1_gate", "per", base + MXC_CCM_CGR0, 20);
104 clk[uart2_gate] = imx_clk_gate2("uart2_gate", "per", base + MXC_CCM_CGR0, 22);
105 clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "spll", base + MXC_CCM_CGR0, 24);
106 clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "per", base + MXC_CCM_CGR0, 26);
107 clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "per", base + MXC_CCM_CGR0, 28);
108 clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per", base + MXC_CCM_CGR0, 30);
109 clk[hantro_gate] = imx_clk_gate2("hantro_gate", "per", base + MXC_CCM_CGR1, 0);
110 clk[mstick1_gate] = imx_clk_gate2("mstick1_gate", "per", base + MXC_CCM_CGR1, 2);
111 clk[mstick2_gate] = imx_clk_gate2("mstick2_gate", "per", base + MXC_CCM_CGR1, 4);
112 clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", base + MXC_CCM_CGR1, 6);
113 clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MXC_CCM_CGR1, 8);
114 clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MXC_CCM_CGR1, 10);
115 clk[pwm_gate] = imx_clk_gate2("pwm_gate", "per", base + MXC_CCM_CGR1, 12);
116 clk[sim_gate] = imx_clk_gate2("sim_gate", "per", base + MXC_CCM_CGR1, 14);
117 clk[ect_gate] = imx_clk_gate2("ect_gate", "per", base + MXC_CCM_CGR1, 16);
118 clk[usb_gate] = imx_clk_gate2("usb_gate", "ahb", base + MXC_CCM_CGR1, 18);
119 clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MXC_CCM_CGR1, 20);
120 clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MXC_CCM_CGR1, 22);
121 clk[uart3_gate] = imx_clk_gate2("uart3_gate", "per", base + MXC_CCM_CGR1, 24);
122 clk[uart4_gate] = imx_clk_gate2("uart4_gate", "per", base + MXC_CCM_CGR1, 26);
123 clk[uart5_gate] = imx_clk_gate2("uart5_gate", "per", base + MXC_CCM_CGR1, 28);
124 clk[owire_gate] = imx_clk_gate2("owire_gate", "per", base + MXC_CCM_CGR1, 30);
125 clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "spll", base + MXC_CCM_CGR2, 0);
126 clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MXC_CCM_CGR2, 2);
127 clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MXC_CCM_CGR2, 4);
128 clk[gacc_gate] = imx_clk_gate2("gacc_gate", "per", base + MXC_CCM_CGR2, 6);
129 clk[emi_gate] = imx_clk_gate2("emi_gate", "ahb", base + MXC_CCM_CGR2, 8);
130 clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MXC_CCM_CGR2, 10);
131 clk[firi_gate] = imx_clk_gate2("firi_gate", "upll", base+MXC_CCM_CGR2, 12);
132
133 imx_check_clocks(clk, ARRAY_SIZE(clk));
134
135 np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm");
136
137 if (np) {
138 clk_data.clks = clk;
139 clk_data.clk_num = ARRAY_SIZE(clk);
140 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
141 }
142
143 clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
144 clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
145 clk_register_clkdev(clk[cspi1_gate], NULL, "imx31-cspi.0");
146 clk_register_clkdev(clk[cspi2_gate], NULL, "imx31-cspi.1");
147 clk_register_clkdev(clk[cspi3_gate], NULL, "imx31-cspi.2");
148 clk_register_clkdev(clk[pwm_gate], "pwm", NULL);
149 clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
150 clk_register_clkdev(clk[rtc_gate], NULL, "imx21-rtc");
151 clk_register_clkdev(clk[epit1_gate], "epit", NULL);
152 clk_register_clkdev(clk[epit2_gate], "epit", NULL);
153 clk_register_clkdev(clk[nfc], NULL, "imx27-nand.0");
154 clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
155 clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
156 clk_register_clkdev(clk[kpp_gate], NULL, "imx-keypad");
157 clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.0");
158 clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.0");
159 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
160 clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.1");
161 clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.1");
162 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
163 clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.2");
164 clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.2");
165 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
166 clk_register_clkdev(clk[usb_div_post], "per", "imx-udc-mx27");
167 clk_register_clkdev(clk[usb_gate], "ahb", "imx-udc-mx27");
168 clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx27");
169 clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
170 /* i.mx31 has the i.mx21 type uart */
171 clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
172 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0");
173 clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1");
174 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1");
175 clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2");
176 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2");
177 clk_register_clkdev(clk[uart4_gate], "per", "imx21-uart.3");
178 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.3");
179 clk_register_clkdev(clk[uart5_gate], "per", "imx21-uart.4");
180 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.4");
181 clk_register_clkdev(clk[i2c1_gate], NULL, "imx21-i2c.0");
182 clk_register_clkdev(clk[i2c2_gate], NULL, "imx21-i2c.1");
183 clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2");
184 clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0");
185 clk_register_clkdev(clk[sdhc1_gate], NULL, "imx31-mmc.0");
186 clk_register_clkdev(clk[sdhc2_gate], NULL, "imx31-mmc.1");
187 clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0");
188 clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1");
189 clk_register_clkdev(clk[firi_gate], "firi", NULL);
190 clk_register_clkdev(clk[ata_gate], NULL, "pata_imx");
191 clk_register_clkdev(clk[rtic_gate], "rtic", NULL);
192 clk_register_clkdev(clk[rng_gate], NULL, "mxc_rnga");
193 clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma");
194 clk_register_clkdev(clk[iim_gate], "iim", NULL);
195
196 clk_set_parent(clk[csi], clk[upll]);
197 clk_prepare_enable(clk[emi_gate]);
198 clk_prepare_enable(clk[iim_gate]);
199 mx31_revision();
200 clk_disable_unprepare(clk[iim_gate]);
201
202 mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, GPT_TYPE_IMX31);
203
204 return 0;
205}
206
207int __init mx31_clocks_init_dt(void)
208{
209 struct device_node *np;
210 u32 fref = 26000000; /* default */
211
212 for_each_compatible_node(np, NULL, "fixed-clock") {
213 if (!of_device_is_compatible(np, "fsl,imx-osc26m"))
214 continue;
215
216 if (!of_property_read_u32(np, "clock-frequency", &fref))
217 break;
218 }
219
220 return mx31_clocks_init(fref);
221}
diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
new file mode 100644
index 000000000000..69138ba3dec7
--- /dev/null
+++ b/drivers/clk/imx/clk-imx35.c
@@ -0,0 +1,310 @@
1/*
2 * Copyright (C) 2012 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
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 */
9#include <linux/mm.h>
10#include <linux/delay.h>
11#include <linux/clk.h>
12#include <linux/io.h>
13#include <linux/clkdev.h>
14#include <linux/of.h>
15#include <linux/err.h>
16#include <soc/imx/revision.h>
17#include <soc/imx/timer.h>
18#include <asm/irq.h>
19
20#include "clk.h"
21
22#define MX35_CCM_BASE_ADDR 0x53f80000
23#define MX35_GPT1_BASE_ADDR 0x53f90000
24#define MX35_INT_GPT (NR_IRQS_LEGACY + 29)
25
26#define MXC_CCM_PDR0 0x04
27#define MX35_CCM_PDR2 0x0c
28#define MX35_CCM_PDR3 0x10
29#define MX35_CCM_PDR4 0x14
30#define MX35_CCM_MPCTL 0x1c
31#define MX35_CCM_PPCTL 0x20
32#define MX35_CCM_CGR0 0x2c
33#define MX35_CCM_CGR1 0x30
34#define MX35_CCM_CGR2 0x34
35#define MX35_CCM_CGR3 0x38
36
37struct arm_ahb_div {
38 unsigned char arm, ahb, sel;
39};
40
41static struct arm_ahb_div clk_consumer[] = {
42 { .arm = 1, .ahb = 4, .sel = 0},
43 { .arm = 1, .ahb = 3, .sel = 1},
44 { .arm = 2, .ahb = 2, .sel = 0},
45 { .arm = 0, .ahb = 0, .sel = 0},
46 { .arm = 0, .ahb = 0, .sel = 0},
47 { .arm = 0, .ahb = 0, .sel = 0},
48 { .arm = 4, .ahb = 1, .sel = 0},
49 { .arm = 1, .ahb = 5, .sel = 0},
50 { .arm = 1, .ahb = 8, .sel = 0},
51 { .arm = 1, .ahb = 6, .sel = 1},
52 { .arm = 2, .ahb = 4, .sel = 0},
53 { .arm = 0, .ahb = 0, .sel = 0},
54 { .arm = 0, .ahb = 0, .sel = 0},
55 { .arm = 0, .ahb = 0, .sel = 0},
56 { .arm = 4, .ahb = 2, .sel = 0},
57 { .arm = 0, .ahb = 0, .sel = 0},
58};
59
60static char hsp_div_532[] = { 4, 8, 3, 0 };
61static char hsp_div_400[] = { 3, 6, 3, 0 };
62
63static struct clk_onecell_data clk_data;
64
65static const char *std_sel[] = {"ppll", "arm"};
66static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
67
68enum mx35_clks {
69 ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
70 arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel,
71 esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre,
72 spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre,
73 ssi2_div_post, usb_sel, usb_div, nfc_div, asrc_gate, pata_gate,
74 audmux_gate, can1_gate, can2_gate, cspi1_gate, cspi2_gate, ect_gate,
75 edio_gate, emi_gate, epit1_gate, epit2_gate, esai_gate, esdhc1_gate,
76 esdhc2_gate, esdhc3_gate, fec_gate, gpio1_gate, gpio2_gate, gpio3_gate,
77 gpt_gate, i2c1_gate, i2c2_gate, i2c3_gate, iomuxc_gate, ipu_gate,
78 kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate,
79 rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
80 ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
81 wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate,
82 gpu2d_gate, clk_max
83};
84
85static struct clk *clk[clk_max];
86
87int __init mx35_clocks_init(void)
88{
89 void __iomem *base;
90 u32 pdr0, consumer_sel, hsp_sel;
91 struct arm_ahb_div *aad;
92 unsigned char *hsp_div;
93
94 base = ioremap(MX35_CCM_BASE_ADDR, SZ_4K);
95 BUG_ON(!base);
96
97 pdr0 = __raw_readl(base + MXC_CCM_PDR0);
98 consumer_sel = (pdr0 >> 16) & 0xf;
99 aad = &clk_consumer[consumer_sel];
100 if (!aad->arm) {
101 pr_err("i.MX35 clk: illegal consumer mux selection 0x%x\n", consumer_sel);
102 /*
103 * We are basically stuck. Continue with a default entry and hope we
104 * get far enough to actually show the above message
105 */
106 aad = &clk_consumer[0];
107 }
108
109 clk[ckih] = imx_clk_fixed("ckih", 24000000);
110 clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "mpll", "ckih", base + MX35_CCM_MPCTL);
111 clk[ppll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "ppll", "ckih", base + MX35_CCM_PPCTL);
112
113 clk[mpll] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4);
114
115 if (aad->sel)
116 clk[arm] = imx_clk_fixed_factor("arm", "mpll_075", 1, aad->arm);
117 else
118 clk[arm] = imx_clk_fixed_factor("arm", "mpll", 1, aad->arm);
119
120 if (clk_get_rate(clk[arm]) > 400000000)
121 hsp_div = hsp_div_532;
122 else
123 hsp_div = hsp_div_400;
124
125 hsp_sel = (pdr0 >> 20) & 0x3;
126 if (!hsp_div[hsp_sel]) {
127 pr_err("i.MX35 clk: illegal hsp clk selection 0x%x\n", hsp_sel);
128 hsp_sel = 0;
129 }
130
131 clk[hsp] = imx_clk_fixed_factor("hsp", "arm", 1, hsp_div[hsp_sel]);
132
133 clk[ahb] = imx_clk_fixed_factor("ahb", "arm", 1, aad->ahb);
134 clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
135
136 clk[arm_per_div] = imx_clk_divider("arm_per_div", "arm", base + MX35_CCM_PDR4, 16, 6);
137 clk[ahb_per_div] = imx_clk_divider("ahb_per_div", "ahb", base + MXC_CCM_PDR0, 12, 3);
138 clk[ipg_per] = imx_clk_mux("ipg_per", base + MXC_CCM_PDR0, 26, 1, ipg_per_sel, ARRAY_SIZE(ipg_per_sel));
139
140 clk[uart_sel] = imx_clk_mux("uart_sel", base + MX35_CCM_PDR3, 14, 1, std_sel, ARRAY_SIZE(std_sel));
141 clk[uart_div] = imx_clk_divider("uart_div", "uart_sel", base + MX35_CCM_PDR4, 10, 6);
142
143 clk[esdhc_sel] = imx_clk_mux("esdhc_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
144 clk[esdhc1_div] = imx_clk_divider("esdhc1_div", "esdhc_sel", base + MX35_CCM_PDR3, 0, 6);
145 clk[esdhc2_div] = imx_clk_divider("esdhc2_div", "esdhc_sel", base + MX35_CCM_PDR3, 8, 6);
146 clk[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base + MX35_CCM_PDR3, 16, 6);
147
148 clk[spdif_sel] = imx_clk_mux("spdif_sel", base + MX35_CCM_PDR3, 22, 1, std_sel, ARRAY_SIZE(std_sel));
149 clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel", base + MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */
150 clk[spdif_div_post] = imx_clk_divider("spdif_div_post", "spdif_div_pre", base + MX35_CCM_PDR3, 23, 6);
151
152 clk[ssi_sel] = imx_clk_mux("ssi_sel", base + MX35_CCM_PDR2, 6, 1, std_sel, ARRAY_SIZE(std_sel));
153 clk[ssi1_div_pre] = imx_clk_divider("ssi1_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 24, 3);
154 clk[ssi1_div_post] = imx_clk_divider("ssi1_div_post", "ssi1_div_pre", base + MX35_CCM_PDR2, 0, 6);
155 clk[ssi2_div_pre] = imx_clk_divider("ssi2_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 27, 3);
156 clk[ssi2_div_post] = imx_clk_divider("ssi2_div_post", "ssi2_div_pre", base + MX35_CCM_PDR2, 8, 6);
157
158 clk[usb_sel] = imx_clk_mux("usb_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
159 clk[usb_div] = imx_clk_divider("usb_div", "usb_sel", base + MX35_CCM_PDR4, 22, 6);
160
161 clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + MX35_CCM_PDR4, 28, 4);
162
163 clk[csi_sel] = imx_clk_mux("csi_sel", base + MX35_CCM_PDR2, 7, 1, std_sel, ARRAY_SIZE(std_sel));
164 clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MX35_CCM_PDR2, 16, 6);
165
166 clk[asrc_gate] = imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0, 0);
167 clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0, 2);
168 clk[audmux_gate] = imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0, 4);
169 clk[can1_gate] = imx_clk_gate2("can1_gate", "ipg", base + MX35_CCM_CGR0, 6);
170 clk[can2_gate] = imx_clk_gate2("can2_gate", "ipg", base + MX35_CCM_CGR0, 8);
171 clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MX35_CCM_CGR0, 10);
172 clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MX35_CCM_CGR0, 12);
173 clk[ect_gate] = imx_clk_gate2("ect_gate", "ipg", base + MX35_CCM_CGR0, 14);
174 clk[edio_gate] = imx_clk_gate2("edio_gate", "ipg", base + MX35_CCM_CGR0, 16);
175 clk[emi_gate] = imx_clk_gate2("emi_gate", "ipg", base + MX35_CCM_CGR0, 18);
176 clk[epit1_gate] = imx_clk_gate2("epit1_gate", "ipg", base + MX35_CCM_CGR0, 20);
177 clk[epit2_gate] = imx_clk_gate2("epit2_gate", "ipg", base + MX35_CCM_CGR0, 22);
178 clk[esai_gate] = imx_clk_gate2("esai_gate", "ipg", base + MX35_CCM_CGR0, 24);
179 clk[esdhc1_gate] = imx_clk_gate2("esdhc1_gate", "esdhc1_div", base + MX35_CCM_CGR0, 26);
180 clk[esdhc2_gate] = imx_clk_gate2("esdhc2_gate", "esdhc2_div", base + MX35_CCM_CGR0, 28);
181 clk[esdhc3_gate] = imx_clk_gate2("esdhc3_gate", "esdhc3_div", base + MX35_CCM_CGR0, 30);
182
183 clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", base + MX35_CCM_CGR1, 0);
184 clk[gpio1_gate] = imx_clk_gate2("gpio1_gate", "ipg", base + MX35_CCM_CGR1, 2);
185 clk[gpio2_gate] = imx_clk_gate2("gpio2_gate", "ipg", base + MX35_CCM_CGR1, 4);
186 clk[gpio3_gate] = imx_clk_gate2("gpio3_gate", "ipg", base + MX35_CCM_CGR1, 6);
187 clk[gpt_gate] = imx_clk_gate2("gpt_gate", "ipg", base + MX35_CCM_CGR1, 8);
188 clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "ipg_per", base + MX35_CCM_CGR1, 10);
189 clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "ipg_per", base + MX35_CCM_CGR1, 12);
190 clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "ipg_per", base + MX35_CCM_CGR1, 14);
191 clk[iomuxc_gate] = imx_clk_gate2("iomuxc_gate", "ipg", base + MX35_CCM_CGR1, 16);
192 clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MX35_CCM_CGR1, 18);
193 clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MX35_CCM_CGR1, 20);
194 clk[mlb_gate] = imx_clk_gate2("mlb_gate", "ahb", base + MX35_CCM_CGR1, 22);
195 clk[mshc_gate] = imx_clk_gate2("mshc_gate", "dummy", base + MX35_CCM_CGR1, 24);
196 clk[owire_gate] = imx_clk_gate2("owire_gate", "ipg_per", base + MX35_CCM_CGR1, 26);
197 clk[pwm_gate] = imx_clk_gate2("pwm_gate", "ipg_per", base + MX35_CCM_CGR1, 28);
198 clk[rngc_gate] = imx_clk_gate2("rngc_gate", "ipg", base + MX35_CCM_CGR1, 30);
199
200 clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MX35_CCM_CGR2, 0);
201 clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MX35_CCM_CGR2, 2);
202 clk[scc_gate] = imx_clk_gate2("scc_gate", "ipg", base + MX35_CCM_CGR2, 4);
203 clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MX35_CCM_CGR2, 6);
204 clk[spba_gate] = imx_clk_gate2("spba_gate", "ipg", base + MX35_CCM_CGR2, 8);
205 clk[spdif_gate] = imx_clk_gate2("spdif_gate", "spdif_div_post", base + MX35_CCM_CGR2, 10);
206 clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "ssi1_div_post", base + MX35_CCM_CGR2, 12);
207 clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "ssi2_div_post", base + MX35_CCM_CGR2, 14);
208 clk[uart1_gate] = imx_clk_gate2("uart1_gate", "uart_div", base + MX35_CCM_CGR2, 16);
209 clk[uart2_gate] = imx_clk_gate2("uart2_gate", "uart_div", base + MX35_CCM_CGR2, 18);
210 clk[uart3_gate] = imx_clk_gate2("uart3_gate", "uart_div", base + MX35_CCM_CGR2, 20);
211 clk[usbotg_gate] = imx_clk_gate2("usbotg_gate", "ahb", base + MX35_CCM_CGR2, 22);
212 clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MX35_CCM_CGR2, 24);
213 clk[max_gate] = imx_clk_gate2("max_gate", "dummy", base + MX35_CCM_CGR2, 26);
214 clk[admux_gate] = imx_clk_gate2("admux_gate", "ipg", base + MX35_CCM_CGR2, 30);
215
216 clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", base + MX35_CCM_CGR3, 0);
217 clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3, 2);
218 clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3, 4);
219
220 imx_check_clocks(clk, ARRAY_SIZE(clk));
221
222 clk_register_clkdev(clk[pata_gate], NULL, "pata_imx");
223 clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0");
224 clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1");
225 clk_register_clkdev(clk[cspi1_gate], "per", "imx35-cspi.0");
226 clk_register_clkdev(clk[cspi1_gate], "ipg", "imx35-cspi.0");
227 clk_register_clkdev(clk[cspi2_gate], "per", "imx35-cspi.1");
228 clk_register_clkdev(clk[cspi2_gate], "ipg", "imx35-cspi.1");
229 clk_register_clkdev(clk[epit1_gate], NULL, "imx-epit.0");
230 clk_register_clkdev(clk[epit2_gate], NULL, "imx-epit.1");
231 clk_register_clkdev(clk[esdhc1_gate], "per", "sdhci-esdhc-imx35.0");
232 clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.0");
233 clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.0");
234 clk_register_clkdev(clk[esdhc2_gate], "per", "sdhci-esdhc-imx35.1");
235 clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.1");
236 clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.1");
237 clk_register_clkdev(clk[esdhc3_gate], "per", "sdhci-esdhc-imx35.2");
238 clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.2");
239 clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.2");
240 /* i.mx35 has the i.mx27 type fec */
241 clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0");
242 clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
243 clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
244 clk_register_clkdev(clk[i2c1_gate], NULL, "imx21-i2c.0");
245 clk_register_clkdev(clk[i2c2_gate], NULL, "imx21-i2c.1");
246 clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2");
247 clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
248 clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
249 clk_register_clkdev(clk[kpp_gate], NULL, "imx-keypad");
250 clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1");
251 clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
252 clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0");
253 clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1");
254 /* i.mx35 has the i.mx21 type uart */
255 clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
256 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0");
257 clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1");
258 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1");
259 clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2");
260 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2");
261 clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
262 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
263 clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.0");
264 clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1");
265 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
266 clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.1");
267 clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
268 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
269 clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.2");
270 clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx27");
271 clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx27");
272 clk_register_clkdev(clk[usbotg_gate], "ahb", "imx-udc-mx27");
273 clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
274 clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
275 clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
276 clk_register_clkdev(clk[admux_gate], "audmux", NULL);
277
278 clk_prepare_enable(clk[spba_gate]);
279 clk_prepare_enable(clk[gpio1_gate]);
280 clk_prepare_enable(clk[gpio2_gate]);
281 clk_prepare_enable(clk[gpio3_gate]);
282 clk_prepare_enable(clk[iim_gate]);
283 clk_prepare_enable(clk[emi_gate]);
284 clk_prepare_enable(clk[max_gate]);
285 clk_prepare_enable(clk[iomuxc_gate]);
286
287 /*
288 * SCC is needed to boot via mmc after a watchdog reset. The clock code
289 * before conversion to common clk also enabled UART1 (which isn't
290 * handled here and not needed for mmc) and IIM (which is enabled
291 * unconditionally above).
292 */
293 clk_prepare_enable(clk[scc_gate]);
294
295 imx_print_silicon_rev("i.MX35", mx35_revision());
296
297 mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, GPT_TYPE_IMX31);
298
299 return 0;
300}
301
302static void __init mx35_clocks_init_dt(struct device_node *ccm_node)
303{
304 clk_data.clks = clk;
305 clk_data.clk_num = ARRAY_SIZE(clk);
306 of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
307
308 mx35_clocks_init();
309}
310CLK_OF_DECLARE(imx35, "fsl,imx35-ccm", mx35_clocks_init_dt);
diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c
new file mode 100644
index 000000000000..a7e4f394be0d
--- /dev/null
+++ b/drivers/clk/imx/clk-imx51-imx53.c
@@ -0,0 +1,570 @@
1/*
2 * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
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 */
9#include <linux/mm.h>
10#include <linux/delay.h>
11#include <linux/clk.h>
12#include <linux/io.h>
13#include <linux/clkdev.h>
14#include <linux/clk-provider.h>
15#include <linux/err.h>
16#include <linux/of.h>
17#include <linux/of_address.h>
18#include <linux/of_irq.h>
19#include <soc/imx/revision.h>
20#include <dt-bindings/clock/imx5-clock.h>
21
22#include "clk.h"
23
24#define MX51_DPLL1_BASE 0x83f80000
25#define MX51_DPLL2_BASE 0x83f84000
26#define MX51_DPLL3_BASE 0x83f88000
27
28#define MX53_DPLL1_BASE 0x63f80000
29#define MX53_DPLL2_BASE 0x63f84000
30#define MX53_DPLL3_BASE 0x63f88000
31#define MX53_DPLL4_BASE 0x63f8c000
32
33#define MXC_CCM_CCR (ccm_base + 0x00)
34#define MXC_CCM_CCDR (ccm_base + 0x04)
35#define MXC_CCM_CSR (ccm_base + 0x08)
36#define MXC_CCM_CCSR (ccm_base + 0x0c)
37#define MXC_CCM_CACRR (ccm_base + 0x10)
38#define MXC_CCM_CBCDR (ccm_base + 0x14)
39#define MXC_CCM_CBCMR (ccm_base + 0x18)
40#define MXC_CCM_CSCMR1 (ccm_base + 0x1c)
41#define MXC_CCM_CSCMR2 (ccm_base + 0x20)
42#define MXC_CCM_CSCDR1 (ccm_base + 0x24)
43#define MXC_CCM_CS1CDR (ccm_base + 0x28)
44#define MXC_CCM_CS2CDR (ccm_base + 0x2c)
45#define MXC_CCM_CDCDR (ccm_base + 0x30)
46#define MXC_CCM_CHSCDR (ccm_base + 0x34)
47#define MXC_CCM_CSCDR2 (ccm_base + 0x38)
48#define MXC_CCM_CSCDR3 (ccm_base + 0x3c)
49#define MXC_CCM_CSCDR4 (ccm_base + 0x40)
50#define MXC_CCM_CWDR (ccm_base + 0x44)
51#define MXC_CCM_CDHIPR (ccm_base + 0x48)
52#define MXC_CCM_CDCR (ccm_base + 0x4c)
53#define MXC_CCM_CTOR (ccm_base + 0x50)
54#define MXC_CCM_CLPCR (ccm_base + 0x54)
55#define MXC_CCM_CISR (ccm_base + 0x58)
56#define MXC_CCM_CIMR (ccm_base + 0x5c)
57#define MXC_CCM_CCOSR (ccm_base + 0x60)
58#define MXC_CCM_CGPR (ccm_base + 0x64)
59#define MXC_CCM_CCGR0 (ccm_base + 0x68)
60#define MXC_CCM_CCGR1 (ccm_base + 0x6c)
61#define MXC_CCM_CCGR2 (ccm_base + 0x70)
62#define MXC_CCM_CCGR3 (ccm_base + 0x74)
63#define MXC_CCM_CCGR4 (ccm_base + 0x78)
64#define MXC_CCM_CCGR5 (ccm_base + 0x7c)
65#define MXC_CCM_CCGR6 (ccm_base + 0x80)
66#define MXC_CCM_CCGR7 (ccm_base + 0x84)
67
68/* Low-power Audio Playback Mode clock */
69static const char *lp_apm_sel[] = { "osc", };
70
71/* This is used multiple times */
72static const char *standard_pll_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "lp_apm", };
73static const char *periph_apm_sel[] = { "pll1_sw", "pll3_sw", "lp_apm", };
74static const char *main_bus_sel[] = { "pll2_sw", "periph_apm", };
75static const char *per_lp_apm_sel[] = { "main_bus", "lp_apm", };
76static const char *per_root_sel[] = { "per_podf", "ipg", };
77static const char *esdhc_c_sel[] = { "esdhc_a_podf", "esdhc_b_podf", };
78static const char *esdhc_d_sel[] = { "esdhc_a_podf", "esdhc_b_podf", };
79static const char *ssi_apm_sels[] = { "ckih1", "lp_amp", "ckih2", };
80static const char *ssi_clk_sels[] = { "pll1_sw", "pll2_sw", "pll3_sw", "ssi_apm", };
81static const char *ssi3_clk_sels[] = { "ssi1_root_gate", "ssi2_root_gate", };
82static const char *ssi_ext1_com_sels[] = { "ssi_ext1_podf", "ssi1_root_gate", };
83static const char *ssi_ext2_com_sels[] = { "ssi_ext2_podf", "ssi2_root_gate", };
84static const char *emi_slow_sel[] = { "main_bus", "ahb", };
85static const char *usb_phy_sel_str[] = { "osc", "usb_phy_podf", };
86static const char *mx51_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "tve_di", };
87static const char *mx53_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "di_pll4_podf", "dummy", "ldb_di0_gate", };
88static const char *mx53_ldb_di0_sel[] = { "pll3_sw", "pll4_sw", };
89static const char *mx51_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", };
90static const char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", "ldb_di1_gate", };
91static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", };
92static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", };
93static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", };
94static const char *mx51_tve_sel[] = { "tve_pred", "tve_ext_sel", };
95static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
96static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" };
97static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" };
98static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
99static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", };
100static const char *mx53_cko1_sel[] = {
101 "cpu_podf", "pll1_sw", "pll2_sw", "pll3_sw",
102 "emi_slow_podf", "pll4_sw", "nfc_podf", "dummy",
103 "di_pred", "dummy", "dummy", "ahb",
104 "ipg", "per_root", "ckil", "dummy",};
105static const char *mx53_cko2_sel[] = {
106 "dummy"/* dptc_core */, "dummy"/* dptc_perich */,
107 "dummy", "esdhc_a_podf",
108 "usboh3_podf", "dummy"/* wrck_clk_root */,
109 "ecspi_podf", "dummy"/* pll1_ref_clk */,
110 "esdhc_b_podf", "dummy"/* ddr_clk_root */,
111 "dummy"/* arm_axi_clk_root */, "dummy"/* usb_phy_out */,
112 "vpu_sel", "ipu_sel",
113 "osc", "ckih1",
114 "dummy", "esdhc_c_sel",
115 "ssi1_root_podf", "ssi2_root_podf",
116 "dummy", "dummy",
117 "dummy"/* lpsr_clk_root */, "dummy"/* pgc_clk_root */,
118 "dummy"/* tve_out */, "usb_phy_sel",
119 "tve_sel", "lp_apm",
120 "uart_root", "dummy"/* spdif0_clk_root */,
121 "dummy", "dummy", };
122static const char *mx51_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", };
123static const char *mx53_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", "pll4_sw", };
124static const char *spdif_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "spdif_xtal_sel", };
125static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", };
126static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", };
127static const char *step_sels[] = { "lp_apm", };
128static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" };
129
130static struct clk *clk[IMX5_CLK_END];
131static struct clk_onecell_data clk_data;
132
133static void __init mx5_clocks_common_init(void __iomem *ccm_base)
134{
135 clk[IMX5_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
136 clk[IMX5_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
137 clk[IMX5_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
138 clk[IMX5_CLK_CKIH1] = imx_obtain_fixed_clock("ckih1", 0);
139 clk[IMX5_CLK_CKIH2] = imx_obtain_fixed_clock("ckih2", 0);
140
141 clk[IMX5_CLK_PERIPH_APM] = imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2,
142 periph_apm_sel, ARRAY_SIZE(periph_apm_sel));
143 clk[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1,
144 main_bus_sel, ARRAY_SIZE(main_bus_sel));
145 clk[IMX5_CLK_PER_LP_APM] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCMR, 1, 1,
146 per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel));
147 clk[IMX5_CLK_PER_PRED1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2);
148 clk[IMX5_CLK_PER_PRED2] = imx_clk_divider("per_pred2", "per_pred1", MXC_CCM_CBCDR, 3, 3);
149 clk[IMX5_CLK_PER_PODF] = imx_clk_divider("per_podf", "per_pred2", MXC_CCM_CBCDR, 0, 3);
150 clk[IMX5_CLK_PER_ROOT] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1,
151 per_root_sel, ARRAY_SIZE(per_root_sel));
152 clk[IMX5_CLK_AHB] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3);
153 clk[IMX5_CLK_AHB_MAX] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28);
154 clk[IMX5_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24);
155 clk[IMX5_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26);
156 clk[IMX5_CLK_TMAX1] = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0);
157 clk[IMX5_CLK_TMAX2] = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2);
158 clk[IMX5_CLK_TMAX3] = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4);
159 clk[IMX5_CLK_SPBA] = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0);
160 clk[IMX5_CLK_IPG] = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2);
161 clk[IMX5_CLK_AXI_A] = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3);
162 clk[IMX5_CLK_AXI_B] = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3);
163 clk[IMX5_CLK_UART_SEL] = imx_clk_mux("uart_sel", MXC_CCM_CSCMR1, 24, 2,
164 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
165 clk[IMX5_CLK_UART_PRED] = imx_clk_divider("uart_pred", "uart_sel", MXC_CCM_CSCDR1, 3, 3);
166 clk[IMX5_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_pred", MXC_CCM_CSCDR1, 0, 3);
167
168 clk[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2,
169 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
170 clk[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2,
171 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
172 clk[IMX5_CLK_ESDHC_A_PRED] = imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", MXC_CCM_CSCDR1, 16, 3);
173 clk[IMX5_CLK_ESDHC_A_PODF] = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", MXC_CCM_CSCDR1, 11, 3);
174 clk[IMX5_CLK_ESDHC_B_PRED] = imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", MXC_CCM_CSCDR1, 22, 3);
175 clk[IMX5_CLK_ESDHC_B_PODF] = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", MXC_CCM_CSCDR1, 19, 3);
176 clk[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
177 clk[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
178
179 clk[IMX5_CLK_EMI_SEL] = imx_clk_mux("emi_sel", MXC_CCM_CBCDR, 26, 1,
180 emi_slow_sel, ARRAY_SIZE(emi_slow_sel));
181 clk[IMX5_CLK_EMI_SLOW_PODF] = imx_clk_divider("emi_slow_podf", "emi_sel", MXC_CCM_CBCDR, 22, 3);
182 clk[IMX5_CLK_NFC_PODF] = imx_clk_divider("nfc_podf", "emi_slow_podf", MXC_CCM_CBCDR, 13, 3);
183 clk[IMX5_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", MXC_CCM_CSCMR1, 4, 2,
184 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
185 clk[IMX5_CLK_ECSPI_PRED] = imx_clk_divider("ecspi_pred", "ecspi_sel", MXC_CCM_CSCDR2, 25, 3);
186 clk[IMX5_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_pred", MXC_CCM_CSCDR2, 19, 6);
187 clk[IMX5_CLK_USBOH3_SEL] = imx_clk_mux("usboh3_sel", MXC_CCM_CSCMR1, 22, 2,
188 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
189 clk[IMX5_CLK_USBOH3_PRED] = imx_clk_divider("usboh3_pred", "usboh3_sel", MXC_CCM_CSCDR1, 8, 3);
190 clk[IMX5_CLK_USBOH3_PODF] = imx_clk_divider("usboh3_podf", "usboh3_pred", MXC_CCM_CSCDR1, 6, 2);
191 clk[IMX5_CLK_USB_PHY_PRED] = imx_clk_divider("usb_phy_pred", "pll3_sw", MXC_CCM_CDCDR, 3, 3);
192 clk[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3);
193 clk[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1,
194 usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
195 clk[IMX5_CLK_STEP_SEL] = imx_clk_mux("step_sel", MXC_CCM_CCSR, 7, 2, step_sels, ARRAY_SIZE(step_sels));
196 clk[IMX5_CLK_CPU_PODF_SEL] = imx_clk_mux("cpu_podf_sel", MXC_CCM_CCSR, 2, 1, cpu_podf_sels, ARRAY_SIZE(cpu_podf_sels));
197 clk[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf", "cpu_podf_sel", MXC_CCM_CACRR, 0, 3);
198 clk[IMX5_CLK_DI_PRED] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3);
199 clk[IMX5_CLK_IIM_GATE] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30);
200 clk[IMX5_CLK_UART1_IPG_GATE] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6);
201 clk[IMX5_CLK_UART1_PER_GATE] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8);
202 clk[IMX5_CLK_UART2_IPG_GATE] = imx_clk_gate2("uart2_ipg_gate", "ipg", MXC_CCM_CCGR1, 10);
203 clk[IMX5_CLK_UART2_PER_GATE] = imx_clk_gate2("uart2_per_gate", "uart_root", MXC_CCM_CCGR1, 12);
204 clk[IMX5_CLK_UART3_IPG_GATE] = imx_clk_gate2("uart3_ipg_gate", "ipg", MXC_CCM_CCGR1, 14);
205 clk[IMX5_CLK_UART3_PER_GATE] = imx_clk_gate2("uart3_per_gate", "uart_root", MXC_CCM_CCGR1, 16);
206 clk[IMX5_CLK_I2C1_GATE] = imx_clk_gate2("i2c1_gate", "per_root", MXC_CCM_CCGR1, 18);
207 clk[IMX5_CLK_I2C2_GATE] = imx_clk_gate2("i2c2_gate", "per_root", MXC_CCM_CCGR1, 20);
208 clk[IMX5_CLK_PWM1_IPG_GATE] = imx_clk_gate2("pwm1_ipg_gate", "ipg", MXC_CCM_CCGR2, 10);
209 clk[IMX5_CLK_PWM1_HF_GATE] = imx_clk_gate2("pwm1_hf_gate", "per_root", MXC_CCM_CCGR2, 12);
210 clk[IMX5_CLK_PWM2_IPG_GATE] = imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14);
211 clk[IMX5_CLK_PWM2_HF_GATE] = imx_clk_gate2("pwm2_hf_gate", "per_root", MXC_CCM_CCGR2, 16);
212 clk[IMX5_CLK_GPT_IPG_GATE] = imx_clk_gate2("gpt_ipg_gate", "ipg", MXC_CCM_CCGR2, 18);
213 clk[IMX5_CLK_GPT_HF_GATE] = imx_clk_gate2("gpt_hf_gate", "per_root", MXC_CCM_CCGR2, 20);
214 clk[IMX5_CLK_FEC_GATE] = imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24);
215 clk[IMX5_CLK_USBOH3_GATE] = imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26);
216 clk[IMX5_CLK_USBOH3_PER_GATE] = imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28);
217 clk[IMX5_CLK_ESDHC1_IPG_GATE] = imx_clk_gate2("esdhc1_ipg_gate", "ipg", MXC_CCM_CCGR3, 0);
218 clk[IMX5_CLK_ESDHC2_IPG_GATE] = imx_clk_gate2("esdhc2_ipg_gate", "ipg", MXC_CCM_CCGR3, 4);
219 clk[IMX5_CLK_ESDHC3_IPG_GATE] = imx_clk_gate2("esdhc3_ipg_gate", "ipg", MXC_CCM_CCGR3, 8);
220 clk[IMX5_CLK_ESDHC4_IPG_GATE] = imx_clk_gate2("esdhc4_ipg_gate", "ipg", MXC_CCM_CCGR3, 12);
221 clk[IMX5_CLK_SSI1_IPG_GATE] = imx_clk_gate2("ssi1_ipg_gate", "ipg", MXC_CCM_CCGR3, 16);
222 clk[IMX5_CLK_SSI2_IPG_GATE] = imx_clk_gate2("ssi2_ipg_gate", "ipg", MXC_CCM_CCGR3, 20);
223 clk[IMX5_CLK_SSI3_IPG_GATE] = imx_clk_gate2("ssi3_ipg_gate", "ipg", MXC_CCM_CCGR3, 24);
224 clk[IMX5_CLK_ECSPI1_IPG_GATE] = imx_clk_gate2("ecspi1_ipg_gate", "ipg", MXC_CCM_CCGR4, 18);
225 clk[IMX5_CLK_ECSPI1_PER_GATE] = imx_clk_gate2("ecspi1_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 20);
226 clk[IMX5_CLK_ECSPI2_IPG_GATE] = imx_clk_gate2("ecspi2_ipg_gate", "ipg", MXC_CCM_CCGR4, 22);
227 clk[IMX5_CLK_ECSPI2_PER_GATE] = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24);
228 clk[IMX5_CLK_CSPI_IPG_GATE] = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26);
229 clk[IMX5_CLK_SDMA_GATE] = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30);
230 clk[IMX5_CLK_EMI_FAST_GATE] = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14);
231 clk[IMX5_CLK_EMI_SLOW_GATE] = imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16);
232 clk[IMX5_CLK_IPU_SEL] = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel));
233 clk[IMX5_CLK_IPU_GATE] = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10);
234 clk[IMX5_CLK_NFC_GATE] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20);
235 clk[IMX5_CLK_IPU_DI0_GATE] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10);
236 clk[IMX5_CLK_IPU_DI1_GATE] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12);
237 clk[IMX5_CLK_GPU3D_SEL] = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel));
238 clk[IMX5_CLK_GPU2D_SEL] = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel));
239 clk[IMX5_CLK_GPU3D_GATE] = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2);
240 clk[IMX5_CLK_GARB_GATE] = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4);
241 clk[IMX5_CLK_GPU2D_GATE] = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14);
242 clk[IMX5_CLK_VPU_SEL] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel));
243 clk[IMX5_CLK_VPU_GATE] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6);
244 clk[IMX5_CLK_VPU_REFERENCE_GATE] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8);
245 clk[IMX5_CLK_UART4_IPG_GATE] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8);
246 clk[IMX5_CLK_UART4_PER_GATE] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10);
247 clk[IMX5_CLK_UART5_IPG_GATE] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12);
248 clk[IMX5_CLK_UART5_PER_GATE] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14);
249 clk[IMX5_CLK_GPC_DVFS] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24);
250
251 clk[IMX5_CLK_SSI_APM] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels));
252 clk[IMX5_CLK_SSI1_ROOT_SEL] = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
253 clk[IMX5_CLK_SSI2_ROOT_SEL] = imx_clk_mux("ssi2_root_sel", MXC_CCM_CSCMR1, 12, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
254 clk[IMX5_CLK_SSI3_ROOT_SEL] = imx_clk_mux("ssi3_root_sel", MXC_CCM_CSCMR1, 11, 1, ssi3_clk_sels, ARRAY_SIZE(ssi3_clk_sels));
255 clk[IMX5_CLK_SSI_EXT1_SEL] = imx_clk_mux("ssi_ext1_sel", MXC_CCM_CSCMR1, 28, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
256 clk[IMX5_CLK_SSI_EXT2_SEL] = imx_clk_mux("ssi_ext2_sel", MXC_CCM_CSCMR1, 30, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
257 clk[IMX5_CLK_SSI_EXT1_COM_SEL] = imx_clk_mux("ssi_ext1_com_sel", MXC_CCM_CSCMR1, 0, 1, ssi_ext1_com_sels, ARRAY_SIZE(ssi_ext1_com_sels));
258 clk[IMX5_CLK_SSI_EXT2_COM_SEL] = imx_clk_mux("ssi_ext2_com_sel", MXC_CCM_CSCMR1, 1, 1, ssi_ext2_com_sels, ARRAY_SIZE(ssi_ext2_com_sels));
259 clk[IMX5_CLK_SSI1_ROOT_PRED] = imx_clk_divider("ssi1_root_pred", "ssi1_root_sel", MXC_CCM_CS1CDR, 6, 3);
260 clk[IMX5_CLK_SSI1_ROOT_PODF] = imx_clk_divider("ssi1_root_podf", "ssi1_root_pred", MXC_CCM_CS1CDR, 0, 6);
261 clk[IMX5_CLK_SSI2_ROOT_PRED] = imx_clk_divider("ssi2_root_pred", "ssi2_root_sel", MXC_CCM_CS2CDR, 6, 3);
262 clk[IMX5_CLK_SSI2_ROOT_PODF] = imx_clk_divider("ssi2_root_podf", "ssi2_root_pred", MXC_CCM_CS2CDR, 0, 6);
263 clk[IMX5_CLK_SSI_EXT1_PRED] = imx_clk_divider("ssi_ext1_pred", "ssi_ext1_sel", MXC_CCM_CS1CDR, 22, 3);
264 clk[IMX5_CLK_SSI_EXT1_PODF] = imx_clk_divider("ssi_ext1_podf", "ssi_ext1_pred", MXC_CCM_CS1CDR, 16, 6);
265 clk[IMX5_CLK_SSI_EXT2_PRED] = imx_clk_divider("ssi_ext2_pred", "ssi_ext2_sel", MXC_CCM_CS2CDR, 22, 3);
266 clk[IMX5_CLK_SSI_EXT2_PODF] = imx_clk_divider("ssi_ext2_podf", "ssi_ext2_pred", MXC_CCM_CS2CDR, 16, 6);
267 clk[IMX5_CLK_SSI1_ROOT_GATE] = imx_clk_gate2("ssi1_root_gate", "ssi1_root_podf", MXC_CCM_CCGR3, 18);
268 clk[IMX5_CLK_SSI2_ROOT_GATE] = imx_clk_gate2("ssi2_root_gate", "ssi2_root_podf", MXC_CCM_CCGR3, 22);
269 clk[IMX5_CLK_SSI3_ROOT_GATE] = imx_clk_gate2("ssi3_root_gate", "ssi3_root_sel", MXC_CCM_CCGR3, 26);
270 clk[IMX5_CLK_SSI_EXT1_GATE] = imx_clk_gate2("ssi_ext1_gate", "ssi_ext1_com_sel", MXC_CCM_CCGR3, 28);
271 clk[IMX5_CLK_SSI_EXT2_GATE] = imx_clk_gate2("ssi_ext2_gate", "ssi_ext2_com_sel", MXC_CCM_CCGR3, 30);
272 clk[IMX5_CLK_EPIT1_IPG_GATE] = imx_clk_gate2("epit1_ipg_gate", "ipg", MXC_CCM_CCGR2, 2);
273 clk[IMX5_CLK_EPIT1_HF_GATE] = imx_clk_gate2("epit1_hf_gate", "per_root", MXC_CCM_CCGR2, 4);
274 clk[IMX5_CLK_EPIT2_IPG_GATE] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6);
275 clk[IMX5_CLK_EPIT2_HF_GATE] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8);
276 clk[IMX5_CLK_OWIRE_GATE] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22);
277 clk[IMX5_CLK_SRTC_GATE] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28);
278 clk[IMX5_CLK_PATA_GATE] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0);
279 clk[IMX5_CLK_SPDIF0_SEL] = imx_clk_mux("spdif0_sel", MXC_CCM_CSCMR2, 0, 2, spdif_sel, ARRAY_SIZE(spdif_sel));
280 clk[IMX5_CLK_SPDIF0_PRED] = imx_clk_divider("spdif0_pred", "spdif0_sel", MXC_CCM_CDCDR, 25, 3);
281 clk[IMX5_CLK_SPDIF0_PODF] = imx_clk_divider("spdif0_podf", "spdif0_pred", MXC_CCM_CDCDR, 19, 6);
282 clk[IMX5_CLK_SPDIF0_COM_SEL] = imx_clk_mux_flags("spdif0_com_sel", MXC_CCM_CSCMR2, 4, 1,
283 spdif0_com_sel, ARRAY_SIZE(spdif0_com_sel), CLK_SET_RATE_PARENT);
284 clk[IMX5_CLK_SPDIF0_GATE] = imx_clk_gate2("spdif0_gate", "spdif0_com_sel", MXC_CCM_CCGR5, 26);
285 clk[IMX5_CLK_SPDIF_IPG_GATE] = imx_clk_gate2("spdif_ipg_gate", "ipg", MXC_CCM_CCGR5, 30);
286 clk[IMX5_CLK_SAHARA_IPG_GATE] = imx_clk_gate2("sahara_ipg_gate", "ipg", MXC_CCM_CCGR4, 14);
287 clk[IMX5_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "usb_phy1_gate", 1, 1);
288
289 clk_register_clkdev(clk[IMX5_CLK_CPU_PODF], NULL, "cpu0");
290 clk_register_clkdev(clk[IMX5_CLK_GPC_DVFS], "gpc_dvfs", NULL);
291
292 /* Set SDHC parents to be PLL2 */
293 clk_set_parent(clk[IMX5_CLK_ESDHC_A_SEL], clk[IMX5_CLK_PLL2_SW]);
294 clk_set_parent(clk[IMX5_CLK_ESDHC_B_SEL], clk[IMX5_CLK_PLL2_SW]);
295
296 /* move usb phy clk to 24MHz */
297 clk_set_parent(clk[IMX5_CLK_USB_PHY_SEL], clk[IMX5_CLK_OSC]);
298
299 clk_prepare_enable(clk[IMX5_CLK_GPC_DVFS]);
300 clk_prepare_enable(clk[IMX5_CLK_AHB_MAX]); /* esdhc3 */
301 clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ1]);
302 clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ2]); /* fec */
303 clk_prepare_enable(clk[IMX5_CLK_SPBA]);
304 clk_prepare_enable(clk[IMX5_CLK_EMI_FAST_GATE]); /* fec */
305 clk_prepare_enable(clk[IMX5_CLK_EMI_SLOW_GATE]); /* eim */
306 clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC1_GATE]);
307 clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC2_GATE]);
308 clk_prepare_enable(clk[IMX5_CLK_MIPI_ESC_GATE]);
309 clk_prepare_enable(clk[IMX5_CLK_MIPI_HSP_GATE]);
310 clk_prepare_enable(clk[IMX5_CLK_TMAX1]);
311 clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */
312 clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */
313}
314
315static void __init mx50_clocks_init(struct device_node *np)
316{
317 void __iomem *ccm_base;
318 void __iomem *pll_base;
319 unsigned long r;
320
321 pll_base = ioremap(MX53_DPLL1_BASE, SZ_16K);
322 WARN_ON(!pll_base);
323 clk[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", pll_base);
324
325 pll_base = ioremap(MX53_DPLL2_BASE, SZ_16K);
326 WARN_ON(!pll_base);
327 clk[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", pll_base);
328
329 pll_base = ioremap(MX53_DPLL3_BASE, SZ_16K);
330 WARN_ON(!pll_base);
331 clk[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", pll_base);
332
333 ccm_base = of_iomap(np, 0);
334 WARN_ON(!ccm_base);
335
336 mx5_clocks_common_init(ccm_base);
337
338 clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1,
339 lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
340 clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
341 clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6);
342 clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10);
343 clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
344 clk[IMX5_CLK_USB_PHY1_GATE] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10);
345 clk[IMX5_CLK_USB_PHY2_GATE] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12);
346 clk[IMX5_CLK_I2C3_GATE] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
347
348 clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
349 mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
350 clk[IMX5_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3);
351 clk[IMX5_CLK_CKO1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7);
352
353 clk[IMX5_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5,
354 mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel));
355 clk[IMX5_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3);
356 clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
357
358 imx_check_clocks(clk, ARRAY_SIZE(clk));
359
360 clk_data.clks = clk;
361 clk_data.clk_num = ARRAY_SIZE(clk);
362 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
363
364 /* set SDHC root clock to 200MHZ*/
365 clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000);
366 clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000);
367
368 clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]);
369 imx_print_silicon_rev("i.MX50", IMX_CHIP_REVISION_1_1);
370 clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]);
371
372 r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
373 clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
374}
375CLK_OF_DECLARE(imx50_ccm, "fsl,imx50-ccm", mx50_clocks_init);
376
377static void __init mx51_clocks_init(struct device_node *np)
378{
379 void __iomem *ccm_base;
380 void __iomem *pll_base;
381 u32 val;
382
383 pll_base = ioremap(MX51_DPLL1_BASE, SZ_16K);
384 WARN_ON(!pll_base);
385 clk[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", pll_base);
386
387 pll_base = ioremap(MX51_DPLL2_BASE, SZ_16K);
388 WARN_ON(!pll_base);
389 clk[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", pll_base);
390
391 pll_base = ioremap(MX51_DPLL3_BASE, SZ_16K);
392 WARN_ON(!pll_base);
393 clk[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", pll_base);
394
395 ccm_base = of_iomap(np, 0);
396 WARN_ON(!ccm_base);
397
398 mx5_clocks_common_init(ccm_base);
399
400 clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1,
401 lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
402 clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
403 mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
404 clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
405 mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
406 clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
407 mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT);
408 clk[IMX5_CLK_TVE_SEL] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1,
409 mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel));
410 clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30);
411 clk[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3);
412 clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
413 clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 6);
414 clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 10);
415 clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
416 clk[IMX5_CLK_USB_PHY_GATE] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0);
417 clk[IMX5_CLK_HSI2C_GATE] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22);
418 clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6);
419 clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8);
420 clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10);
421 clk[IMX5_CLK_MIPI_HSP_GATE] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12);
422 clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
423 mx51_spdif_xtal_sel, ARRAY_SIZE(mx51_spdif_xtal_sel));
424 clk[IMX5_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", MXC_CCM_CSCMR2, 2, 2,
425 spdif_sel, ARRAY_SIZE(spdif_sel));
426 clk[IMX5_CLK_SPDIF1_PRED] = imx_clk_divider("spdif1_pred", "spdif1_sel", MXC_CCM_CDCDR, 16, 3);
427 clk[IMX5_CLK_SPDIF1_PODF] = imx_clk_divider("spdif1_podf", "spdif1_pred", MXC_CCM_CDCDR, 9, 6);
428 clk[IMX5_CLK_SPDIF1_COM_SEL] = imx_clk_mux("spdif1_com_sel", MXC_CCM_CSCMR2, 5, 1,
429 mx51_spdif1_com_sel, ARRAY_SIZE(mx51_spdif1_com_sel));
430 clk[IMX5_CLK_SPDIF1_GATE] = imx_clk_gate2("spdif1_gate", "spdif1_com_sel", MXC_CCM_CCGR5, 28);
431
432 imx_check_clocks(clk, ARRAY_SIZE(clk));
433
434 clk_data.clks = clk;
435 clk_data.clk_num = ARRAY_SIZE(clk);
436 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
437
438 /* set the usboh3 parent to pll2_sw */
439 clk_set_parent(clk[IMX5_CLK_USBOH3_SEL], clk[IMX5_CLK_PLL2_SW]);
440
441 /* set SDHC root clock to 166.25MHZ*/
442 clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 166250000);
443 clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 166250000);
444
445 clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]);
446 imx_print_silicon_rev("i.MX51", mx51_revision());
447 clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]);
448
449 /*
450 * Reference Manual says: Functionality of CCDR[18] and CLPCR[23] is no
451 * longer supported. Set to one for better power saving.
452 *
453 * The effect of not setting these bits is that MIPI clocks can't be
454 * enabled without the IPU clock being enabled aswell.
455 */
456 val = readl(MXC_CCM_CCDR);
457 val |= 1 << 18;
458 writel(val, MXC_CCM_CCDR);
459
460 val = readl(MXC_CCM_CLPCR);
461 val |= 1 << 23;
462 writel(val, MXC_CCM_CLPCR);
463}
464CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init);
465
466static void __init mx53_clocks_init(struct device_node *np)
467{
468 void __iomem *ccm_base;
469 void __iomem *pll_base;
470 unsigned long r;
471
472 pll_base = ioremap(MX53_DPLL1_BASE, SZ_16K);
473 WARN_ON(!pll_base);
474 clk[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", pll_base);
475
476 pll_base = ioremap(MX53_DPLL2_BASE, SZ_16K);
477 WARN_ON(!pll_base);
478 clk[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", pll_base);
479
480 pll_base = ioremap(MX53_DPLL3_BASE, SZ_16K);
481 WARN_ON(!pll_base);
482 clk[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", pll_base);
483
484 pll_base = ioremap(MX53_DPLL4_BASE, SZ_16K);
485 WARN_ON(!pll_base);
486 clk[IMX5_CLK_PLL4_SW] = imx_clk_pllv2("pll4_sw", "osc", pll_base);
487
488 ccm_base = of_iomap(np, 0);
489 WARN_ON(!ccm_base);
490
491 mx5_clocks_common_init(ccm_base);
492
493 clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1,
494 lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
495 clk[IMX5_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
496 clk[IMX5_CLK_LDB_DI1_DIV] = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0);
497 clk[IMX5_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
498 mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT);
499 clk[IMX5_CLK_DI_PLL4_PODF] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3);
500 clk[IMX5_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
501 clk[IMX5_CLK_LDB_DI0_DIV] = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0);
502 clk[IMX5_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
503 mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT);
504 clk[IMX5_CLK_LDB_DI0_GATE] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28);
505 clk[IMX5_CLK_LDB_DI1_GATE] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30);
506 clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
507 mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
508 clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
509 mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
510 clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
511 mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT);
512 clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
513 clk[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3);
514 clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
515 clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6);
516 clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10);
517 clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
518 clk[IMX5_CLK_USB_PHY1_GATE] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10);
519 clk[IMX5_CLK_USB_PHY2_GATE] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12);
520 clk[IMX5_CLK_CAN_SEL] = imx_clk_mux("can_sel", MXC_CCM_CSCMR2, 6, 2,
521 mx53_can_sel, ARRAY_SIZE(mx53_can_sel));
522 clk[IMX5_CLK_CAN1_SERIAL_GATE] = imx_clk_gate2("can1_serial_gate", "can_sel", MXC_CCM_CCGR6, 22);
523 clk[IMX5_CLK_CAN1_IPG_GATE] = imx_clk_gate2("can1_ipg_gate", "ipg", MXC_CCM_CCGR6, 20);
524 clk[IMX5_CLK_OCRAM] = imx_clk_gate2("ocram", "ahb", MXC_CCM_CCGR6, 2);
525 clk[IMX5_CLK_CAN2_SERIAL_GATE] = imx_clk_gate2("can2_serial_gate", "can_sel", MXC_CCM_CCGR4, 8);
526 clk[IMX5_CLK_CAN2_IPG_GATE] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6);
527 clk[IMX5_CLK_I2C3_GATE] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
528 clk[IMX5_CLK_SATA_GATE] = imx_clk_gate2("sata_gate", "ipg", MXC_CCM_CCGR4, 2);
529
530 clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
531 mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
532 clk[IMX5_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3);
533 clk[IMX5_CLK_CKO1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7);
534
535 clk[IMX5_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5,
536 mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel));
537 clk[IMX5_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3);
538 clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
539 clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
540 mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel));
541 clk[IMX5_CLK_ARM] = imx_clk_cpu("arm", "cpu_podf",
542 clk[IMX5_CLK_CPU_PODF],
543 clk[IMX5_CLK_CPU_PODF_SEL],
544 clk[IMX5_CLK_PLL1_SW],
545 clk[IMX5_CLK_STEP_SEL]);
546
547 imx_check_clocks(clk, ARRAY_SIZE(clk));
548
549 clk_data.clks = clk;
550 clk_data.clk_num = ARRAY_SIZE(clk);
551 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
552
553 /* set SDHC root clock to 200MHZ*/
554 clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000);
555 clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000);
556
557 /* move can bus clk to 24MHz */
558 clk_set_parent(clk[IMX5_CLK_CAN_SEL], clk[IMX5_CLK_LP_APM]);
559
560 /* make sure step clock is running from 24MHz */
561 clk_set_parent(clk[IMX5_CLK_STEP_SEL], clk[IMX5_CLK_LP_APM]);
562
563 clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]);
564 imx_print_silicon_rev("i.MX53", mx53_revision());
565 clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]);
566
567 r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
568 clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
569}
570CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init);
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
new file mode 100644
index 000000000000..d046f8e43de8
--- /dev/null
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -0,0 +1,538 @@
1/*
2 * Copyright 2011-2013 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/init.h>
14#include <linux/types.h>
15#include <linux/clk.h>
16#include <linux/clkdev.h>
17#include <linux/err.h>
18#include <linux/io.h>
19#include <linux/of.h>
20#include <linux/of_address.h>
21#include <linux/of_irq.h>
22#include <soc/imx/revision.h>
23#include <dt-bindings/clock/imx6qdl-clock.h>
24
25#include "clk.h"
26
27static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
28static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
29static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
30static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", };
31static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
32static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
33static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
34static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
35static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
36static const char *gpu_axi_sels[] = { "axi", "ahb", };
37static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
38static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
39static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m", };
40static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
41static const char *ldb_di_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
42static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
43static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
44static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
45static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
46static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
47static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", };
48static const char *pcie_axi_sels[] = { "axi", "ahb", };
49static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_div", };
50static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
51static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", };
52static const char *eim_sels[] = { "pll2_pfd2_396m", "pll3_usb_otg", "axi", "pll2_pfd0_352m", };
53static const char *eim_slow_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
54static const char *vdo_axi_sels[] = { "axi", "ahb", };
55static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", };
56static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
57 "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
58 "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio_div", };
59static const char *cko2_sels[] = {
60 "mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1",
61 "gpu2d_axi", "dummy", "ecspi_root", "gpu3d_axi",
62 "usdhc3", "dummy", "arm", "ipu1",
63 "ipu2", "vdo_axi", "osc", "gpu2d_core",
64 "gpu3d_core", "usdhc2", "ssi1", "ssi2",
65 "ssi3", "gpu3d_shader", "vpu_axi", "can_root",
66 "ldb_di0", "ldb_di1", "esai_extal", "eim_slow",
67 "uart_serial", "spdif", "asrc", "hsi_tx",
68};
69static const char *cko_sels[] = { "cko1", "cko2", };
70static const char *lvds_sels[] = {
71 "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
72 "pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
73 "pcie_ref_125m", "sata_ref_100m",
74};
75static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", };
76static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
77static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
78static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
79static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
80static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
81static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
82static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
83
84static struct clk *clk[IMX6QDL_CLK_END];
85static struct clk_onecell_data clk_data;
86
87static unsigned int const clks_init_on[] __initconst = {
88 IMX6QDL_CLK_MMDC_CH0_AXI,
89 IMX6QDL_CLK_ROM,
90 IMX6QDL_CLK_ARM,
91};
92
93static struct clk_div_table clk_enet_ref_table[] = {
94 { .val = 0, .div = 20, },
95 { .val = 1, .div = 10, },
96 { .val = 2, .div = 5, },
97 { .val = 3, .div = 4, },
98 { /* sentinel */ }
99};
100
101static struct clk_div_table post_div_table[] = {
102 { .val = 2, .div = 1, },
103 { .val = 1, .div = 2, },
104 { .val = 0, .div = 4, },
105 { /* sentinel */ }
106};
107
108static struct clk_div_table video_div_table[] = {
109 { .val = 0, .div = 1, },
110 { .val = 1, .div = 2, },
111 { .val = 2, .div = 1, },
112 { .val = 3, .div = 4, },
113 { /* sentinel */ }
114};
115
116static unsigned int share_count_esai;
117static unsigned int share_count_asrc;
118static unsigned int share_count_ssi1;
119static unsigned int share_count_ssi2;
120static unsigned int share_count_ssi3;
121static unsigned int share_count_mipi_core_cfg;
122
123static inline int clk_on_imx6q(void)
124{
125 return of_machine_is_compatible("fsl,imx6q");
126}
127
128static inline int clk_on_imx6dl(void)
129{
130 return of_machine_is_compatible("fsl,imx6dl");
131}
132
133static void __init imx6q_clocks_init(struct device_node *ccm_node)
134{
135 struct device_node *np;
136 void __iomem *base;
137 int i;
138 int ret;
139
140 clk[IMX6QDL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
141 clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
142 clk[IMX6QDL_CLK_CKIH] = imx_obtain_fixed_clock("ckih1", 0);
143 clk[IMX6QDL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
144 /* Clock source from external clock via CLK1/2 PADs */
145 clk[IMX6QDL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
146 clk[IMX6QDL_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0);
147
148 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
149 base = of_iomap(np, 0);
150 WARN_ON(!base);
151
152 /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
153 if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) {
154 post_div_table[1].div = 1;
155 post_div_table[2].div = 1;
156 video_div_table[1].div = 1;
157 video_div_table[3].div = 1;
158 }
159
160 clk[IMX6QDL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
161 clk[IMX6QDL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
162 clk[IMX6QDL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
163 clk[IMX6QDL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
164 clk[IMX6QDL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
165 clk[IMX6QDL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
166 clk[IMX6QDL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
167
168 /* type name parent_name base div_mask */
169 clk[IMX6QDL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
170 clk[IMX6QDL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
171 clk[IMX6QDL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
172 clk[IMX6QDL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
173 clk[IMX6QDL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
174 clk[IMX6QDL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
175 clk[IMX6QDL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
176
177 clk[IMX6QDL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
178 clk[IMX6QDL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
179 clk[IMX6QDL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
180 clk[IMX6QDL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
181 clk[IMX6QDL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
182 clk[IMX6QDL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
183 clk[IMX6QDL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
184
185 /* Do not bypass PLLs initially */
186 clk_set_parent(clk[IMX6QDL_PLL1_BYPASS], clk[IMX6QDL_CLK_PLL1]);
187 clk_set_parent(clk[IMX6QDL_PLL2_BYPASS], clk[IMX6QDL_CLK_PLL2]);
188 clk_set_parent(clk[IMX6QDL_PLL3_BYPASS], clk[IMX6QDL_CLK_PLL3]);
189 clk_set_parent(clk[IMX6QDL_PLL4_BYPASS], clk[IMX6QDL_CLK_PLL4]);
190 clk_set_parent(clk[IMX6QDL_PLL5_BYPASS], clk[IMX6QDL_CLK_PLL5]);
191 clk_set_parent(clk[IMX6QDL_PLL6_BYPASS], clk[IMX6QDL_CLK_PLL6]);
192 clk_set_parent(clk[IMX6QDL_PLL7_BYPASS], clk[IMX6QDL_CLK_PLL7]);
193
194 clk[IMX6QDL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
195 clk[IMX6QDL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
196 clk[IMX6QDL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
197 clk[IMX6QDL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
198 clk[IMX6QDL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
199 clk[IMX6QDL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
200 clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
201
202 /*
203 * Bit 20 is the reserved and read-only bit, we do this only for:
204 * - Do nothing for usbphy clk_enable/disable
205 * - Keep refcount when do usbphy clk_enable/disable, in that case,
206 * the clk framework may need to enable/disable usbphy's parent
207 */
208 clk[IMX6QDL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20);
209 clk[IMX6QDL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
210
211 /*
212 * usbphy*_gate needs to be on after system boots up, and software
213 * never needs to control it anymore.
214 */
215 clk[IMX6QDL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
216 clk[IMX6QDL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
217
218 clk[IMX6QDL_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
219 clk[IMX6QDL_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
220
221 clk[IMX6QDL_CLK_SATA_REF_100M] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
222 clk[IMX6QDL_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
223
224 clk[IMX6QDL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0,
225 base + 0xe0, 0, 2, 0, clk_enet_ref_table,
226 &imx_ccm_lock);
227
228 clk[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
229 clk[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
230
231 /*
232 * lvds1_gate and lvds2_gate are pseudo-gates. Both can be
233 * independently configured as clock inputs or outputs. We treat
234 * the "output_enable" bit as a gate, even though it's really just
235 * enabling clock output.
236 */
237 clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate_exclusive("lvds1_gate", "lvds1_sel", base + 0x160, 10, BIT(12));
238 clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate_exclusive("lvds2_gate", "lvds2_sel", base + 0x160, 11, BIT(13));
239
240 clk[IMX6QDL_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10));
241 clk[IMX6QDL_CLK_LVDS2_IN] = imx_clk_gate_exclusive("lvds2_in", "anaclk2", base + 0x160, 13, BIT(11));
242
243 /* name parent_name reg idx */
244 clk[IMX6QDL_CLK_PLL2_PFD0_352M] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
245 clk[IMX6QDL_CLK_PLL2_PFD1_594M] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
246 clk[IMX6QDL_CLK_PLL2_PFD2_396M] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2);
247 clk[IMX6QDL_CLK_PLL3_PFD0_720M] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0);
248 clk[IMX6QDL_CLK_PLL3_PFD1_540M] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1);
249 clk[IMX6QDL_CLK_PLL3_PFD2_508M] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
250 clk[IMX6QDL_CLK_PLL3_PFD3_454M] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
251
252 /* name parent_name mult div */
253 clk[IMX6QDL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
254 clk[IMX6QDL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
255 clk[IMX6QDL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
256 clk[IMX6QDL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
257 clk[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2);
258 clk[IMX6QDL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
259 clk[IMX6QDL_CLK_VIDEO_27M] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20);
260 if (clk_on_imx6dl()) {
261 clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1);
262 clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1);
263 }
264
265 clk[IMX6QDL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
266 clk[IMX6QDL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
267 clk[IMX6QDL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
268 clk[IMX6QDL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
269
270 np = ccm_node;
271 base = of_iomap(np, 0);
272 WARN_ON(!base);
273
274 /* name reg shift width parent_names num_parents */
275 clk[IMX6QDL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
276 clk[IMX6QDL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
277 clk[IMX6QDL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
278 clk[IMX6QDL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
279 clk[IMX6QDL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
280 clk[IMX6QDL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
281 clk[IMX6QDL_CLK_AXI_SEL] = imx_clk_mux("axi_sel", base + 0x14, 6, 2, axi_sels, ARRAY_SIZE(axi_sels));
282 clk[IMX6QDL_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
283 clk[IMX6QDL_CLK_ASRC_SEL] = imx_clk_mux("asrc_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
284 clk[IMX6QDL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
285 if (clk_on_imx6q()) {
286 clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_mux("gpu2d_axi", base + 0x18, 0, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
287 clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_mux("gpu3d_axi", base + 0x18, 1, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
288 }
289 clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels));
290 clk[IMX6QDL_CLK_GPU3D_CORE_SEL] = imx_clk_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels));
291 clk[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
292 clk[IMX6QDL_CLK_IPU1_SEL] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
293 clk[IMX6QDL_CLK_IPU2_SEL] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
294 clk[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
295 clk[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
296 clk[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_mux_flags("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
297 clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
298 clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
299 clk[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_mux_flags("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
300 clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT);
301 clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT);
302 clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT);
303 clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT);
304 clk[IMX6QDL_CLK_HSI_TX_SEL] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels));
305 clk[IMX6QDL_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
306 clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
307 clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
308 clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
309 clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
310 clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
311 clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
312 clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
313 clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels));
314 clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_fixup_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels), imx_cscmr1_fixup);
315 clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_fixup_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels), imx_cscmr1_fixup);
316 clk[IMX6QDL_CLK_VDO_AXI_SEL] = imx_clk_mux("vdo_axi_sel", base + 0x18, 11, 1, vdo_axi_sels, ARRAY_SIZE(vdo_axi_sels));
317 clk[IMX6QDL_CLK_VPU_AXI_SEL] = imx_clk_mux("vpu_axi_sel", base + 0x18, 14, 2, vpu_axi_sels, ARRAY_SIZE(vpu_axi_sels));
318 clk[IMX6QDL_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels));
319 clk[IMX6QDL_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels));
320 clk[IMX6QDL_CLK_CKO] = imx_clk_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels));
321
322 /* name reg shift width busy: reg, shift parent_names num_parents */
323 clk[IMX6QDL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
324 clk[IMX6QDL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
325
326 /* name parent_name reg shift width */
327 clk[IMX6QDL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
328 clk[IMX6QDL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
329 clk[IMX6QDL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
330 clk[IMX6QDL_CLK_IPG_PER] = imx_clk_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup);
331 clk[IMX6QDL_CLK_ESAI_PRED] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3);
332 clk[IMX6QDL_CLK_ESAI_PODF] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3);
333 clk[IMX6QDL_CLK_ASRC_PRED] = imx_clk_divider("asrc_pred", "asrc_sel", base + 0x30, 12, 3);
334 clk[IMX6QDL_CLK_ASRC_PODF] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3);
335 clk[IMX6QDL_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3);
336 clk[IMX6QDL_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3);
337 clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6);
338 clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6);
339 clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3);
340 clk[IMX6QDL_CLK_GPU3D_CORE_PODF] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3);
341 clk[IMX6QDL_CLK_GPU3D_SHADER] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3);
342 clk[IMX6QDL_CLK_IPU1_PODF] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3);
343 clk[IMX6QDL_CLK_IPU2_PODF] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3);
344 clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
345 clk[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0);
346 clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
347 clk[IMX6QDL_CLK_LDB_DI1_PODF] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0);
348 clk[IMX6QDL_CLK_IPU1_DI0_PRE] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3);
349 clk[IMX6QDL_CLK_IPU1_DI1_PRE] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3);
350 clk[IMX6QDL_CLK_IPU2_DI0_PRE] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3);
351 clk[IMX6QDL_CLK_IPU2_DI1_PRE] = imx_clk_divider("ipu2_di1_pre", "ipu2_di1_pre_sel", base + 0x38, 12, 3);
352 clk[IMX6QDL_CLK_HSI_TX_PODF] = imx_clk_divider("hsi_tx_podf", "hsi_tx_sel", base + 0x30, 29, 3);
353 clk[IMX6QDL_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3);
354 clk[IMX6QDL_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6);
355 clk[IMX6QDL_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3);
356 clk[IMX6QDL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6);
357 clk[IMX6QDL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3);
358 clk[IMX6QDL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6);
359 clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6);
360 clk[IMX6QDL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
361 clk[IMX6QDL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
362 clk[IMX6QDL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
363 clk[IMX6QDL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
364 clk[IMX6QDL_CLK_ENFC_PRED] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3);
365 clk[IMX6QDL_CLK_ENFC_PODF] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6);
366 clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_fixup_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3, imx_cscmr1_fixup);
367 clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_fixup_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3, imx_cscmr1_fixup);
368 clk[IMX6QDL_CLK_VPU_AXI_PODF] = imx_clk_divider("vpu_axi_podf", "vpu_axi_sel", base + 0x24, 25, 3);
369 clk[IMX6QDL_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3);
370 clk[IMX6QDL_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3);
371
372 /* name parent_name reg shift width busy: reg, shift */
373 clk[IMX6QDL_CLK_AXI] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0);
374 clk[IMX6QDL_CLK_MMDC_CH0_AXI_PODF] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph", base + 0x14, 19, 3, base + 0x48, 4);
375 clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
376 clk[IMX6QDL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
377 clk[IMX6QDL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
378
379 /* name parent_name reg shift */
380 clk[IMX6QDL_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4);
381 clk[IMX6QDL_CLK_ASRC] = imx_clk_gate2_shared("asrc", "asrc_podf", base + 0x68, 6, &share_count_asrc);
382 clk[IMX6QDL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc);
383 clk[IMX6QDL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc);
384 clk[IMX6QDL_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14);
385 clk[IMX6QDL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16);
386 clk[IMX6QDL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
387 clk[IMX6QDL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_root", base + 0x68, 20);
388 clk[IMX6QDL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0);
389 clk[IMX6QDL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2);
390 clk[IMX6QDL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4);
391 clk[IMX6QDL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6);
392 if (clk_on_imx6dl())
393 clk[IMX6DL_CLK_I2C4] = imx_clk_gate2("i2c4", "ipg_per", base + 0x6c, 8);
394 else
395 clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8);
396 clk[IMX6QDL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
397 clk[IMX6QDL_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai);
398 clk[IMX6QDL_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai);
399 clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai);
400 clk[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20);
401 clk[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);
402 if (clk_on_imx6dl())
403 /*
404 * The multiplexer and divider of imx6q clock gpu3d_shader get
405 * redefined/reused as gpu2d_core_sel and gpu2d_core_podf on imx6dl.
406 */
407 clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu3d_shader", base + 0x6c, 24);
408 else
409 clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
410 clk[IMX6QDL_CLK_GPU3D_CORE] = imx_clk_gate2("gpu3d_core", "gpu3d_core_podf", base + 0x6c, 26);
411 clk[IMX6QDL_CLK_HDMI_IAHB] = imx_clk_gate2("hdmi_iahb", "ahb", base + 0x70, 0);
412 clk[IMX6QDL_CLK_HDMI_ISFR] = imx_clk_gate2("hdmi_isfr", "video_27m", base + 0x70, 4);
413 clk[IMX6QDL_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_per", base + 0x70, 6);
414 clk[IMX6QDL_CLK_I2C2] = imx_clk_gate2("i2c2", "ipg_per", base + 0x70, 8);
415 clk[IMX6QDL_CLK_I2C3] = imx_clk_gate2("i2c3", "ipg_per", base + 0x70, 10);
416 clk[IMX6QDL_CLK_IIM] = imx_clk_gate2("iim", "ipg", base + 0x70, 12);
417 clk[IMX6QDL_CLK_ENFC] = imx_clk_gate2("enfc", "enfc_podf", base + 0x70, 14);
418 clk[IMX6QDL_CLK_VDOA] = imx_clk_gate2("vdoa", "vdo_axi", base + 0x70, 26);
419 clk[IMX6QDL_CLK_IPU1] = imx_clk_gate2("ipu1", "ipu1_podf", base + 0x74, 0);
420 clk[IMX6QDL_CLK_IPU1_DI0] = imx_clk_gate2("ipu1_di0", "ipu1_di0_sel", base + 0x74, 2);
421 clk[IMX6QDL_CLK_IPU1_DI1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4);
422 clk[IMX6QDL_CLK_IPU2] = imx_clk_gate2("ipu2", "ipu2_podf", base + 0x74, 6);
423 clk[IMX6QDL_CLK_IPU2_DI0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8);
424 clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12);
425 clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14);
426 clk[IMX6QDL_CLK_IPU2_DI1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10);
427 clk[IMX6QDL_CLK_HSI_TX] = imx_clk_gate2_shared("hsi_tx", "hsi_tx_podf", base + 0x74, 16, &share_count_mipi_core_cfg);
428 clk[IMX6QDL_CLK_MIPI_CORE_CFG] = imx_clk_gate2_shared("mipi_core_cfg", "video_27m", base + 0x74, 16, &share_count_mipi_core_cfg);
429 clk[IMX6QDL_CLK_MIPI_IPG] = imx_clk_gate2_shared("mipi_ipg", "ipg", base + 0x74, 16, &share_count_mipi_core_cfg);
430 if (clk_on_imx6dl())
431 /*
432 * The multiplexer and divider of the imx6q clock gpu2d get
433 * redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl.
434 */
435 clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "gpu2d_core_podf", base + 0x74, 18);
436 else
437 clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "axi", base + 0x74, 18);
438 clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20);
439 clk[IMX6QDL_CLK_MMDC_CH1_AXI] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22);
440 clk[IMX6QDL_CLK_OCRAM] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28);
441 clk[IMX6QDL_CLK_OPENVG_AXI] = imx_clk_gate2("openvg_axi", "axi", base + 0x74, 30);
442 clk[IMX6QDL_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "pcie_axi_sel", base + 0x78, 0);
443 clk[IMX6QDL_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12);
444 clk[IMX6QDL_CLK_PWM1] = imx_clk_gate2("pwm1", "ipg_per", base + 0x78, 16);
445 clk[IMX6QDL_CLK_PWM2] = imx_clk_gate2("pwm2", "ipg_per", base + 0x78, 18);
446 clk[IMX6QDL_CLK_PWM3] = imx_clk_gate2("pwm3", "ipg_per", base + 0x78, 20);
447 clk[IMX6QDL_CLK_PWM4] = imx_clk_gate2("pwm4", "ipg_per", base + 0x78, 22);
448 clk[IMX6QDL_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24);
449 clk[IMX6QDL_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26);
450 clk[IMX6QDL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28);
451 clk[IMX6QDL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30);
452 clk[IMX6QDL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0);
453 clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4);
454 clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
455 clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
456 clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif_podf", base + 0x7c, 14);
457 clk[IMX6QDL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1);
458 clk[IMX6QDL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2);
459 clk[IMX6QDL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3);
460 clk[IMX6QDL_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1);
461 clk[IMX6QDL_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2);
462 clk[IMX6QDL_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3);
463 clk[IMX6QDL_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
464 clk[IMX6QDL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26);
465 clk[IMX6QDL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
466 clk[IMX6QDL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
467 clk[IMX6QDL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
468 clk[IMX6QDL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
469 clk[IMX6QDL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
470 clk[IMX6QDL_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10);
471 clk[IMX6QDL_CLK_VDO_AXI] = imx_clk_gate2("vdo_axi", "vdo_axi_sel", base + 0x80, 12);
472 clk[IMX6QDL_CLK_VPU_AXI] = imx_clk_gate2("vpu_axi", "vpu_axi_podf", base + 0x80, 14);
473 clk[IMX6QDL_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
474 clk[IMX6QDL_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24);
475
476 /*
477 * The gpt_3m clock is not available on i.MX6Q TO1.0. Let's point it
478 * to clock gpt_ipg_per to ease the gpt driver code.
479 */
480 if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0)
481 clk[IMX6QDL_CLK_GPT_3M] = clk[IMX6QDL_CLK_GPT_IPG_PER];
482
483 imx_check_clocks(clk, ARRAY_SIZE(clk));
484
485 clk_data.clks = clk;
486 clk_data.clk_num = ARRAY_SIZE(clk);
487 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
488
489 clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL);
490
491 if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
492 clk_on_imx6dl()) {
493 clk_set_parent(clk[IMX6QDL_CLK_LDB_DI0_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
494 clk_set_parent(clk[IMX6QDL_CLK_LDB_DI1_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
495 }
496
497 clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI0_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
498 clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
499 clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
500 clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI1_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
501 clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI0_SEL], clk[IMX6QDL_CLK_IPU1_DI0_PRE]);
502 clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI1_SEL], clk[IMX6QDL_CLK_IPU1_DI1_PRE]);
503 clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI0_SEL], clk[IMX6QDL_CLK_IPU2_DI0_PRE]);
504 clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI1_SEL], clk[IMX6QDL_CLK_IPU2_DI1_PRE]);
505
506 /*
507 * The gpmi needs 100MHz frequency in the EDO/Sync mode,
508 * We can not get the 100MHz from the pll2_pfd0_352m.
509 * So choose pll2_pfd2_396m as enfc_sel's parent.
510 */
511 clk_set_parent(clk[IMX6QDL_CLK_ENFC_SEL], clk[IMX6QDL_CLK_PLL2_PFD2_396M]);
512
513 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
514 clk_prepare_enable(clk[clks_init_on[i]]);
515
516 if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
517 clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY1_GATE]);
518 clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY2_GATE]);
519 }
520
521 /*
522 * Let's initially set up CLKO with OSC24M, since this configuration
523 * is widely used by imx6q board designs to clock audio codec.
524 */
525 ret = clk_set_parent(clk[IMX6QDL_CLK_CKO2_SEL], clk[IMX6QDL_CLK_OSC]);
526 if (!ret)
527 ret = clk_set_parent(clk[IMX6QDL_CLK_CKO], clk[IMX6QDL_CLK_CKO2]);
528 if (ret)
529 pr_warn("failed to set up CLKO: %d\n", ret);
530
531 /* Audio-related clocks configuration */
532 clk_set_parent(clk[IMX6QDL_CLK_SPDIF_SEL], clk[IMX6QDL_CLK_PLL3_PFD3_454M]);
533
534 /* All existing boards with PCIe use LVDS1 */
535 if (IS_ENABLED(CONFIG_PCI_IMX6))
536 clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]);
537}
538CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c
new file mode 100644
index 000000000000..a0d4cf26cfa9
--- /dev/null
+++ b/drivers/clk/imx/clk-imx6sl.c
@@ -0,0 +1,443 @@
1/*
2 * Copyright 2013-2014 Freescale Semiconductor, Inc.
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 */
9
10#include <linux/clk.h>
11#include <linux/clkdev.h>
12#include <linux/err.h>
13#include <linux/of.h>
14#include <linux/of_address.h>
15#include <linux/of_irq.h>
16#include <dt-bindings/clock/imx6sl-clock.h>
17
18#include "clk.h"
19
20#define CCSR 0xc
21#define BM_CCSR_PLL1_SW_CLK_SEL (1 << 2)
22#define CACRR 0x10
23#define CDHIPR 0x48
24#define BM_CDHIPR_ARM_PODF_BUSY (1 << 16)
25#define ARM_WAIT_DIV_396M 2
26#define ARM_WAIT_DIV_792M 4
27#define ARM_WAIT_DIV_996M 6
28
29#define PLL_ARM 0x0
30#define BM_PLL_ARM_DIV_SELECT (0x7f << 0)
31#define BM_PLL_ARM_POWERDOWN (1 << 12)
32#define BM_PLL_ARM_ENABLE (1 << 13)
33#define BM_PLL_ARM_LOCK (1 << 31)
34#define PLL_ARM_DIV_792M 66
35
36static const char *step_sels[] = { "osc", "pll2_pfd2", };
37static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
38static const char *ocram_alt_sels[] = { "pll2_pfd2", "pll3_pfd1", };
39static const char *ocram_sels[] = { "periph", "ocram_alt_sels", };
40static const char *pre_periph_sels[] = { "pll2_bus", "pll2_pfd2", "pll2_pfd0", "pll2_198m", };
41static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", };
42static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
43static const char *periph_sels[] = { "pre_periph_sel", "periph_clk2_podf", };
44static const char *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2_podf", };
45static const char *csi_sels[] = { "osc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", };
46static const char *lcdif_axi_sels[] = { "pll2_bus", "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", };
47static const char *usdhc_sels[] = { "pll2_pfd2", "pll2_pfd0", };
48static const char *ssi_sels[] = { "pll3_pfd2", "pll3_pfd3", "pll4_audio_div", "dummy", };
49static const char *perclk_sels[] = { "ipg", "osc", };
50static const char *pxp_axi_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd3", };
51static const char *epdc_axi_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd2", };
52static const char *gpu2d_ovg_sels[] = { "pll3_pfd1", "pll3_usb_otg", "pll2_bus", "pll2_pfd2", };
53static const char *gpu2d_sels[] = { "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", "pll2_bus", };
54static const char *lcdif_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll3_pfd0", "pll3_pfd1", };
55static const char *epdc_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd1", "pll3_pfd1", };
56static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", };
57static const char *ecspi_sels[] = { "pll3_60m", "osc", };
58static const char *uart_sels[] = { "pll3_80m", "osc", };
59static const char *lvds_sels[] = {
60 "pll1_sys", "pll2_bus", "pll2_pfd0", "pll2_pfd1", "pll2_pfd2", "dummy", "pll4_audio", "pll5_video",
61 "dummy", "enet_ref", "dummy", "dummy", "pll3_usb_otg", "pll7_usb_host", "pll3_pfd0", "pll3_pfd1",
62 "pll3_pfd2", "pll3_pfd3", "osc", "dummy", "dummy", "dummy", "dummy", "dummy",
63 "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
64};
65static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", };
66static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
67static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
68static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
69static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
70static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
71static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
72static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
73
74static struct clk_div_table clk_enet_ref_table[] = {
75 { .val = 0, .div = 20, },
76 { .val = 1, .div = 10, },
77 { .val = 2, .div = 5, },
78 { .val = 3, .div = 4, },
79 { }
80};
81
82static struct clk_div_table post_div_table[] = {
83 { .val = 2, .div = 1, },
84 { .val = 1, .div = 2, },
85 { .val = 0, .div = 4, },
86 { }
87};
88
89static struct clk_div_table video_div_table[] = {
90 { .val = 0, .div = 1, },
91 { .val = 1, .div = 2, },
92 { .val = 2, .div = 1, },
93 { .val = 3, .div = 4, },
94 { }
95};
96
97static unsigned int share_count_ssi1;
98static unsigned int share_count_ssi2;
99static unsigned int share_count_ssi3;
100
101static struct clk *clks[IMX6SL_CLK_END];
102static struct clk_onecell_data clk_data;
103static void __iomem *ccm_base;
104static void __iomem *anatop_base;
105
106static const u32 clks_init_on[] __initconst = {
107 IMX6SL_CLK_IPG, IMX6SL_CLK_ARM, IMX6SL_CLK_MMDC_ROOT,
108};
109
110/*
111 * ERR005311 CCM: After exit from WAIT mode, unwanted interrupt(s) taken
112 * during WAIT mode entry process could cause cache memory
113 * corruption.
114 *
115 * Software workaround:
116 * To prevent this issue from occurring, software should ensure that the
117 * ARM to IPG clock ratio is less than 12:5 (that is < 2.4x), before
118 * entering WAIT mode.
119 *
120 * This function will set the ARM clk to max value within the 12:5 limit.
121 * As IPG clock is fixed at 66MHz(so ARM freq must not exceed 158.4MHz),
122 * ARM freq are one of below setpoints: 396MHz, 792MHz and 996MHz, since
123 * the clk APIs can NOT be called in idle thread(may cause kernel schedule
124 * as there is sleep function in PLL wait function), so here we just slow
125 * down ARM to below freq according to previous freq:
126 *
127 * run mode wait mode
128 * 396MHz -> 132MHz;
129 * 792MHz -> 158.4MHz;
130 * 996MHz -> 142.3MHz;
131 */
132static int imx6sl_get_arm_divider_for_wait(void)
133{
134 if (readl_relaxed(ccm_base + CCSR) & BM_CCSR_PLL1_SW_CLK_SEL) {
135 return ARM_WAIT_DIV_396M;
136 } else {
137 if ((readl_relaxed(anatop_base + PLL_ARM) &
138 BM_PLL_ARM_DIV_SELECT) == PLL_ARM_DIV_792M)
139 return ARM_WAIT_DIV_792M;
140 else
141 return ARM_WAIT_DIV_996M;
142 }
143}
144
145static void imx6sl_enable_pll_arm(bool enable)
146{
147 static u32 saved_pll_arm;
148 u32 val;
149
150 if (enable) {
151 saved_pll_arm = val = readl_relaxed(anatop_base + PLL_ARM);
152 val |= BM_PLL_ARM_ENABLE;
153 val &= ~BM_PLL_ARM_POWERDOWN;
154 writel_relaxed(val, anatop_base + PLL_ARM);
155 while (!(__raw_readl(anatop_base + PLL_ARM) & BM_PLL_ARM_LOCK))
156 ;
157 } else {
158 writel_relaxed(saved_pll_arm, anatop_base + PLL_ARM);
159 }
160}
161
162void imx6sl_set_wait_clk(bool enter)
163{
164 static unsigned long saved_arm_div;
165 int arm_div_for_wait = imx6sl_get_arm_divider_for_wait();
166
167 /*
168 * According to hardware design, arm podf change need
169 * PLL1 clock enabled.
170 */
171 if (arm_div_for_wait == ARM_WAIT_DIV_396M)
172 imx6sl_enable_pll_arm(true);
173
174 if (enter) {
175 saved_arm_div = readl_relaxed(ccm_base + CACRR);
176 writel_relaxed(arm_div_for_wait, ccm_base + CACRR);
177 } else {
178 writel_relaxed(saved_arm_div, ccm_base + CACRR);
179 }
180 while (__raw_readl(ccm_base + CDHIPR) & BM_CDHIPR_ARM_PODF_BUSY)
181 ;
182
183 if (arm_div_for_wait == ARM_WAIT_DIV_396M)
184 imx6sl_enable_pll_arm(false);
185}
186
187static void __init imx6sl_clocks_init(struct device_node *ccm_node)
188{
189 struct device_node *np;
190 void __iomem *base;
191 int i;
192 int ret;
193
194 clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
195 clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
196 clks[IMX6SL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
197 /* Clock source from external clock via CLK1 PAD */
198 clks[IMX6SL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
199
200 np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop");
201 base = of_iomap(np, 0);
202 WARN_ON(!base);
203 anatop_base = base;
204
205 clks[IMX6SL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
206 clks[IMX6SL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
207 clks[IMX6SL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
208 clks[IMX6SL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
209 clks[IMX6SL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
210 clks[IMX6SL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
211 clks[IMX6SL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
212
213 /* type name parent_name base div_mask */
214 clks[IMX6SL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
215 clks[IMX6SL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
216 clks[IMX6SL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
217 clks[IMX6SL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
218 clks[IMX6SL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
219 clks[IMX6SL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
220 clks[IMX6SL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
221
222 clks[IMX6SL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
223 clks[IMX6SL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
224 clks[IMX6SL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
225 clks[IMX6SL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
226 clks[IMX6SL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
227 clks[IMX6SL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
228 clks[IMX6SL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
229
230 /* Do not bypass PLLs initially */
231 clk_set_parent(clks[IMX6SL_PLL1_BYPASS], clks[IMX6SL_CLK_PLL1]);
232 clk_set_parent(clks[IMX6SL_PLL2_BYPASS], clks[IMX6SL_CLK_PLL2]);
233 clk_set_parent(clks[IMX6SL_PLL3_BYPASS], clks[IMX6SL_CLK_PLL3]);
234 clk_set_parent(clks[IMX6SL_PLL4_BYPASS], clks[IMX6SL_CLK_PLL4]);
235 clk_set_parent(clks[IMX6SL_PLL5_BYPASS], clks[IMX6SL_CLK_PLL5]);
236 clk_set_parent(clks[IMX6SL_PLL6_BYPASS], clks[IMX6SL_CLK_PLL6]);
237 clk_set_parent(clks[IMX6SL_PLL7_BYPASS], clks[IMX6SL_CLK_PLL7]);
238
239 clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
240 clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
241 clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
242 clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
243 clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
244 clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
245 clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
246
247 clks[IMX6SL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
248 clks[IMX6SL_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12));
249 clks[IMX6SL_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10));
250
251 /*
252 * usbphy1 and usbphy2 are implemented as dummy gates using reserve
253 * bit 20. They are used by phy driver to keep the refcount of
254 * parent PLL correct. usbphy1_gate and usbphy2_gate only needs to be
255 * turned on during boot, and software will not need to control it
256 * anymore after that.
257 */
258 clks[IMX6SL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20);
259 clks[IMX6SL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
260 clks[IMX6SL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
261 clks[IMX6SL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
262
263 /* dev name parent_name flags reg shift width div: flags, div_table lock */
264 clks[IMX6SL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
265 clks[IMX6SL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
266 clks[IMX6SL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
267 clks[IMX6SL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
268 clks[IMX6SL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, base + 0xe0, 0, 2, 0, clk_enet_ref_table, &imx_ccm_lock);
269
270 /* name parent_name reg idx */
271 clks[IMX6SL_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0", "pll2_bus", base + 0x100, 0);
272 clks[IMX6SL_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_bus", base + 0x100, 1);
273 clks[IMX6SL_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_bus", base + 0x100, 2);
274 clks[IMX6SL_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0", "pll3_usb_otg", base + 0xf0, 0);
275 clks[IMX6SL_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_usb_otg", base + 0xf0, 1);
276 clks[IMX6SL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", base + 0xf0, 2);
277 clks[IMX6SL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", base + 0xf0, 3);
278
279 /* name parent_name mult div */
280 clks[IMX6SL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2", 1, 2);
281 clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
282 clks[IMX6SL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
283 clks[IMX6SL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
284
285 np = ccm_node;
286 base = of_iomap(np, 0);
287 WARN_ON(!base);
288 ccm_base = base;
289
290 /* name reg shift width parent_names num_parents */
291 clks[IMX6SL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
292 clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
293 clks[IMX6SL_CLK_OCRAM_ALT_SEL] = imx_clk_mux("ocram_alt_sel", base + 0x14, 7, 1, ocram_alt_sels, ARRAY_SIZE(ocram_alt_sels));
294 clks[IMX6SL_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 1, ocram_sels, ARRAY_SIZE(ocram_sels));
295 clks[IMX6SL_CLK_PRE_PERIPH2_SEL] = imx_clk_mux("pre_periph2_sel", base + 0x18, 21, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
296 clks[IMX6SL_CLK_PRE_PERIPH_SEL] = imx_clk_mux("pre_periph_sel", base + 0x18, 18, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
297 clks[IMX6SL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
298 clks[IMX6SL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
299 clks[IMX6SL_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels));
300 clks[IMX6SL_CLK_LCDIF_AXI_SEL] = imx_clk_mux("lcdif_axi_sel", base + 0x3c, 14, 2, lcdif_axi_sels, ARRAY_SIZE(lcdif_axi_sels));
301 clks[IMX6SL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
302 clks[IMX6SL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
303 clks[IMX6SL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
304 clks[IMX6SL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup);
305 clks[IMX6SL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
306 clks[IMX6SL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
307 clks[IMX6SL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
308 clks[IMX6SL_CLK_PERCLK_SEL] = imx_clk_fixup_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels), imx_cscmr1_fixup);
309 clks[IMX6SL_CLK_PXP_AXI_SEL] = imx_clk_mux("pxp_axi_sel", base + 0x34, 6, 3, pxp_axi_sels, ARRAY_SIZE(pxp_axi_sels));
310 clks[IMX6SL_CLK_EPDC_AXI_SEL] = imx_clk_mux("epdc_axi_sel", base + 0x34, 15, 3, epdc_axi_sels, ARRAY_SIZE(epdc_axi_sels));
311 clks[IMX6SL_CLK_GPU2D_OVG_SEL] = imx_clk_mux("gpu2d_ovg_sel", base + 0x18, 4, 2, gpu2d_ovg_sels, ARRAY_SIZE(gpu2d_ovg_sels));
312 clks[IMX6SL_CLK_GPU2D_SEL] = imx_clk_mux("gpu2d_sel", base + 0x18, 8, 2, gpu2d_sels, ARRAY_SIZE(gpu2d_sels));
313 clks[IMX6SL_CLK_LCDIF_PIX_SEL] = imx_clk_mux("lcdif_pix_sel", base + 0x38, 6, 3, lcdif_pix_sels, ARRAY_SIZE(lcdif_pix_sels));
314 clks[IMX6SL_CLK_EPDC_PIX_SEL] = imx_clk_mux("epdc_pix_sel", base + 0x38, 15, 3, epdc_pix_sels, ARRAY_SIZE(epdc_pix_sels));
315 clks[IMX6SL_CLK_SPDIF0_SEL] = imx_clk_mux("spdif0_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
316 clks[IMX6SL_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
317 clks[IMX6SL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
318 clks[IMX6SL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
319 clks[IMX6SL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
320
321 /* name reg shift width busy: reg, shift parent_names num_parents */
322 clks[IMX6SL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
323 clks[IMX6SL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
324
325 /* name parent_name reg shift width */
326 clks[IMX6SL_CLK_OCRAM_PODF] = imx_clk_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3);
327 clks[IMX6SL_CLK_PERIPH_CLK2_PODF] = imx_clk_divider("periph_clk2_podf", "periph_clk2_sel", base + 0x14, 27, 3);
328 clks[IMX6SL_CLK_PERIPH2_CLK2_PODF] = imx_clk_divider("periph2_clk2_podf", "periph2_clk2_sel", base + 0x14, 0, 3);
329 clks[IMX6SL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
330 clks[IMX6SL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
331 clks[IMX6SL_CLK_LCDIF_AXI_PODF] = imx_clk_divider("lcdif_axi_podf", "lcdif_axi_sel", base + 0x3c, 16, 3);
332 clks[IMX6SL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
333 clks[IMX6SL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
334 clks[IMX6SL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
335 clks[IMX6SL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
336 clks[IMX6SL_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3);
337 clks[IMX6SL_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6);
338 clks[IMX6SL_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3);
339 clks[IMX6SL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6);
340 clks[IMX6SL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3);
341 clks[IMX6SL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6);
342 clks[IMX6SL_CLK_PERCLK] = imx_clk_fixup_divider("perclk", "perclk_sel", base + 0x1c, 0, 6, imx_cscmr1_fixup);
343 clks[IMX6SL_CLK_PXP_AXI_PODF] = imx_clk_divider("pxp_axi_podf", "pxp_axi_sel", base + 0x34, 3, 3);
344 clks[IMX6SL_CLK_EPDC_AXI_PODF] = imx_clk_divider("epdc_axi_podf", "epdc_axi_sel", base + 0x34, 12, 3);
345 clks[IMX6SL_CLK_GPU2D_OVG_PODF] = imx_clk_divider("gpu2d_ovg_podf", "gpu2d_ovg_sel", base + 0x18, 26, 3);
346 clks[IMX6SL_CLK_GPU2D_PODF] = imx_clk_divider("gpu2d_podf", "gpu2d_sel", base + 0x18, 29, 3);
347 clks[IMX6SL_CLK_LCDIF_PIX_PRED] = imx_clk_divider("lcdif_pix_pred", "lcdif_pix_sel", base + 0x38, 3, 3);
348 clks[IMX6SL_CLK_EPDC_PIX_PRED] = imx_clk_divider("epdc_pix_pred", "epdc_pix_sel", base + 0x38, 12, 3);
349 clks[IMX6SL_CLK_LCDIF_PIX_PODF] = imx_clk_fixup_divider("lcdif_pix_podf", "lcdif_pix_pred", base + 0x1c, 20, 3, imx_cscmr1_fixup);
350 clks[IMX6SL_CLK_EPDC_PIX_PODF] = imx_clk_divider("epdc_pix_podf", "epdc_pix_pred", base + 0x18, 23, 3);
351 clks[IMX6SL_CLK_SPDIF0_PRED] = imx_clk_divider("spdif0_pred", "spdif0_sel", base + 0x30, 25, 3);
352 clks[IMX6SL_CLK_SPDIF0_PODF] = imx_clk_divider("spdif0_podf", "spdif0_pred", base + 0x30, 22, 3);
353 clks[IMX6SL_CLK_SPDIF1_PRED] = imx_clk_divider("spdif1_pred", "spdif1_sel", base + 0x30, 12, 3);
354 clks[IMX6SL_CLK_SPDIF1_PODF] = imx_clk_divider("spdif1_podf", "spdif1_pred", base + 0x30, 9, 3);
355 clks[IMX6SL_CLK_EXTERN_AUDIO_PRED] = imx_clk_divider("extern_audio_pred", "extern_audio_sel", base + 0x28, 9, 3);
356 clks[IMX6SL_CLK_EXTERN_AUDIO_PODF] = imx_clk_divider("extern_audio_podf", "extern_audio_pred", base + 0x28, 25, 3);
357 clks[IMX6SL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6);
358 clks[IMX6SL_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_sel", base + 0x24, 0, 6);
359
360 /* name parent_name reg shift width busy: reg, shift */
361 clks[IMX6SL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
362 clks[IMX6SL_CLK_MMDC_ROOT] = imx_clk_busy_divider("mmdc", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
363 clks[IMX6SL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
364
365 /* name parent_name reg shift */
366 clks[IMX6SL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0);
367 clks[IMX6SL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2);
368 clks[IMX6SL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4);
369 clks[IMX6SL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6);
370 clks[IMX6SL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
371 clks[IMX6SL_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12);
372 clks[IMX6SL_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14);
373 clks[IMX6SL_CLK_EXTERN_AUDIO] = imx_clk_gate2("extern_audio", "extern_audio_podf", base + 0x6c, 16);
374 clks[IMX6SL_CLK_GPT] = imx_clk_gate2("gpt", "perclk", base + 0x6c, 20);
375 clks[IMX6SL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22);
376 clks[IMX6SL_CLK_GPU2D_OVG] = imx_clk_gate2("gpu2d_ovg", "gpu2d_ovg_podf", base + 0x6c, 26);
377 clks[IMX6SL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6);
378 clks[IMX6SL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8);
379 clks[IMX6SL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
380 clks[IMX6SL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
381 clks[IMX6SL_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x74, 0);
382 clks[IMX6SL_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "pxp_axi_podf", base + 0x74, 2);
383 clks[IMX6SL_CLK_EPDC_AXI] = imx_clk_gate2("epdc_axi", "epdc_axi_podf", base + 0x74, 4);
384 clks[IMX6SL_CLK_LCDIF_AXI] = imx_clk_gate2("lcdif_axi", "lcdif_axi_podf", base + 0x74, 6);
385 clks[IMX6SL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_pix_podf", base + 0x74, 8);
386 clks[IMX6SL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_pix_podf", base + 0x74, 10);
387 clks[IMX6SL_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28);
388 clks[IMX6SL_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16);
389 clks[IMX6SL_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18);
390 clks[IMX6SL_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20);
391 clks[IMX6SL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22);
392 clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6);
393 clks[IMX6SL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
394 clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif0_podf", base + 0x7c, 14);
395 clks[IMX6SL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1);
396 clks[IMX6SL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2);
397 clks[IMX6SL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3);
398 clks[IMX6SL_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1);
399 clks[IMX6SL_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2);
400 clks[IMX6SL_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3);
401 clks[IMX6SL_CLK_UART] = imx_clk_gate2("uart", "ipg", base + 0x7c, 24);
402 clks[IMX6SL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_root", base + 0x7c, 26);
403 clks[IMX6SL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
404 clks[IMX6SL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
405 clks[IMX6SL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
406 clks[IMX6SL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
407 clks[IMX6SL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
408
409 imx_check_clocks(clks, ARRAY_SIZE(clks));
410
411 clk_data.clks = clks;
412 clk_data.clk_num = ARRAY_SIZE(clks);
413 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
414
415 /* Ensure the AHB clk is at 132MHz. */
416 ret = clk_set_rate(clks[IMX6SL_CLK_AHB], 132000000);
417 if (ret)
418 pr_warn("%s: failed to set AHB clock rate %d!\n",
419 __func__, ret);
420
421 /*
422 * Make sure those always on clocks are enabled to maintain the correct
423 * usecount and enabling/disabling of parent PLLs.
424 */
425 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
426 clk_prepare_enable(clks[clks_init_on[i]]);
427
428 if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
429 clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]);
430 clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]);
431 }
432
433 /* Audio-related clocks configuration */
434 clk_set_parent(clks[IMX6SL_CLK_SPDIF0_SEL], clks[IMX6SL_CLK_PLL3_PFD3]);
435
436 /* set PLL5 video as lcdif pix parent clock */
437 clk_set_parent(clks[IMX6SL_CLK_LCDIF_PIX_SEL],
438 clks[IMX6SL_CLK_PLL5_VIDEO_DIV]);
439
440 clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL],
441 clks[IMX6SL_CLK_PLL2_PFD2]);
442}
443CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init);
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
new file mode 100644
index 000000000000..5b95c2c2bf52
--- /dev/null
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -0,0 +1,561 @@
1/*
2 * Copyright (C) 2014 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <dt-bindings/clock/imx6sx-clock.h>
13#include <linux/clk.h>
14#include <linux/clkdev.h>
15#include <linux/err.h>
16#include <linux/init.h>
17#include <linux/io.h>
18#include <linux/of.h>
19#include <linux/of_address.h>
20#include <linux/of_irq.h>
21#include <linux/types.h>
22
23#include "clk.h"
24
25#define CCDR 0x4
26#define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16)
27
28static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
29static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
30static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
31static const char *periph2_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll4_audio_div", };
32static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", };
33static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "osc", };
34static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
35static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
36static const char *ocram_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
37static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll5_video_div", "pll3_usb_otg", };
38static const char *gpu_axi_sels[] = { "pll2_pfd2_396m", "pll3_pfd0_720m", "pll3_pfd1_540m", "pll2_bus", };
39static const char *gpu_core_sels[] = { "pll3_pfd1_540m", "pll3_pfd0_720m", "pll2_bus", "pll2_pfd2_396m", };
40static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", };
41static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", };
42static const char *ldb_di0_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_pfd3_594m", "pll2_pfd1_594m", "pll3_pfd3_454m", };
43static const char *ldb_di1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
44static const char *pcie_axi_sels[] = { "axi", "ahb", };
45static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll5_video_div", "pll4_audio_div", };
46static const char *qspi1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
47static const char *perclk_sels[] = { "ipg", "osc", };
48static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
49static const char *vid_sels[] = { "pll3_pfd1_540m", "pll3_usb_otg", "pll3_pfd3_454m", "pll4_audio_div", "pll5_video_div", };
50static const char *can_sels[] = { "pll3_60m", "osc", "pll3_80m", "dummy", };
51static const char *uart_sels[] = { "pll3_80m", "osc", };
52static const char *qspi2_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", "pll3_pfd3_454m", "dummy", "dummy", "dummy", };
53static const char *enet_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", };
54static const char *enet_sels[] = { "enet_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
55static const char *m4_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "osc", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd3_454m", };
56static const char *m4_sels[] = { "m4_pre_sel", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
57static const char *eim_slow_sels[] = { "ocram", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
58static const char *ecspi_sels[] = { "pll3_60m", "osc", };
59static const char *lcdif1_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_540m", };
60static const char *lcdif1_sels[] = { "lcdif1_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
61static const char *lcdif2_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd3_594m", "pll3_pfd1_540m", };
62static const char *lcdif2_sels[] = { "lcdif2_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
63static const char *display_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll3_usb_otg", "pll3_pfd1_540m", };
64static const char *csi_sels[] = { "osc", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
65static const char *cko1_sels[] = {
66 "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
67 "dummy", "ocram", "dummy", "pxp_axi", "epdc_axi", "lcdif_pix",
68 "epdc_pix", "ahb", "ipg", "perclk", "ckil", "pll4_audio_div",
69};
70static const char *cko2_sels[] = {
71 "dummy", "mmdc_p0_fast", "usdhc4", "usdhc1", "dummy", "wrck",
72 "ecspi_root", "dummy", "usdhc3", "pcie", "arm", "csi_core",
73 "lcdif_axi", "dummy", "osc", "dummy", "gpu2d_ovg_core",
74 "usdhc2", "ssi1", "ssi2", "ssi3", "gpu2d_core", "dummy",
75 "dummy", "dummy", "dummy", "esai_extal", "eim_slow", "uart_serial",
76 "spdif", "asrc", "dummy",
77};
78static const char *cko_sels[] = { "cko1", "cko2", };
79static const char *lvds_sels[] = {
80 "arm", "pll1_sys", "dummy", "dummy", "dummy", "dummy", "dummy", "pll5_video_div",
81 "dummy", "dummy", "pcie_ref_125m", "dummy", "usbphy1", "usbphy2",
82};
83static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", };
84static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
85static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
86static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
87static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
88static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
89static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
90static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
91
92static struct clk *clks[IMX6SX_CLK_CLK_END];
93static struct clk_onecell_data clk_data;
94
95static int const clks_init_on[] __initconst = {
96 IMX6SX_CLK_AIPS_TZ1, IMX6SX_CLK_AIPS_TZ2, IMX6SX_CLK_AIPS_TZ3,
97 IMX6SX_CLK_IPMUX1, IMX6SX_CLK_IPMUX2, IMX6SX_CLK_IPMUX3,
98 IMX6SX_CLK_WAKEUP, IMX6SX_CLK_MMDC_P0_FAST, IMX6SX_CLK_MMDC_P0_IPG,
99 IMX6SX_CLK_ROM, IMX6SX_CLK_ARM, IMX6SX_CLK_IPG, IMX6SX_CLK_OCRAM,
100 IMX6SX_CLK_PER2_MAIN, IMX6SX_CLK_PERCLK, IMX6SX_CLK_M4,
101 IMX6SX_CLK_QSPI1, IMX6SX_CLK_QSPI2, IMX6SX_CLK_UART_IPG,
102 IMX6SX_CLK_UART_SERIAL, IMX6SX_CLK_I2C3, IMX6SX_CLK_ECSPI5,
103 IMX6SX_CLK_CAN1_IPG, IMX6SX_CLK_CAN1_SERIAL, IMX6SX_CLK_CAN2_IPG,
104 IMX6SX_CLK_CAN2_SERIAL, IMX6SX_CLK_CANFD, IMX6SX_CLK_EPIT1,
105 IMX6SX_CLK_EPIT2,
106};
107
108static struct clk_div_table clk_enet_ref_table[] = {
109 { .val = 0, .div = 20, },
110 { .val = 1, .div = 10, },
111 { .val = 2, .div = 5, },
112 { .val = 3, .div = 4, },
113 { }
114};
115
116static struct clk_div_table post_div_table[] = {
117 { .val = 2, .div = 1, },
118 { .val = 1, .div = 2, },
119 { .val = 0, .div = 4, },
120 { }
121};
122
123static struct clk_div_table video_div_table[] = {
124 { .val = 0, .div = 1, },
125 { .val = 1, .div = 2, },
126 { .val = 2, .div = 1, },
127 { .val = 3, .div = 4, },
128 { }
129};
130
131static u32 share_count_asrc;
132static u32 share_count_audio;
133static u32 share_count_esai;
134static u32 share_count_ssi1;
135static u32 share_count_ssi2;
136static u32 share_count_ssi3;
137
138static void __init imx6sx_clocks_init(struct device_node *ccm_node)
139{
140 struct device_node *np;
141 void __iomem *base;
142 int i;
143
144 clks[IMX6SX_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
145
146 clks[IMX6SX_CLK_CKIL] = of_clk_get_by_name(ccm_node, "ckil");
147 clks[IMX6SX_CLK_OSC] = of_clk_get_by_name(ccm_node, "osc");
148
149 /* ipp_di clock is external input */
150 clks[IMX6SX_CLK_IPP_DI0] = of_clk_get_by_name(ccm_node, "ipp_di0");
151 clks[IMX6SX_CLK_IPP_DI1] = of_clk_get_by_name(ccm_node, "ipp_di1");
152
153 /* Clock source from external clock via CLK1 PAD */
154 clks[IMX6SX_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
155
156 np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop");
157 base = of_iomap(np, 0);
158 WARN_ON(!base);
159
160 clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
161 clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
162 clks[IMX6SX_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
163 clks[IMX6SX_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
164 clks[IMX6SX_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
165 clks[IMX6SX_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
166 clks[IMX6SX_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
167
168 /* type name parent_name base div_mask */
169 clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
170 clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
171 clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
172 clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
173 clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
174 clks[IMX6SX_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
175 clks[IMX6SX_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
176
177 clks[IMX6SX_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
178 clks[IMX6SX_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
179 clks[IMX6SX_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
180 clks[IMX6SX_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
181 clks[IMX6SX_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
182 clks[IMX6SX_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
183 clks[IMX6SX_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
184
185 /* Do not bypass PLLs initially */
186 clk_set_parent(clks[IMX6SX_PLL1_BYPASS], clks[IMX6SX_CLK_PLL1]);
187 clk_set_parent(clks[IMX6SX_PLL2_BYPASS], clks[IMX6SX_CLK_PLL2]);
188 clk_set_parent(clks[IMX6SX_PLL3_BYPASS], clks[IMX6SX_CLK_PLL3]);
189 clk_set_parent(clks[IMX6SX_PLL4_BYPASS], clks[IMX6SX_CLK_PLL4]);
190 clk_set_parent(clks[IMX6SX_PLL5_BYPASS], clks[IMX6SX_CLK_PLL5]);
191 clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]);
192 clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]);
193
194 clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
195 clks[IMX6SX_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
196 clks[IMX6SX_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
197 clks[IMX6SX_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
198 clks[IMX6SX_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
199 clks[IMX6SX_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
200 clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
201
202 /*
203 * Bit 20 is the reserved and read-only bit, we do this only for:
204 * - Do nothing for usbphy clk_enable/disable
205 * - Keep refcount when do usbphy clk_enable/disable, in that case,
206 * the clk framework may need to enable/disable usbphy's parent
207 */
208 clks[IMX6SX_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20);
209 clks[IMX6SX_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
210
211 /*
212 * usbphy*_gate needs to be on after system boots up, and software
213 * never needs to control it anymore.
214 */
215 clks[IMX6SX_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
216 clks[IMX6SX_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
217
218 /* FIXME 100MHz is used for pcie ref for all imx6 pcie, excepted imx6q */
219 clks[IMX6SX_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 5);
220 clks[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
221
222 clks[IMX6SX_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12));
223 clks[IMX6SX_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10));
224
225 clks[IMX6SX_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0,
226 base + 0xe0, 0, 2, 0, clk_enet_ref_table,
227 &imx_ccm_lock);
228 clks[IMX6SX_CLK_ENET2_REF] = clk_register_divider_table(NULL, "enet2_ref", "pll6_enet", 0,
229 base + 0xe0, 2, 2, 0, clk_enet_ref_table,
230 &imx_ccm_lock);
231 clks[IMX6SX_CLK_ENET2_REF_125M] = imx_clk_gate("enet2_ref_125m", "enet2_ref", base + 0xe0, 20);
232
233 clks[IMX6SX_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
234 clks[IMX6SX_CLK_ENET_PTP] = imx_clk_gate("enet_ptp_25m", "enet_ptp_ref", base + 0xe0, 21);
235
236 /* name parent_name reg idx */
237 clks[IMX6SX_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
238 clks[IMX6SX_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
239 clks[IMX6SX_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2);
240 clks[IMX6SX_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3);
241 clks[IMX6SX_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0);
242 clks[IMX6SX_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1);
243 clks[IMX6SX_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
244 clks[IMX6SX_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
245
246 /* name parent_name mult div */
247 clks[IMX6SX_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
248 clks[IMX6SX_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
249 clks[IMX6SX_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
250 clks[IMX6SX_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
251 clks[IMX6SX_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2);
252 clks[IMX6SX_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
253
254 clks[IMX6SX_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio",
255 CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
256 clks[IMX6SX_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div",
257 CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
258 clks[IMX6SX_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video",
259 CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
260 clks[IMX6SX_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div",
261 CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
262
263 /* name reg shift width parent_names num_parents */
264 clks[IMX6SX_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
265
266 np = ccm_node;
267 base = of_iomap(np, 0);
268 WARN_ON(!base);
269
270 /* name reg shift width parent_names num_parents */
271 clks[IMX6SX_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
272 clks[IMX6SX_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
273 clks[IMX6SX_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 2, ocram_sels, ARRAY_SIZE(ocram_sels));
274 clks[IMX6SX_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
275 clks[IMX6SX_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
276 clks[IMX6SX_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
277 clks[IMX6SX_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
278 clks[IMX6SX_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
279 clks[IMX6SX_CLK_GPU_AXI_SEL] = imx_clk_mux("gpu_axi_sel", base + 0x18, 8, 2, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
280 clks[IMX6SX_CLK_GPU_CORE_SEL] = imx_clk_mux("gpu_core_sel", base + 0x18, 4, 2, gpu_core_sels, ARRAY_SIZE(gpu_core_sels));
281 clks[IMX6SX_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels));
282 clks[IMX6SX_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
283 clks[IMX6SX_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
284 clks[IMX6SX_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
285 clks[IMX6SX_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
286 clks[IMX6SX_CLK_SSI3_SEL] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
287 clks[IMX6SX_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
288 clks[IMX6SX_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
289 clks[IMX6SX_CLK_QSPI1_SEL] = imx_clk_mux_flags("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels), CLK_SET_RATE_PARENT);
290 clks[IMX6SX_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
291 clks[IMX6SX_CLK_VID_SEL] = imx_clk_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels));
292 clks[IMX6SX_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
293 clks[IMX6SX_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels));
294 clks[IMX6SX_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
295 clks[IMX6SX_CLK_QSPI2_SEL] = imx_clk_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT);
296 clks[IMX6SX_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
297 clks[IMX6SX_CLK_AUDIO_SEL] = imx_clk_mux("audio_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
298 clks[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels));
299 clks[IMX6SX_CLK_ENET_SEL] = imx_clk_mux("enet_sel", base + 0x34, 9, 3, enet_sels, ARRAY_SIZE(enet_sels));
300 clks[IMX6SX_CLK_M4_PRE_SEL] = imx_clk_mux("m4_pre_sel", base + 0x34, 6, 3, m4_pre_sels, ARRAY_SIZE(m4_pre_sels));
301 clks[IMX6SX_CLK_M4_SEL] = imx_clk_mux("m4_sel", base + 0x34, 0, 3, m4_sels, ARRAY_SIZE(m4_sels));
302 clks[IMX6SX_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
303 clks[IMX6SX_CLK_LCDIF2_PRE_SEL] = imx_clk_mux("lcdif2_pre_sel", base + 0x38, 6, 3, lcdif2_pre_sels, ARRAY_SIZE(lcdif2_pre_sels));
304 clks[IMX6SX_CLK_LCDIF2_SEL] = imx_clk_mux("lcdif2_sel", base + 0x38, 0, 3, lcdif2_sels, ARRAY_SIZE(lcdif2_sels));
305 clks[IMX6SX_CLK_DISPLAY_SEL] = imx_clk_mux("display_sel", base + 0x3c, 14, 2, display_sels, ARRAY_SIZE(display_sels));
306 clks[IMX6SX_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels));
307 clks[IMX6SX_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels));
308 clks[IMX6SX_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels));
309 clks[IMX6SX_CLK_CKO] = imx_clk_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels));
310
311 clks[IMX6SX_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux_flags("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels), CLK_SET_RATE_PARENT);
312 clks[IMX6SX_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux_flags("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels), CLK_SET_RATE_PARENT);
313 clks[IMX6SX_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels), CLK_SET_RATE_PARENT);
314 clks[IMX6SX_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels), CLK_SET_RATE_PARENT);
315 clks[IMX6SX_CLK_LCDIF1_PRE_SEL] = imx_clk_mux_flags("lcdif1_pre_sel", base + 0x38, 15, 3, lcdif1_pre_sels, ARRAY_SIZE(lcdif1_pre_sels), CLK_SET_RATE_PARENT);
316 clks[IMX6SX_CLK_LCDIF1_SEL] = imx_clk_mux_flags("lcdif1_sel", base + 0x38, 9, 3, lcdif1_sels, ARRAY_SIZE(lcdif1_sels), CLK_SET_RATE_PARENT);
317
318 /* name parent_name reg shift width */
319 clks[IMX6SX_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
320 clks[IMX6SX_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
321 clks[IMX6SX_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
322 clks[IMX6SX_CLK_GPU_CORE_PODF] = imx_clk_divider("gpu_core_podf", "gpu_core_sel", base + 0x18, 29, 3);
323 clks[IMX6SX_CLK_GPU_AXI_PODF] = imx_clk_divider("gpu_axi_podf", "gpu_axi_sel", base + 0x18, 26, 3);
324 clks[IMX6SX_CLK_LCDIF1_PODF] = imx_clk_divider("lcdif1_podf", "lcdif1_pred", base + 0x18, 23, 3);
325 clks[IMX6SX_CLK_QSPI1_PODF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3);
326 clks[IMX6SX_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3);
327 clks[IMX6SX_CLK_LCDIF2_PODF] = imx_clk_divider("lcdif2_podf", "lcdif2_pred", base + 0x1c, 20, 3);
328 clks[IMX6SX_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6);
329 clks[IMX6SX_CLK_VID_PODF] = imx_clk_divider("vid_podf", "vid_sel", base + 0x20, 24, 2);
330 clks[IMX6SX_CLK_CAN_PODF] = imx_clk_divider("can_podf", "can_sel", base + 0x20, 2, 6);
331 clks[IMX6SX_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
332 clks[IMX6SX_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
333 clks[IMX6SX_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
334 clks[IMX6SX_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
335 clks[IMX6SX_CLK_UART_PODF] = imx_clk_divider("uart_podf", "uart_sel", base + 0x24, 0, 6);
336 clks[IMX6SX_CLK_ESAI_PRED] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3);
337 clks[IMX6SX_CLK_ESAI_PODF] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3);
338 clks[IMX6SX_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3);
339 clks[IMX6SX_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6);
340 clks[IMX6SX_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3);
341 clks[IMX6SX_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6);
342 clks[IMX6SX_CLK_QSPI2_PRED] = imx_clk_divider("qspi2_pred", "qspi2_sel", base + 0x2c, 18, 3);
343 clks[IMX6SX_CLK_QSPI2_PODF] = imx_clk_divider("qspi2_podf", "qspi2_pred", base + 0x2c, 21, 6);
344 clks[IMX6SX_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3);
345 clks[IMX6SX_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6);
346 clks[IMX6SX_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3);
347 clks[IMX6SX_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3);
348 clks[IMX6SX_CLK_AUDIO_PRED] = imx_clk_divider("audio_pred", "audio_sel", base + 0x30, 12, 3);
349 clks[IMX6SX_CLK_AUDIO_PODF] = imx_clk_divider("audio_podf", "audio_pred", base + 0x30, 9, 3);
350 clks[IMX6SX_CLK_ENET_PODF] = imx_clk_divider("enet_podf", "enet_pre_sel", base + 0x34, 12, 3);
351 clks[IMX6SX_CLK_M4_PODF] = imx_clk_divider("m4_podf", "m4_sel", base + 0x34, 3, 3);
352 clks[IMX6SX_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6);
353 clks[IMX6SX_CLK_LCDIF1_PRED] = imx_clk_divider("lcdif1_pred", "lcdif1_pre_sel", base + 0x38, 12, 3);
354 clks[IMX6SX_CLK_LCDIF2_PRED] = imx_clk_divider("lcdif2_pred", "lcdif2_pre_sel", base + 0x38, 3, 3);
355 clks[IMX6SX_CLK_DISPLAY_PODF] = imx_clk_divider("display_podf", "display_sel", base + 0x3c, 16, 3);
356 clks[IMX6SX_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
357 clks[IMX6SX_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3);
358 clks[IMX6SX_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3);
359
360 clks[IMX6SX_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
361 clks[IMX6SX_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7);
362 clks[IMX6SX_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
363 clks[IMX6SX_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7);
364
365 /* name reg shift width busy: reg, shift parent_names num_parents */
366 clks[IMX6SX_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
367 clks[IMX6SX_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
368 /* name parent_name reg shift width busy: reg, shift */
369 clks[IMX6SX_CLK_OCRAM_PODF] = imx_clk_busy_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3, base + 0x48, 0);
370 clks[IMX6SX_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
371 clks[IMX6SX_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
372 clks[IMX6SX_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
373
374 /* name parent_name reg shift */
375 /* CCGR0 */
376 clks[IMX6SX_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0);
377 clks[IMX6SX_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2);
378 clks[IMX6SX_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4);
379 clks[IMX6SX_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc);
380 clks[IMX6SX_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc);
381 clks[IMX6SX_CLK_CAAM_MEM] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8);
382 clks[IMX6SX_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10);
383 clks[IMX6SX_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12);
384 clks[IMX6SX_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14);
385 clks[IMX6SX_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16);
386 clks[IMX6SX_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
387 clks[IMX6SX_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20);
388 clks[IMX6SX_CLK_DCIC1] = imx_clk_gate2("dcic1", "display_podf", base + 0x68, 24);
389 clks[IMX6SX_CLK_DCIC2] = imx_clk_gate2("dcic2", "display_podf", base + 0x68, 26);
390 clks[IMX6SX_CLK_AIPS_TZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x68, 30);
391
392 /* CCGR1 */
393 clks[IMX6SX_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0);
394 clks[IMX6SX_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2);
395 clks[IMX6SX_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4);
396 clks[IMX6SX_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6);
397 clks[IMX6SX_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_podf", base + 0x6c, 8);
398 clks[IMX6SX_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12);
399 clks[IMX6SX_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14);
400 clks[IMX6SX_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai);
401 clks[IMX6SX_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai);
402 clks[IMX6SX_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai);
403 clks[IMX6SX_CLK_WAKEUP] = imx_clk_gate2("wakeup", "ipg", base + 0x6c, 18);
404 clks[IMX6SX_CLK_GPT_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x6c, 20);
405 clks[IMX6SX_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22);
406 clks[IMX6SX_CLK_GPU] = imx_clk_gate2("gpu", "gpu_core_podf", base + 0x6c, 26);
407 clks[IMX6SX_CLK_CANFD] = imx_clk_gate2("canfd", "can_podf", base + 0x6c, 30);
408
409 /* CCGR2 */
410 clks[IMX6SX_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x70, 2);
411 clks[IMX6SX_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6);
412 clks[IMX6SX_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8);
413 clks[IMX6SX_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
414 clks[IMX6SX_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
415 clks[IMX6SX_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif1_podf", base + 0x70, 14);
416 clks[IMX6SX_CLK_IPMUX1] = imx_clk_gate2("ipmux1", "ahb", base + 0x70, 16);
417 clks[IMX6SX_CLK_IPMUX2] = imx_clk_gate2("ipmux2", "ahb", base + 0x70, 18);
418 clks[IMX6SX_CLK_IPMUX3] = imx_clk_gate2("ipmux3", "ahb", base + 0x70, 20);
419 clks[IMX6SX_CLK_TZASC1] = imx_clk_gate2("tzasc1", "mmdc_podf", base + 0x70, 22);
420 clks[IMX6SX_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "display_podf", base + 0x70, 28);
421 clks[IMX6SX_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "display_podf", base + 0x70, 30);
422
423 /* CCGR3 */
424 clks[IMX6SX_CLK_M4] = imx_clk_gate2("m4", "m4_podf", base + 0x74, 2);
425 clks[IMX6SX_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x74, 4);
426 clks[IMX6SX_CLK_ENET_AHB] = imx_clk_gate2("enet_ahb", "enet_sel", base + 0x74, 4);
427 clks[IMX6SX_CLK_DISPLAY_AXI] = imx_clk_gate2("display_axi", "display_podf", base + 0x74, 6);
428 clks[IMX6SX_CLK_LCDIF2_PIX] = imx_clk_gate2("lcdif2_pix", "lcdif2_sel", base + 0x74, 8);
429 clks[IMX6SX_CLK_LCDIF1_PIX] = imx_clk_gate2("lcdif1_pix", "lcdif1_sel", base + 0x74, 10);
430 clks[IMX6SX_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_div_sel", base + 0x74, 12);
431 clks[IMX6SX_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14);
432 clks[IMX6SX_CLK_MLB] = imx_clk_gate2("mlb", "ahb", base + 0x74, 18);
433 clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20);
434 clks[IMX6SX_CLK_MMDC_P0_IPG] = imx_clk_gate2("mmdc_p0_ipg", "ipg", base + 0x74, 24);
435 clks[IMX6SX_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28);
436
437 /* CCGR4 */
438 clks[IMX6SX_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "display_podf", base + 0x78, 0);
439 clks[IMX6SX_CLK_QSPI2] = imx_clk_gate2("qspi2", "qspi2_podf", base + 0x78, 10);
440 clks[IMX6SX_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12);
441 clks[IMX6SX_CLK_PER2_MAIN] = imx_clk_gate2("per2_main", "ahb", base + 0x78, 14);
442 clks[IMX6SX_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16);
443 clks[IMX6SX_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18);
444 clks[IMX6SX_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20);
445 clks[IMX6SX_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22);
446 clks[IMX6SX_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24);
447 clks[IMX6SX_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26);
448 clks[IMX6SX_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "qspi2_podf", base + 0x78, 28);
449 clks[IMX6SX_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30);
450
451 /* CCGR5 */
452 clks[IMX6SX_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0);
453 clks[IMX6SX_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
454 clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
455 clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio);
456 clks[IMX6SX_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio);
457 clks[IMX6SX_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1);
458 clks[IMX6SX_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2);
459 clks[IMX6SX_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3);
460 clks[IMX6SX_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1);
461 clks[IMX6SX_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2);
462 clks[IMX6SX_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3);
463 clks[IMX6SX_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
464 clks[IMX6SX_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_podf", base + 0x7c, 26);
465 clks[IMX6SX_CLK_SAI1_IPG] = imx_clk_gate2("sai1_ipg", "ipg", base + 0x7c, 28);
466 clks[IMX6SX_CLK_SAI2_IPG] = imx_clk_gate2("sai2_ipg", "ipg", base + 0x7c, 30);
467 clks[IMX6SX_CLK_SAI1] = imx_clk_gate2("sai1", "ssi1_podf", base + 0x7c, 28);
468 clks[IMX6SX_CLK_SAI2] = imx_clk_gate2("sai2", "ssi2_podf", base + 0x7c, 30);
469
470 /* CCGR6 */
471 clks[IMX6SX_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
472 clks[IMX6SX_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
473 clks[IMX6SX_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
474 clks[IMX6SX_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
475 clks[IMX6SX_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
476 clks[IMX6SX_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10);
477 clks[IMX6SX_CLK_PWM8] = imx_clk_gate2("pwm8", "perclk", base + 0x80, 16);
478 clks[IMX6SX_CLK_VADC] = imx_clk_gate2("vadc", "vid_podf", base + 0x80, 20);
479 clks[IMX6SX_CLK_GIS] = imx_clk_gate2("gis", "display_podf", base + 0x80, 22);
480 clks[IMX6SX_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24);
481 clks[IMX6SX_CLK_PWM5] = imx_clk_gate2("pwm5", "perclk", base + 0x80, 26);
482 clks[IMX6SX_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28);
483 clks[IMX6SX_CLK_PWM7] = imx_clk_gate2("pwm7", "perclk", base + 0x80, 30);
484
485 clks[IMX6SX_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
486 clks[IMX6SX_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24);
487
488 /* mask handshake of mmdc */
489 writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
490
491 imx_check_clocks(clks, ARRAY_SIZE(clks));
492
493 clk_data.clks = clks;
494 clk_data.clk_num = ARRAY_SIZE(clks);
495 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
496
497 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
498 clk_prepare_enable(clks[clks_init_on[i]]);
499
500 if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
501 clk_prepare_enable(clks[IMX6SX_CLK_USBPHY1_GATE]);
502 clk_prepare_enable(clks[IMX6SX_CLK_USBPHY2_GATE]);
503 }
504
505 /* Set the default 132MHz for EIM module */
506 clk_set_parent(clks[IMX6SX_CLK_EIM_SLOW_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
507 clk_set_rate(clks[IMX6SX_CLK_EIM_SLOW], 132000000);
508
509 /* set parent clock for LCDIF1 pixel clock */
510 clk_set_parent(clks[IMX6SX_CLK_LCDIF1_PRE_SEL], clks[IMX6SX_CLK_PLL5_VIDEO_DIV]);
511 clk_set_parent(clks[IMX6SX_CLK_LCDIF1_SEL], clks[IMX6SX_CLK_LCDIF1_PODF]);
512
513 /* Set the parent clks of PCIe lvds1 and pcie_axi to be pcie ref, axi */
514 if (clk_set_parent(clks[IMX6SX_CLK_LVDS1_SEL], clks[IMX6SX_CLK_PCIE_REF_125M]))
515 pr_err("Failed to set pcie bus parent clk.\n");
516 if (clk_set_parent(clks[IMX6SX_CLK_PCIE_AXI_SEL], clks[IMX6SX_CLK_AXI]))
517 pr_err("Failed to set pcie parent clk.\n");
518
519 /*
520 * Init enet system AHB clock, set to 200MHz
521 * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB
522 */
523 clk_set_parent(clks[IMX6SX_CLK_ENET_PRE_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
524 clk_set_parent(clks[IMX6SX_CLK_ENET_SEL], clks[IMX6SX_CLK_ENET_PODF]);
525 clk_set_rate(clks[IMX6SX_CLK_ENET_PODF], 200000000);
526 clk_set_rate(clks[IMX6SX_CLK_ENET_REF], 125000000);
527 clk_set_rate(clks[IMX6SX_CLK_ENET2_REF], 125000000);
528
529 /* Audio clocks */
530 clk_set_rate(clks[IMX6SX_CLK_PLL4_AUDIO_DIV], 393216000);
531
532 clk_set_parent(clks[IMX6SX_CLK_SPDIF_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
533 clk_set_rate(clks[IMX6SX_CLK_SPDIF_PODF], 98304000);
534
535 clk_set_parent(clks[IMX6SX_CLK_AUDIO_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]);
536 clk_set_rate(clks[IMX6SX_CLK_AUDIO_PODF], 24000000);
537
538 clk_set_parent(clks[IMX6SX_CLK_SSI1_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
539 clk_set_parent(clks[IMX6SX_CLK_SSI2_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
540 clk_set_parent(clks[IMX6SX_CLK_SSI3_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
541 clk_set_rate(clks[IMX6SX_CLK_SSI1_PODF], 24576000);
542 clk_set_rate(clks[IMX6SX_CLK_SSI2_PODF], 24576000);
543 clk_set_rate(clks[IMX6SX_CLK_SSI3_PODF], 24576000);
544
545 clk_set_parent(clks[IMX6SX_CLK_ESAI_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]);
546 clk_set_rate(clks[IMX6SX_CLK_ESAI_PODF], 24576000);
547
548 /* Set parent clock for vadc */
549 clk_set_parent(clks[IMX6SX_CLK_VID_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]);
550
551 /* default parent of can_sel clock is invalid, manually set it here */
552 clk_set_parent(clks[IMX6SX_CLK_CAN_SEL], clks[IMX6SX_CLK_PLL3_60M]);
553
554 /* Update gpu clock from default 528M to 720M */
555 clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
556 clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
557
558 clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
559 clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
560}
561CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init);
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
new file mode 100644
index 000000000000..71f3a94b472c
--- /dev/null
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -0,0 +1,860 @@
1/*
2 * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <dt-bindings/clock/imx7d-clock.h>
13#include <linux/clk.h>
14#include <linux/clkdev.h>
15#include <linux/err.h>
16#include <linux/init.h>
17#include <linux/io.h>
18#include <linux/of.h>
19#include <linux/of_address.h>
20#include <linux/of_irq.h>
21#include <linux/types.h>
22
23#include "clk.h"
24
25static struct clk *clks[IMX7D_CLK_END];
26static const char *arm_a7_sel[] = { "osc", "pll_arm_main_clk",
27 "pll_enet_500m_clk", "pll_dram_main_clk",
28 "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_audio_main_clk",
29 "pll_usb_main_clk", };
30
31static const char *arm_m4_sel[] = { "osc", "pll_sys_main_240m_clk",
32 "pll_enet_250m_clk", "pll_sys_pfd2_270m_clk",
33 "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk",
34 "pll_usb_main_clk", };
35
36static const char *arm_m0_sel[] = { "osc", "pll_sys_main_120m_clk",
37 "pll_enet_125m_clk", "pll_sys_pfd2_135m_clk",
38 "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk",
39 "pll_usb_main_clk", };
40
41static const char *axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
42 "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd5_clk",
43 "pll_audio_main_clk", "pll_video_main_clk", "pll_sys_pfd7_clk", };
44
45static const char *disp_axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
46 "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd6_clk",
47 "pll_sys_pfd7_clk", "pll_audio_main_clk", "pll_video_main_clk", };
48
49static const char *enet_axi_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
50 "pll_dram_533m_clk", "pll_enet_250m_clk",
51 "pll_sys_main_240m_clk", "pll_audio_main_clk", "pll_video_main_clk",
52 "pll_sys_pfd4_clk", };
53
54static const char *nand_usdhc_bus_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
55 "pll_dram_533m_clk", "pll_sys_main_240m_clk",
56 "pll_sys_pfd2_135m_clk", "pll_sys_pfd6_clk", "pll_enet_250m_clk",
57 "pll_audio_main_clk", };
58
59static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
60 "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk",
61 "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_main_clk",
62 "pll_video_main_clk", };
63
64static const char *dram_phym_sel[] = { "pll_dram_main_clk",
65 "dram_phym_alt_clk", };
66
67static const char *dram_sel[] = { "pll_dram_main_clk",
68 "dram_alt_clk", };
69
70static const char *dram_phym_alt_sel[] = { "osc", "pll_dram_533m_clk",
71 "pll_sys_main_clk", "pll_enet_500m_clk",
72 "pll_usb_main_clk", "pll_sys_pfd7_clk", "pll_audio_main_clk",
73 "pll_video_main_clk", };
74
75static const char *dram_alt_sel[] = { "osc", "pll_dram_533m_clk",
76 "pll_sys_main_clk", "pll_enet_500m_clk",
77 "pll_enet_250m_clk", "pll_sys_pfd0_392m_clk",
78 "pll_audio_main_clk", "pll_sys_pfd2_270m_clk", };
79
80static const char *usb_hsic_sel[] = { "osc", "pll_sys_main_clk",
81 "pll_usb_main_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk",
82 "pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
83
84static const char *pcie_ctrl_sel[] = { "osc", "pll_enet_250m_clk",
85 "pll_sys_main_240m_clk", "pll_sys_pfd2_270m_clk",
86 "pll_dram_533m_clk", "pll_enet_500m_clk",
87 "pll_sys_pfd1_332m_clk", "pll_sys_pfd6_clk", };
88
89static const char *pcie_phy_sel[] = { "osc", "pll_enet_100m_clk",
90 "pll_enet_500m_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3",
91 "ext_clk_4", "pll_sys_pfd0_392m_clk", };
92
93static const char *epdc_pixel_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
94 "pll_dram_533m_clk", "pll_sys_main_clk", "pll_sys_pfd5_clk",
95 "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", "pll_video_main_clk", };
96
97static const char *lcdif_pixel_sel[] = { "osc", "pll_sys_pfd5_clk",
98 "pll_dram_533m_clk", "ext_clk_3", "pll_sys_pfd4_clk",
99 "pll_sys_pfd2_270m_clk", "pll_video_main_clk",
100 "pll_usb_main_clk", };
101
102static const char *mipi_dsi_sel[] = { "osc", "pll_sys_pfd5_clk",
103 "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk",
104 "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", };
105
106static const char *mipi_csi_sel[] = { "osc", "pll_sys_pfd4_clk",
107 "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk",
108 "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", };
109
110static const char *mipi_dphy_sel[] = { "osc", "pll_sys_main_120m_clk",
111 "pll_dram_533m_clk", "pll_sys_pfd5_clk", "ref_1m_clk", "ext_clk_2",
112 "pll_video_main_clk", "ext_clk_3", };
113
114static const char *sai1_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
115 "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk",
116 "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", };
117
118static const char *sai2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
119 "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk",
120 "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", };
121
122static const char *sai3_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
123 "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk",
124 "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_3", };
125
126static const char *spdif_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
127 "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk",
128 "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_3_clk", };
129
130static const char *enet1_ref_sel[] = { "osc", "pll_enet_125m_clk",
131 "pll_enet_50m_clk", "pll_enet_25m_clk",
132 "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk",
133 "ext_clk_4", };
134
135static const char *enet1_time_sel[] = { "osc", "pll_enet_100m_clk",
136 "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3",
137 "ext_clk_4", "pll_video_main_clk", };
138
139static const char *enet2_ref_sel[] = { "osc", "pll_enet_125m_clk",
140 "pll_enet_50m_clk", "pll_enet_25m_clk",
141 "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk",
142 "ext_clk_4", };
143
144static const char *enet2_time_sel[] = { "osc", "pll_enet_100m_clk",
145 "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3",
146 "ext_clk_4", "pll_video_main_clk", };
147
148static const char *enet_phy_ref_sel[] = { "osc", "pll_enet_25m_clk",
149 "pll_enet_50m_clk", "pll_enet_125m_clk",
150 "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk",
151 "pll_sys_pfd3_clk", };
152
153static const char *eim_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
154 "pll_sys_main_120m_clk", "pll_dram_533m_clk",
155 "pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_enet_125m_clk",
156 "pll_usb_main_clk", };
157
158static const char *nand_sel[] = { "osc", "pll_sys_main_clk",
159 "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd3_clk",
160 "pll_enet_500m_clk", "pll_enet_250m_clk",
161 "pll_video_main_clk", };
162
163static const char *qspi_sel[] = { "osc", "pll_sys_pfd4_clk",
164 "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd3_clk",
165 "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
166
167static const char *usdhc1_sel[] = { "osc", "pll_sys_pfd0_392m_clk",
168 "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk",
169 "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
170
171static const char *usdhc2_sel[] = { "osc", "pll_sys_pfd0_392m_clk",
172 "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk",
173 "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
174
175static const char *usdhc3_sel[] = { "osc", "pll_sys_pfd0_392m_clk",
176 "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk",
177 "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
178
179static const char *can1_sel[] = { "osc", "pll_sys_main_120m_clk",
180 "pll_dram_533m_clk", "pll_sys_main_clk",
181 "pll_enet_40m_clk", "pll_usb_main_clk", "ext_clk_1",
182 "ext_clk_4", };
183
184static const char *can2_sel[] = { "osc", "pll_sys_main_120m_clk",
185 "pll_dram_533m_clk", "pll_sys_main_clk",
186 "pll_enet_40m_clk", "pll_usb_main_clk", "ext_clk_1",
187 "ext_clk_3", };
188
189static const char *i2c1_sel[] = { "osc", "pll_sys_main_120m_clk",
190 "pll_enet_50m_clk", "pll_dram_533m_clk",
191 "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk",
192 "pll_sys_pfd2_135m_clk", };
193
194static const char *i2c2_sel[] = { "osc", "pll_sys_main_120m_clk",
195 "pll_enet_50m_clk", "pll_dram_533m_clk",
196 "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk",
197 "pll_sys_pfd2_135m_clk", };
198
199static const char *i2c3_sel[] = { "osc", "pll_sys_main_120m_clk",
200 "pll_enet_50m_clk", "pll_dram_533m_clk",
201 "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk",
202 "pll_sys_pfd2_135m_clk", };
203
204static const char *i2c4_sel[] = { "osc", "pll_sys_main_120m_clk",
205 "pll_enet_50m_clk", "pll_dram_533m_clk",
206 "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk",
207 "pll_sys_pfd2_135m_clk", };
208
209static const char *uart1_sel[] = { "osc", "pll_sys_main_240m_clk",
210 "pll_enet_40m_clk", "pll_enet_100m_clk",
211 "pll_sys_main_clk", "ext_clk_2", "ext_clk_4",
212 "pll_usb_main_clk", };
213
214static const char *uart2_sel[] = { "osc", "pll_sys_main_240m_clk",
215 "pll_enet_40m_clk", "pll_enet_100m_clk",
216 "pll_sys_main_clk", "ext_clk_2", "ext_clk_3",
217 "pll_usb_main_clk", };
218
219static const char *uart3_sel[] = { "osc", "pll_sys_main_240m_clk",
220 "pll_enet_40m_clk", "pll_enet_100m_clk",
221 "pll_sys_main_clk", "ext_clk_2", "ext_clk_4",
222 "pll_usb_main_clk", };
223
224static const char *uart4_sel[] = { "osc", "pll_sys_main_240m_clk",
225 "pll_enet_40m_clk", "pll_enet_100m_clk",
226 "pll_sys_main_clk", "ext_clk_2", "ext_clk_3",
227 "pll_usb_main_clk", };
228
229static const char *uart5_sel[] = { "osc", "pll_sys_main_240m_clk",
230 "pll_enet_40m_clk", "pll_enet_100m_clk",
231 "pll_sys_main_clk", "ext_clk_2", "ext_clk_4",
232 "pll_usb_main_clk", };
233
234static const char *uart6_sel[] = { "osc", "pll_sys_main_240m_clk",
235 "pll_enet_40m_clk", "pll_enet_100m_clk",
236 "pll_sys_main_clk", "ext_clk_2", "ext_clk_3",
237 "pll_usb_main_clk", };
238
239static const char *uart7_sel[] = { "osc", "pll_sys_main_240m_clk",
240 "pll_enet_40m_clk", "pll_enet_100m_clk",
241 "pll_sys_main_clk", "ext_clk_2", "ext_clk_4",
242 "pll_usb_main_clk", };
243
244static const char *ecspi1_sel[] = { "osc", "pll_sys_main_240m_clk",
245 "pll_enet_40m_clk", "pll_sys_main_120m_clk",
246 "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk",
247 "pll_usb_main_clk", };
248
249static const char *ecspi2_sel[] = { "osc", "pll_sys_main_240m_clk",
250 "pll_enet_40m_clk", "pll_sys_main_120m_clk",
251 "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk",
252 "pll_usb_main_clk", };
253
254static const char *ecspi3_sel[] = { "osc", "pll_sys_main_240m_clk",
255 "pll_enet_40m_clk", "pll_sys_main_120m_clk",
256 "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk",
257 "pll_usb_main_clk", };
258
259static const char *ecspi4_sel[] = { "osc", "pll_sys_main_240m_clk",
260 "pll_enet_40m_clk", "pll_sys_main_120m_clk",
261 "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk",
262 "pll_usb_main_clk", };
263
264static const char *pwm1_sel[] = { "osc", "pll_enet_100m_clk",
265 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
266 "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", };
267
268static const char *pwm2_sel[] = { "osc", "pll_enet_100m_clk",
269 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
270 "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", };
271
272static const char *pwm3_sel[] = { "osc", "pll_enet_100m_clk",
273 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
274 "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", };
275
276static const char *pwm4_sel[] = { "osc", "pll_enet_100m_clk",
277 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
278 "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", };
279
280static const char *flextimer1_sel[] = { "osc", "pll_enet_100m_clk",
281 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
282 "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", };
283
284static const char *flextimer2_sel[] = { "osc", "pll_enet_100m_clk",
285 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
286 "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", };
287
288static const char *sim1_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
289 "pll_sys_main_120m_clk", "pll_dram_533m_clk",
290 "pll_usb_main_clk", "pll_audio_main_clk", "pll_enet_125m_clk",
291 "pll_sys_pfd7_clk", };
292
293static const char *sim2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
294 "pll_sys_main_120m_clk", "pll_dram_533m_clk",
295 "pll_usb_main_clk", "pll_video_main_clk", "pll_enet_125m_clk",
296 "pll_sys_pfd7_clk", };
297
298static const char *gpt1_sel[] = { "osc", "pll_enet_100m_clk",
299 "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
300 "ref_1m_clk", "pll_audio_main_clk", "ext_clk_1", };
301
302static const char *gpt2_sel[] = { "osc", "pll_enet_100m_clk",
303 "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
304 "ref_1m_clk", "pll_audio_main_clk", "ext_clk_2", };
305
306static const char *gpt3_sel[] = { "osc", "pll_enet_100m_clk",
307 "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
308 "ref_1m_clk", "pll_audio_main_clk", "ext_clk_3", };
309
310static const char *gpt4_sel[] = { "osc", "pll_enet_100m_clk",
311 "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
312 "ref_1m_clk", "pll_audio_main_clk", "ext_clk_4", };
313
314static const char *trace_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
315 "pll_sys_main_120m_clk", "pll_dram_533m_clk",
316 "pll_enet_125m_clk", "pll_usb_main_clk", "ext_clk_2",
317 "ext_clk_3", };
318
319static const char *wdog_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
320 "pll_sys_main_120m_clk", "pll_dram_533m_clk",
321 "pll_enet_125m_clk", "pll_usb_main_clk", "ref_1m_clk",
322 "pll_sys_pfd1_166m_clk", };
323
324static const char *csi_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
325 "pll_sys_main_120m_clk", "pll_dram_533m_clk",
326 "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk",
327 "pll_usb_main_clk", };
328
329static const char *audio_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
330 "pll_sys_main_120m_clk", "pll_dram_533m_clk",
331 "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk",
332 "pll_usb_main_clk", };
333
334static const char *wrclk_sel[] = { "osc", "pll_enet_40m_clk",
335 "pll_dram_533m_clk", "pll_usb_main_clk",
336 "pll_sys_main_240m_clk", "pll_sys_pfd2_270m_clk",
337 "pll_enet_500m_clk", "pll_sys_pfd7_clk", };
338
339static const char *clko1_sel[] = { "osc", "pll_sys_main_clk",
340 "pll_sys_main_240m_clk", "pll_sys_pfd0_196m_clk", "pll_sys_pfd3_clk",
341 "pll_enet_500m_clk", "pll_dram_533m_clk", "ref_1m_clk", };
342
343static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk",
344 "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk",
345 "pll_audio_main_clk", "pll_video_main_clk", "osc_32k_clk", };
346
347static const char *lvds1_sel[] = { "pll_arm_main_clk",
348 "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_332m_clk",
349 "pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk",
350 "pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk",
351 "pll_audio_main_clk", "pll_video_main_clk", "pll_enet_500m_clk",
352 "pll_enet_250m_clk", "pll_enet_125m_clk", "pll_enet_100m_clk",
353 "pll_enet_50m_clk", "pll_enet_40m_clk", "pll_enet_25m_clk",
354 "pll_dram_main_clk", };
355
356static const char *pll_bypass_src_sel[] = { "osc", "dummy", };
357static const char *pll_arm_bypass_sel[] = { "pll_arm_main", "pll_arm_main_src", };
358static const char *pll_dram_bypass_sel[] = { "pll_dram_main", "pll_dram_main_src", };
359static const char *pll_sys_bypass_sel[] = { "pll_sys_main", "pll_sys_main_src", };
360static const char *pll_enet_bypass_sel[] = { "pll_enet_main", "pll_enet_main_src", };
361static const char *pll_audio_bypass_sel[] = { "pll_audio_main", "pll_audio_main_src", };
362static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_src", };
363
364static struct clk_onecell_data clk_data;
365
366static void __init imx7d_clocks_init(struct device_node *ccm_node)
367{
368 struct device_node *np;
369 void __iomem *base;
370 int i;
371
372 clks[IMX7D_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
373 clks[IMX7D_OSC_24M_CLK] = of_clk_get_by_name(ccm_node, "osc");
374
375 np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop");
376 base = of_iomap(np, 0);
377 WARN_ON(!base);
378
379 clks[IMX7D_PLL_ARM_MAIN_SRC] = imx_clk_mux("pll_arm_main_src", base + 0x60, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
380 clks[IMX7D_PLL_DRAM_MAIN_SRC] = imx_clk_mux("pll_dram_main_src", base + 0x70, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
381 clks[IMX7D_PLL_SYS_MAIN_SRC] = imx_clk_mux("pll_sys_main_src", base + 0xb0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
382 clks[IMX7D_PLL_ENET_MAIN_SRC] = imx_clk_mux("pll_enet_main_src", base + 0xe0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
383 clks[IMX7D_PLL_AUDIO_MAIN_SRC] = imx_clk_mux("pll_audio_main_src", base + 0xf0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
384 clks[IMX7D_PLL_VIDEO_MAIN_SRC] = imx_clk_mux("pll_video_main_src", base + 0x130, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
385
386 clks[IMX7D_PLL_ARM_MAIN] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm_main", "pll_arm_main_src", base + 0x60, 0x7f);
387 clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_dram_main", "pll_dram_main_src", base + 0x70, 0x7f);
388 clks[IMX7D_PLL_SYS_MAIN] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "pll_sys_main_src", base + 0xb0, 0x1);
389 clks[IMX7D_PLL_ENET_MAIN] = imx_clk_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "pll_enet_main_src", base + 0xe0, 0x0);
390 clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_audio_main", "pll_audio_main_src", base + 0xf0, 0x7f);
391 clks[IMX7D_PLL_VIDEO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_video_main", "pll_video_main_src", base + 0x130, 0x7f);
392
393 clks[IMX7D_PLL_ARM_MAIN_BYPASS] = imx_clk_mux_flags("pll_arm_main_bypass", base + 0x60, 16, 1, pll_arm_bypass_sel, ARRAY_SIZE(pll_arm_bypass_sel), CLK_SET_RATE_PARENT);
394 clks[IMX7D_PLL_DRAM_MAIN_BYPASS] = imx_clk_mux_flags("pll_dram_main_bypass", base + 0x70, 16, 1, pll_dram_bypass_sel, ARRAY_SIZE(pll_dram_bypass_sel), CLK_SET_RATE_PARENT);
395 clks[IMX7D_PLL_SYS_MAIN_BYPASS] = imx_clk_mux_flags("pll_sys_main_bypass", base + 0xb0, 16, 1, pll_sys_bypass_sel, ARRAY_SIZE(pll_sys_bypass_sel), CLK_SET_RATE_PARENT);
396 clks[IMX7D_PLL_ENET_MAIN_BYPASS] = imx_clk_mux_flags("pll_enet_main_bypass", base + 0xe0, 16, 1, pll_enet_bypass_sel, ARRAY_SIZE(pll_enet_bypass_sel), CLK_SET_RATE_PARENT);
397 clks[IMX7D_PLL_AUDIO_MAIN_BYPASS] = imx_clk_mux_flags("pll_audio_main_bypass", base + 0xf0, 16, 1, pll_audio_bypass_sel, ARRAY_SIZE(pll_audio_bypass_sel), CLK_SET_RATE_PARENT);
398 clks[IMX7D_PLL_VIDEO_MAIN_BYPASS] = imx_clk_mux_flags("pll_video_main_bypass", base + 0x130, 16, 1, pll_video_bypass_sel, ARRAY_SIZE(pll_video_bypass_sel), CLK_SET_RATE_PARENT);
399
400 clk_set_parent(clks[IMX7D_PLL_ARM_MAIN_BYPASS], clks[IMX7D_PLL_ARM_MAIN]);
401 clk_set_parent(clks[IMX7D_PLL_DRAM_MAIN_BYPASS], clks[IMX7D_PLL_DRAM_MAIN]);
402 clk_set_parent(clks[IMX7D_PLL_SYS_MAIN_BYPASS], clks[IMX7D_PLL_SYS_MAIN]);
403 clk_set_parent(clks[IMX7D_PLL_ENET_MAIN_BYPASS], clks[IMX7D_PLL_ENET_MAIN]);
404 clk_set_parent(clks[IMX7D_PLL_AUDIO_MAIN_BYPASS], clks[IMX7D_PLL_AUDIO_MAIN]);
405 clk_set_parent(clks[IMX7D_PLL_VIDEO_MAIN_BYPASS], clks[IMX7D_PLL_VIDEO_MAIN]);
406
407 clks[IMX7D_PLL_ARM_MAIN_CLK] = imx_clk_gate("pll_arm_main_clk", "pll_arm_main_bypass", base + 0x60, 13);
408 clks[IMX7D_PLL_DRAM_MAIN_CLK] = imx_clk_gate("pll_dram_main_clk", "pll_dram_main_bypass", base + 0x70, 13);
409 clks[IMX7D_PLL_SYS_MAIN_CLK] = imx_clk_gate("pll_sys_main_clk", "pll_sys_main_bypass", base + 0xb0, 13);
410 clks[IMX7D_PLL_AUDIO_MAIN_CLK] = imx_clk_gate("pll_audio_main_clk", "pll_audio_main_bypass", base + 0xf0, 13);
411 clks[IMX7D_PLL_VIDEO_MAIN_CLK] = imx_clk_gate("pll_video_main_clk", "pll_video_main_bypass", base + 0x130, 13);
412
413 clks[IMX7D_PLL_SYS_PFD0_392M_CLK] = imx_clk_pfd("pll_sys_pfd0_392m_clk", "pll_sys_main_clk", base + 0xc0, 0);
414 clks[IMX7D_PLL_SYS_PFD1_332M_CLK] = imx_clk_pfd("pll_sys_pfd1_332m_clk", "pll_sys_main_clk", base + 0xc0, 1);
415 clks[IMX7D_PLL_SYS_PFD2_270M_CLK] = imx_clk_pfd("pll_sys_pfd2_270m_clk", "pll_sys_main_clk", base + 0xc0, 2);
416
417 clks[IMX7D_PLL_SYS_PFD3_CLK] = imx_clk_pfd("pll_sys_pfd3_clk", "pll_sys_main_clk", base + 0xc0, 3);
418 clks[IMX7D_PLL_SYS_PFD4_CLK] = imx_clk_pfd("pll_sys_pfd4_clk", "pll_sys_main_clk", base + 0xd0, 0);
419 clks[IMX7D_PLL_SYS_PFD5_CLK] = imx_clk_pfd("pll_sys_pfd5_clk", "pll_sys_main_clk", base + 0xd0, 1);
420 clks[IMX7D_PLL_SYS_PFD6_CLK] = imx_clk_pfd("pll_sys_pfd6_clk", "pll_sys_main_clk", base + 0xd0, 2);
421 clks[IMX7D_PLL_SYS_PFD7_CLK] = imx_clk_pfd("pll_sys_pfd7_clk", "pll_sys_main_clk", base + 0xd0, 3);
422
423 clks[IMX7D_PLL_SYS_MAIN_480M] = imx_clk_fixed_factor("pll_sys_main_480m", "pll_sys_main_clk", 1, 1);
424 clks[IMX7D_PLL_SYS_MAIN_240M] = imx_clk_fixed_factor("pll_sys_main_240m", "pll_sys_main_clk", 1, 2);
425 clks[IMX7D_PLL_SYS_MAIN_120M] = imx_clk_fixed_factor("pll_sys_main_120m", "pll_sys_main_clk", 1, 4);
426 clks[IMX7D_PLL_DRAM_MAIN_533M] = imx_clk_fixed_factor("pll_dram_533m", "pll_dram_main_clk", 1, 2);
427
428 clks[IMX7D_PLL_SYS_MAIN_480M_CLK] = imx_clk_gate_dis("pll_sys_main_480m_clk", "pll_sys_main_480m", base + 0xb0, 4);
429 clks[IMX7D_PLL_SYS_MAIN_240M_CLK] = imx_clk_gate_dis("pll_sys_main_240m_clk", "pll_sys_main_240m", base + 0xb0, 5);
430 clks[IMX7D_PLL_SYS_MAIN_120M_CLK] = imx_clk_gate_dis("pll_sys_main_120m_clk", "pll_sys_main_120m", base + 0xb0, 6);
431 clks[IMX7D_PLL_DRAM_MAIN_533M_CLK] = imx_clk_gate("pll_dram_533m_clk", "pll_dram_533m", base + 0x70, 12);
432
433 clks[IMX7D_PLL_SYS_PFD0_196M] = imx_clk_fixed_factor("pll_sys_pfd0_196m", "pll_sys_pfd0_392m_clk", 1, 2);
434 clks[IMX7D_PLL_SYS_PFD1_166M] = imx_clk_fixed_factor("pll_sys_pfd1_166m", "pll_sys_pfd1_332m_clk", 1, 2);
435 clks[IMX7D_PLL_SYS_PFD2_135M] = imx_clk_fixed_factor("pll_sys_pfd2_135m", "pll_sys_pfd2_270m_clk", 1, 2);
436
437 clks[IMX7D_PLL_SYS_PFD0_196M_CLK] = imx_clk_gate_dis("pll_sys_pfd0_196m_clk", "pll_sys_pfd0_196m", base + 0xb0, 26);
438 clks[IMX7D_PLL_SYS_PFD1_166M_CLK] = imx_clk_gate_dis("pll_sys_pfd1_166m_clk", "pll_sys_pfd1_166m", base + 0xb0, 27);
439 clks[IMX7D_PLL_SYS_PFD2_135M_CLK] = imx_clk_gate_dis("pll_sys_pfd2_135m_clk", "pll_sys_pfd2_135m", base + 0xb0, 28);
440
441 clks[IMX7D_PLL_ENET_MAIN_CLK] = imx_clk_fixed_factor("pll_enet_main_clk", "pll_enet_main_bypass", 1, 1);
442 clks[IMX7D_PLL_ENET_MAIN_500M] = imx_clk_fixed_factor("pll_enet_500m", "pll_enet_main_clk", 1, 2);
443 clks[IMX7D_PLL_ENET_MAIN_250M] = imx_clk_fixed_factor("pll_enet_250m", "pll_enet_main_clk", 1, 4);
444 clks[IMX7D_PLL_ENET_MAIN_125M] = imx_clk_fixed_factor("pll_enet_125m", "pll_enet_main_clk", 1, 8);
445 clks[IMX7D_PLL_ENET_MAIN_100M] = imx_clk_fixed_factor("pll_enet_100m", "pll_enet_main_clk", 1, 10);
446 clks[IMX7D_PLL_ENET_MAIN_50M] = imx_clk_fixed_factor("pll_enet_50m", "pll_enet_main_clk", 1, 20);
447 clks[IMX7D_PLL_ENET_MAIN_40M] = imx_clk_fixed_factor("pll_enet_40m", "pll_enet_main_clk", 1, 25);
448 clks[IMX7D_PLL_ENET_MAIN_25M] = imx_clk_fixed_factor("pll_enet_25m", "pll_enet_main_clk", 1, 40);
449
450 clks[IMX7D_PLL_ENET_MAIN_500M_CLK] = imx_clk_gate("pll_enet_500m_clk", "pll_enet_500m", base + 0xe0, 12);
451 clks[IMX7D_PLL_ENET_MAIN_250M_CLK] = imx_clk_gate("pll_enet_250m_clk", "pll_enet_250m", base + 0xe0, 11);
452 clks[IMX7D_PLL_ENET_MAIN_125M_CLK] = imx_clk_gate("pll_enet_125m_clk", "pll_enet_125m", base + 0xe0, 10);
453 clks[IMX7D_PLL_ENET_MAIN_100M_CLK] = imx_clk_gate("pll_enet_100m_clk", "pll_enet_100m", base + 0xe0, 9);
454 clks[IMX7D_PLL_ENET_MAIN_50M_CLK] = imx_clk_gate("pll_enet_50m_clk", "pll_enet_50m", base + 0xe0, 8);
455 clks[IMX7D_PLL_ENET_MAIN_40M_CLK] = imx_clk_gate("pll_enet_40m_clk", "pll_enet_40m", base + 0xe0, 7);
456 clks[IMX7D_PLL_ENET_MAIN_25M_CLK] = imx_clk_gate("pll_enet_25m_clk", "pll_enet_25m", base + 0xe0, 6);
457
458 clks[IMX7D_LVDS1_OUT_SEL] = imx_clk_mux("lvds1_sel", base + 0x170, 0, 5, lvds1_sel, ARRAY_SIZE(lvds1_sel));
459 clks[IMX7D_LVDS1_OUT_CLK] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x170, 5, BIT(6));
460
461 np = ccm_node;
462 base = of_iomap(np, 0);
463 WARN_ON(!base);
464
465 clks[IMX7D_ARM_A7_ROOT_SRC] = imx_clk_mux("arm_a7_src", base + 0x8000, 24, 3, arm_a7_sel, ARRAY_SIZE(arm_a7_sel));
466 clks[IMX7D_ARM_M4_ROOT_SRC] = imx_clk_mux("arm_m4_src", base + 0x8080, 24, 3, arm_m4_sel, ARRAY_SIZE(arm_m4_sel));
467 clks[IMX7D_ARM_M0_ROOT_SRC] = imx_clk_mux("arm_m0_src", base + 0x8100, 24, 3, arm_m0_sel, ARRAY_SIZE(arm_m0_sel));
468 clks[IMX7D_MAIN_AXI_ROOT_SRC] = imx_clk_mux("axi_src", base + 0x8800, 24, 3, axi_sel, ARRAY_SIZE(axi_sel));
469 clks[IMX7D_DISP_AXI_ROOT_SRC] = imx_clk_mux("disp_axi_src", base + 0x8880, 24, 3, disp_axi_sel, ARRAY_SIZE(disp_axi_sel));
470 clks[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_mux("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel));
471 clks[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_mux("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel));
472 clks[IMX7D_AHB_CHANNEL_ROOT_SRC] = imx_clk_mux("ahb_src", base + 0x9000, 24, 3, ahb_channel_sel, ARRAY_SIZE(ahb_channel_sel));
473 clks[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_mux("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel));
474 clks[IMX7D_DRAM_ROOT_SRC] = imx_clk_mux("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel));
475 clks[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_mux("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel));
476 clks[IMX7D_DRAM_ALT_ROOT_SRC] = imx_clk_mux("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel));
477 clks[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_mux("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel));
478 clks[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_mux("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel));
479 clks[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_mux("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel));
480 clks[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_mux("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel));
481 clks[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_mux("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel));
482 clks[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_mux("mipi_dsi_src", base + 0xa380, 24, 3, mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel));
483 clks[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_mux("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel));
484 clks[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_mux("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel));
485 clks[IMX7D_SAI1_ROOT_SRC] = imx_clk_mux("sai1_src", base + 0xa500, 24, 3, sai1_sel, ARRAY_SIZE(sai1_sel));
486 clks[IMX7D_SAI2_ROOT_SRC] = imx_clk_mux("sai2_src", base + 0xa580, 24, 3, sai2_sel, ARRAY_SIZE(sai2_sel));
487 clks[IMX7D_SAI3_ROOT_SRC] = imx_clk_mux("sai3_src", base + 0xa600, 24, 3, sai3_sel, ARRAY_SIZE(sai3_sel));
488 clks[IMX7D_SPDIF_ROOT_SRC] = imx_clk_mux("spdif_src", base + 0xa680, 24, 3, spdif_sel, ARRAY_SIZE(spdif_sel));
489 clks[IMX7D_ENET1_REF_ROOT_SRC] = imx_clk_mux("enet1_ref_src", base + 0xa700, 24, 3, enet1_ref_sel, ARRAY_SIZE(enet1_ref_sel));
490 clks[IMX7D_ENET1_TIME_ROOT_SRC] = imx_clk_mux("enet1_time_src", base + 0xa780, 24, 3, enet1_time_sel, ARRAY_SIZE(enet1_time_sel));
491 clks[IMX7D_ENET2_REF_ROOT_SRC] = imx_clk_mux("enet2_ref_src", base + 0xa800, 24, 3, enet2_ref_sel, ARRAY_SIZE(enet2_ref_sel));
492 clks[IMX7D_ENET2_TIME_ROOT_SRC] = imx_clk_mux("enet2_time_src", base + 0xa880, 24, 3, enet2_time_sel, ARRAY_SIZE(enet2_time_sel));
493 clks[IMX7D_ENET_PHY_REF_ROOT_SRC] = imx_clk_mux("enet_phy_ref_src", base + 0xa900, 24, 3, enet_phy_ref_sel, ARRAY_SIZE(enet_phy_ref_sel));
494 clks[IMX7D_EIM_ROOT_SRC] = imx_clk_mux("eim_src", base + 0xa980, 24, 3, eim_sel, ARRAY_SIZE(eim_sel));
495 clks[IMX7D_NAND_ROOT_SRC] = imx_clk_mux("nand_src", base + 0xaa00, 24, 3, nand_sel, ARRAY_SIZE(nand_sel));
496 clks[IMX7D_QSPI_ROOT_SRC] = imx_clk_mux("qspi_src", base + 0xaa80, 24, 3, qspi_sel, ARRAY_SIZE(qspi_sel));
497 clks[IMX7D_USDHC1_ROOT_SRC] = imx_clk_mux("usdhc1_src", base + 0xab00, 24, 3, usdhc1_sel, ARRAY_SIZE(usdhc1_sel));
498 clks[IMX7D_USDHC2_ROOT_SRC] = imx_clk_mux("usdhc2_src", base + 0xab80, 24, 3, usdhc2_sel, ARRAY_SIZE(usdhc2_sel));
499 clks[IMX7D_USDHC3_ROOT_SRC] = imx_clk_mux("usdhc3_src", base + 0xac00, 24, 3, usdhc3_sel, ARRAY_SIZE(usdhc3_sel));
500 clks[IMX7D_CAN1_ROOT_SRC] = imx_clk_mux("can1_src", base + 0xac80, 24, 3, can1_sel, ARRAY_SIZE(can1_sel));
501 clks[IMX7D_CAN2_ROOT_SRC] = imx_clk_mux("can2_src", base + 0xad00, 24, 3, can2_sel, ARRAY_SIZE(can2_sel));
502 clks[IMX7D_I2C1_ROOT_SRC] = imx_clk_mux("i2c1_src", base + 0xad80, 24, 3, i2c1_sel, ARRAY_SIZE(i2c1_sel));
503 clks[IMX7D_I2C2_ROOT_SRC] = imx_clk_mux("i2c2_src", base + 0xae00, 24, 3, i2c2_sel, ARRAY_SIZE(i2c2_sel));
504 clks[IMX7D_I2C3_ROOT_SRC] = imx_clk_mux("i2c3_src", base + 0xae80, 24, 3, i2c3_sel, ARRAY_SIZE(i2c3_sel));
505 clks[IMX7D_I2C4_ROOT_SRC] = imx_clk_mux("i2c4_src", base + 0xaf00, 24, 3, i2c4_sel, ARRAY_SIZE(i2c4_sel));
506 clks[IMX7D_UART1_ROOT_SRC] = imx_clk_mux("uart1_src", base + 0xaf80, 24, 3, uart1_sel, ARRAY_SIZE(uart1_sel));
507 clks[IMX7D_UART2_ROOT_SRC] = imx_clk_mux("uart2_src", base + 0xb000, 24, 3, uart2_sel, ARRAY_SIZE(uart2_sel));
508 clks[IMX7D_UART3_ROOT_SRC] = imx_clk_mux("uart3_src", base + 0xb080, 24, 3, uart3_sel, ARRAY_SIZE(uart3_sel));
509 clks[IMX7D_UART4_ROOT_SRC] = imx_clk_mux("uart4_src", base + 0xb100, 24, 3, uart4_sel, ARRAY_SIZE(uart4_sel));
510 clks[IMX7D_UART5_ROOT_SRC] = imx_clk_mux("uart5_src", base + 0xb180, 24, 3, uart5_sel, ARRAY_SIZE(uart5_sel));
511 clks[IMX7D_UART6_ROOT_SRC] = imx_clk_mux("uart6_src", base + 0xb200, 24, 3, uart6_sel, ARRAY_SIZE(uart6_sel));
512 clks[IMX7D_UART7_ROOT_SRC] = imx_clk_mux("uart7_src", base + 0xb280, 24, 3, uart7_sel, ARRAY_SIZE(uart7_sel));
513 clks[IMX7D_ECSPI1_ROOT_SRC] = imx_clk_mux("ecspi1_src", base + 0xb300, 24, 3, ecspi1_sel, ARRAY_SIZE(ecspi1_sel));
514 clks[IMX7D_ECSPI2_ROOT_SRC] = imx_clk_mux("ecspi2_src", base + 0xb380, 24, 3, ecspi2_sel, ARRAY_SIZE(ecspi2_sel));
515 clks[IMX7D_ECSPI3_ROOT_SRC] = imx_clk_mux("ecspi3_src", base + 0xb400, 24, 3, ecspi3_sel, ARRAY_SIZE(ecspi3_sel));
516 clks[IMX7D_ECSPI4_ROOT_SRC] = imx_clk_mux("ecspi4_src", base + 0xb480, 24, 3, ecspi4_sel, ARRAY_SIZE(ecspi4_sel));
517 clks[IMX7D_PWM1_ROOT_SRC] = imx_clk_mux("pwm1_src", base + 0xb500, 24, 3, pwm1_sel, ARRAY_SIZE(pwm1_sel));
518 clks[IMX7D_PWM2_ROOT_SRC] = imx_clk_mux("pwm2_src", base + 0xb580, 24, 3, pwm2_sel, ARRAY_SIZE(pwm2_sel));
519 clks[IMX7D_PWM3_ROOT_SRC] = imx_clk_mux("pwm3_src", base + 0xb600, 24, 3, pwm3_sel, ARRAY_SIZE(pwm3_sel));
520 clks[IMX7D_PWM4_ROOT_SRC] = imx_clk_mux("pwm4_src", base + 0xb680, 24, 3, pwm4_sel, ARRAY_SIZE(pwm4_sel));
521 clks[IMX7D_FLEXTIMER1_ROOT_SRC] = imx_clk_mux("flextimer1_src", base + 0xb700, 24, 3, flextimer1_sel, ARRAY_SIZE(flextimer1_sel));
522 clks[IMX7D_FLEXTIMER2_ROOT_SRC] = imx_clk_mux("flextimer2_src", base + 0xb780, 24, 3, flextimer2_sel, ARRAY_SIZE(flextimer2_sel));
523 clks[IMX7D_SIM1_ROOT_SRC] = imx_clk_mux("sim1_src", base + 0xb800, 24, 3, sim1_sel, ARRAY_SIZE(sim1_sel));
524 clks[IMX7D_SIM2_ROOT_SRC] = imx_clk_mux("sim2_src", base + 0xb880, 24, 3, sim2_sel, ARRAY_SIZE(sim2_sel));
525 clks[IMX7D_GPT1_ROOT_SRC] = imx_clk_mux("gpt1_src", base + 0xb900, 24, 3, gpt1_sel, ARRAY_SIZE(gpt1_sel));
526 clks[IMX7D_GPT2_ROOT_SRC] = imx_clk_mux("gpt2_src", base + 0xb980, 24, 3, gpt2_sel, ARRAY_SIZE(gpt2_sel));
527 clks[IMX7D_GPT3_ROOT_SRC] = imx_clk_mux("gpt3_src", base + 0xba00, 24, 3, gpt3_sel, ARRAY_SIZE(gpt3_sel));
528 clks[IMX7D_GPT4_ROOT_SRC] = imx_clk_mux("gpt4_src", base + 0xba80, 24, 3, gpt4_sel, ARRAY_SIZE(gpt4_sel));
529 clks[IMX7D_TRACE_ROOT_SRC] = imx_clk_mux("trace_src", base + 0xbb00, 24, 3, trace_sel, ARRAY_SIZE(trace_sel));
530 clks[IMX7D_WDOG_ROOT_SRC] = imx_clk_mux("wdog_src", base + 0xbb80, 24, 3, wdog_sel, ARRAY_SIZE(wdog_sel));
531 clks[IMX7D_CSI_MCLK_ROOT_SRC] = imx_clk_mux("csi_mclk_src", base + 0xbc00, 24, 3, csi_mclk_sel, ARRAY_SIZE(csi_mclk_sel));
532 clks[IMX7D_AUDIO_MCLK_ROOT_SRC] = imx_clk_mux("audio_mclk_src", base + 0xbc80, 24, 3, audio_mclk_sel, ARRAY_SIZE(audio_mclk_sel));
533 clks[IMX7D_WRCLK_ROOT_SRC] = imx_clk_mux("wrclk_src", base + 0xbd00, 24, 3, wrclk_sel, ARRAY_SIZE(wrclk_sel));
534 clks[IMX7D_CLKO1_ROOT_SRC] = imx_clk_mux("clko1_src", base + 0xbd80, 24, 3, clko1_sel, ARRAY_SIZE(clko1_sel));
535 clks[IMX7D_CLKO2_ROOT_SRC] = imx_clk_mux("clko2_src", base + 0xbe00, 24, 3, clko2_sel, ARRAY_SIZE(clko2_sel));
536
537 clks[IMX7D_ARM_A7_ROOT_CG] = imx_clk_gate("arm_a7_cg", "arm_a7_src", base + 0x8000, 28);
538 clks[IMX7D_ARM_M4_ROOT_CG] = imx_clk_gate("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
539 clks[IMX7D_ARM_M0_ROOT_CG] = imx_clk_gate("arm_m0_cg", "arm_m0_src", base + 0x8100, 28);
540 clks[IMX7D_MAIN_AXI_ROOT_CG] = imx_clk_gate("axi_cg", "axi_src", base + 0x8800, 28);
541 clks[IMX7D_DISP_AXI_ROOT_CG] = imx_clk_gate("disp_axi_cg", "disp_axi_src", base + 0x8880, 28);
542 clks[IMX7D_ENET_AXI_ROOT_CG] = imx_clk_gate("enet_axi_cg", "enet_axi_src", base + 0x8900, 28);
543 clks[IMX7D_NAND_USDHC_BUS_ROOT_CG] = imx_clk_gate("nand_usdhc_cg", "nand_usdhc_src", base + 0x8980, 28);
544 clks[IMX7D_AHB_CHANNEL_ROOT_CG] = imx_clk_gate("ahb_cg", "ahb_src", base + 0x9000, 28);
545 clks[IMX7D_DRAM_PHYM_ROOT_CG] = imx_clk_gate("dram_phym_cg", "dram_phym_src", base + 0x9800, 28);
546 clks[IMX7D_DRAM_ROOT_CG] = imx_clk_gate("dram_cg", "dram_src", base + 0x9880, 28);
547 clks[IMX7D_DRAM_PHYM_ALT_ROOT_CG] = imx_clk_gate("dram_phym_alt_cg", "dram_phym_alt_src", base + 0xa000, 28);
548 clks[IMX7D_DRAM_ALT_ROOT_CG] = imx_clk_gate("dram_alt_cg", "dram_alt_src", base + 0xa080, 28);
549 clks[IMX7D_USB_HSIC_ROOT_CG] = imx_clk_gate("usb_hsic_cg", "usb_hsic_src", base + 0xa100, 28);
550 clks[IMX7D_PCIE_CTRL_ROOT_CG] = imx_clk_gate("pcie_ctrl_cg", "pcie_ctrl_src", base + 0xa180, 28);
551 clks[IMX7D_PCIE_PHY_ROOT_CG] = imx_clk_gate("pcie_phy_cg", "pcie_phy_src", base + 0xa200, 28);
552 clks[IMX7D_EPDC_PIXEL_ROOT_CG] = imx_clk_gate("epdc_pixel_cg", "epdc_pixel_src", base + 0xa280, 28);
553 clks[IMX7D_LCDIF_PIXEL_ROOT_CG] = imx_clk_gate("lcdif_pixel_cg", "lcdif_pixel_src", base + 0xa300, 28);
554 clks[IMX7D_MIPI_DSI_ROOT_CG] = imx_clk_gate("mipi_dsi_cg", "mipi_dsi_src", base + 0xa380, 28);
555 clks[IMX7D_MIPI_CSI_ROOT_CG] = imx_clk_gate("mipi_csi_cg", "mipi_csi_src", base + 0xa400, 28);
556 clks[IMX7D_MIPI_DPHY_ROOT_CG] = imx_clk_gate("mipi_dphy_cg", "mipi_dphy_src", base + 0xa480, 28);
557 clks[IMX7D_SAI1_ROOT_CG] = imx_clk_gate("sai1_cg", "sai1_src", base + 0xa500, 28);
558 clks[IMX7D_SAI2_ROOT_CG] = imx_clk_gate("sai2_cg", "sai2_src", base + 0xa580, 28);
559 clks[IMX7D_SAI3_ROOT_CG] = imx_clk_gate("sai3_cg", "sai3_src", base + 0xa600, 28);
560 clks[IMX7D_SPDIF_ROOT_CG] = imx_clk_gate("spdif_cg", "spdif_src", base + 0xa680, 28);
561 clks[IMX7D_ENET1_REF_ROOT_CG] = imx_clk_gate("enet1_ref_cg", "enet1_ref_src", base + 0xa700, 28);
562 clks[IMX7D_ENET1_TIME_ROOT_CG] = imx_clk_gate("enet1_time_cg", "enet1_time_src", base + 0xa780, 28);
563 clks[IMX7D_ENET2_REF_ROOT_CG] = imx_clk_gate("enet2_ref_cg", "enet2_ref_src", base + 0xa800, 28);
564 clks[IMX7D_ENET2_TIME_ROOT_CG] = imx_clk_gate("enet2_time_cg", "enet2_time_src", base + 0xa880, 28);
565 clks[IMX7D_ENET_PHY_REF_ROOT_CG] = imx_clk_gate("enet_phy_ref_cg", "enet_phy_ref_src", base + 0xa900, 28);
566 clks[IMX7D_EIM_ROOT_CG] = imx_clk_gate("eim_cg", "eim_src", base + 0xa980, 28);
567 clks[IMX7D_NAND_ROOT_CG] = imx_clk_gate("nand_cg", "nand_src", base + 0xaa00, 28);
568 clks[IMX7D_QSPI_ROOT_CG] = imx_clk_gate("qspi_cg", "qspi_src", base + 0xaa80, 28);
569 clks[IMX7D_USDHC1_ROOT_CG] = imx_clk_gate("usdhc1_cg", "usdhc1_src", base + 0xab00, 28);
570 clks[IMX7D_USDHC2_ROOT_CG] = imx_clk_gate("usdhc2_cg", "usdhc2_src", base + 0xab80, 28);
571 clks[IMX7D_USDHC3_ROOT_CG] = imx_clk_gate("usdhc3_cg", "usdhc3_src", base + 0xac00, 28);
572 clks[IMX7D_CAN1_ROOT_CG] = imx_clk_gate("can1_cg", "can1_src", base + 0xac80, 28);
573 clks[IMX7D_CAN2_ROOT_CG] = imx_clk_gate("can2_cg", "can2_src", base + 0xad00, 28);
574 clks[IMX7D_I2C1_ROOT_CG] = imx_clk_gate("i2c1_cg", "i2c1_src", base + 0xad80, 28);
575 clks[IMX7D_I2C2_ROOT_CG] = imx_clk_gate("i2c2_cg", "i2c2_src", base + 0xae00, 28);
576 clks[IMX7D_I2C3_ROOT_CG] = imx_clk_gate("i2c3_cg", "i2c3_src", base + 0xae80, 28);
577 clks[IMX7D_I2C4_ROOT_CG] = imx_clk_gate("i2c4_cg", "i2c4_src", base + 0xaf00, 28);
578 clks[IMX7D_UART1_ROOT_CG] = imx_clk_gate("uart1_cg", "uart1_src", base + 0xaf80, 28);
579 clks[IMX7D_UART2_ROOT_CG] = imx_clk_gate("uart2_cg", "uart2_src", base + 0xb000, 28);
580 clks[IMX7D_UART3_ROOT_CG] = imx_clk_gate("uart3_cg", "uart3_src", base + 0xb080, 28);
581 clks[IMX7D_UART4_ROOT_CG] = imx_clk_gate("uart4_cg", "uart4_src", base + 0xb100, 28);
582 clks[IMX7D_UART5_ROOT_CG] = imx_clk_gate("uart5_cg", "uart5_src", base + 0xb180, 28);
583 clks[IMX7D_UART6_ROOT_CG] = imx_clk_gate("uart6_cg", "uart6_src", base + 0xb200, 28);
584 clks[IMX7D_UART7_ROOT_CG] = imx_clk_gate("uart7_cg", "uart7_src", base + 0xb280, 28);
585 clks[IMX7D_ECSPI1_ROOT_CG] = imx_clk_gate("ecspi1_cg", "ecspi1_src", base + 0xb300, 28);
586 clks[IMX7D_ECSPI2_ROOT_CG] = imx_clk_gate("ecspi2_cg", "ecspi2_src", base + 0xb380, 28);
587 clks[IMX7D_ECSPI3_ROOT_CG] = imx_clk_gate("ecspi3_cg", "ecspi3_src", base + 0xb400, 28);
588 clks[IMX7D_ECSPI4_ROOT_CG] = imx_clk_gate("ecspi4_cg", "ecspi4_src", base + 0xb480, 28);
589 clks[IMX7D_PWM1_ROOT_CG] = imx_clk_gate("pwm1_cg", "pwm1_src", base + 0xb500, 28);
590 clks[IMX7D_PWM2_ROOT_CG] = imx_clk_gate("pwm2_cg", "pwm2_src", base + 0xb580, 28);
591 clks[IMX7D_PWM3_ROOT_CG] = imx_clk_gate("pwm3_cg", "pwm3_src", base + 0xb600, 28);
592 clks[IMX7D_PWM4_ROOT_CG] = imx_clk_gate("pwm4_cg", "pwm4_src", base + 0xb680, 28);
593 clks[IMX7D_FLEXTIMER1_ROOT_CG] = imx_clk_gate("flextimer1_cg", "flextimer1_src", base + 0xb700, 28);
594 clks[IMX7D_FLEXTIMER2_ROOT_CG] = imx_clk_gate("flextimer2_cg", "flextimer2_src", base + 0xb780, 28);
595 clks[IMX7D_SIM1_ROOT_CG] = imx_clk_gate("sim1_cg", "sim1_src", base + 0xb800, 28);
596 clks[IMX7D_SIM2_ROOT_CG] = imx_clk_gate("sim2_cg", "sim2_src", base + 0xb880, 28);
597 clks[IMX7D_GPT1_ROOT_CG] = imx_clk_gate("gpt1_cg", "gpt1_src", base + 0xb900, 28);
598 clks[IMX7D_GPT2_ROOT_CG] = imx_clk_gate("gpt2_cg", "gpt2_src", base + 0xb980, 28);
599 clks[IMX7D_GPT3_ROOT_CG] = imx_clk_gate("gpt3_cg", "gpt3_src", base + 0xbA00, 28);
600 clks[IMX7D_GPT4_ROOT_CG] = imx_clk_gate("gpt4_cg", "gpt4_src", base + 0xbA80, 28);
601 clks[IMX7D_TRACE_ROOT_CG] = imx_clk_gate("trace_cg", "trace_src", base + 0xbb00, 28);
602 clks[IMX7D_WDOG_ROOT_CG] = imx_clk_gate("wdog_cg", "wdog_src", base + 0xbb80, 28);
603 clks[IMX7D_CSI_MCLK_ROOT_CG] = imx_clk_gate("csi_mclk_cg", "csi_mclk_src", base + 0xbc00, 28);
604 clks[IMX7D_AUDIO_MCLK_ROOT_CG] = imx_clk_gate("audio_mclk_cg", "audio_mclk_src", base + 0xbc80, 28);
605 clks[IMX7D_WRCLK_ROOT_CG] = imx_clk_gate("wrclk_cg", "wrclk_src", base + 0xbd00, 28);
606 clks[IMX7D_CLKO1_ROOT_CG] = imx_clk_gate("clko1_cg", "clko1_src", base + 0xbd80, 28);
607 clks[IMX7D_CLKO2_ROOT_CG] = imx_clk_gate("clko2_cg", "clko2_src", base + 0xbe00, 28);
608
609 clks[IMX7D_MAIN_AXI_ROOT_PRE_DIV] = imx_clk_divider("axi_pre_div", "axi_cg", base + 0x8800, 16, 3);
610 clks[IMX7D_DISP_AXI_ROOT_PRE_DIV] = imx_clk_divider("disp_axi_pre_div", "disp_axi_cg", base + 0x8880, 16, 3);
611 clks[IMX7D_ENET_AXI_ROOT_PRE_DIV] = imx_clk_divider("enet_axi_pre_div", "enet_axi_cg", base + 0x8900, 16, 3);
612 clks[IMX7D_NAND_USDHC_BUS_ROOT_PRE_DIV] = imx_clk_divider("nand_usdhc_pre_div", "nand_usdhc_cg", base + 0x8980, 16, 3);
613 clks[IMX7D_AHB_CHANNEL_ROOT_PRE_DIV] = imx_clk_divider("ahb_pre_div", "ahb_cg", base + 0x9000, 16, 3);
614 clks[IMX7D_DRAM_PHYM_ALT_ROOT_PRE_DIV] = imx_clk_divider("dram_phym_alt_pre_div", "dram_phym_alt_cg", base + 0xa000, 16, 3);
615 clks[IMX7D_DRAM_ALT_ROOT_PRE_DIV] = imx_clk_divider("dram_alt_pre_div", "dram_alt_cg", base + 0xa080, 16, 3);
616 clks[IMX7D_USB_HSIC_ROOT_PRE_DIV] = imx_clk_divider("usb_hsic_pre_div", "usb_hsic_cg", base + 0xa100, 16, 3);
617 clks[IMX7D_PCIE_CTRL_ROOT_PRE_DIV] = imx_clk_divider("pcie_ctrl_pre_div", "pcie_ctrl_cg", base + 0xa180, 16, 3);
618 clks[IMX7D_PCIE_PHY_ROOT_PRE_DIV] = imx_clk_divider("pcie_phy_pre_div", "pcie_phy_cg", base + 0xa200, 16, 3);
619 clks[IMX7D_EPDC_PIXEL_ROOT_PRE_DIV] = imx_clk_divider("epdc_pixel_pre_div", "epdc_pixel_cg", base + 0xa280, 16, 3);
620 clks[IMX7D_LCDIF_PIXEL_ROOT_PRE_DIV] = imx_clk_divider("lcdif_pixel_pre_div", "lcdif_pixel_cg", base + 0xa300, 16, 3);
621 clks[IMX7D_MIPI_DSI_ROOT_PRE_DIV] = imx_clk_divider("mipi_dsi_pre_div", "mipi_dsi_cg", base + 0xa380, 16, 3);
622 clks[IMX7D_MIPI_CSI_ROOT_PRE_DIV] = imx_clk_divider("mipi_csi_pre_div", "mipi_csi_cg", base + 0xa400, 16, 3);
623 clks[IMX7D_MIPI_DPHY_ROOT_PRE_DIV] = imx_clk_divider("mipi_dphy_pre_div", "mipi_dphy_cg", base + 0xa480, 16, 3);
624 clks[IMX7D_SAI1_ROOT_PRE_DIV] = imx_clk_divider("sai1_pre_div", "sai1_cg", base + 0xa500, 16, 3);
625 clks[IMX7D_SAI2_ROOT_PRE_DIV] = imx_clk_divider("sai2_pre_div", "sai2_cg", base + 0xa580, 16, 3);
626 clks[IMX7D_SAI3_ROOT_PRE_DIV] = imx_clk_divider("sai3_pre_div", "sai3_cg", base + 0xa600, 16, 3);
627 clks[IMX7D_SPDIF_ROOT_PRE_DIV] = imx_clk_divider("spdif_pre_div", "spdif_cg", base + 0xa680, 16, 3);
628 clks[IMX7D_ENET1_REF_ROOT_PRE_DIV] = imx_clk_divider("enet1_ref_pre_div", "enet1_ref_cg", base + 0xa700, 16, 3);
629 clks[IMX7D_ENET1_TIME_ROOT_PRE_DIV] = imx_clk_divider("enet1_time_pre_div", "enet1_time_cg", base + 0xa780, 16, 3);
630 clks[IMX7D_ENET2_REF_ROOT_PRE_DIV] = imx_clk_divider("enet2_ref_pre_div", "enet2_ref_cg", base + 0xa800, 16, 3);
631 clks[IMX7D_ENET2_TIME_ROOT_PRE_DIV] = imx_clk_divider("enet2_time_pre_div", "enet2_time_cg", base + 0xa880, 16, 3);
632 clks[IMX7D_ENET_PHY_REF_ROOT_PRE_DIV] = imx_clk_divider("enet_phy_ref_pre_div", "enet_phy_ref_cg", base + 0xa900, 16, 3);
633 clks[IMX7D_EIM_ROOT_PRE_DIV] = imx_clk_divider("eim_pre_div", "eim_cg", base + 0xa980, 16, 3);
634 clks[IMX7D_NAND_ROOT_PRE_DIV] = imx_clk_divider("nand_pre_div", "nand_cg", base + 0xaa00, 16, 3);
635 clks[IMX7D_QSPI_ROOT_PRE_DIV] = imx_clk_divider("qspi_pre_div", "qspi_cg", base + 0xaa80, 16, 3);
636 clks[IMX7D_USDHC1_ROOT_PRE_DIV] = imx_clk_divider("usdhc1_pre_div", "usdhc1_cg", base + 0xab00, 16, 3);
637 clks[IMX7D_USDHC2_ROOT_PRE_DIV] = imx_clk_divider("usdhc2_pre_div", "usdhc2_cg", base + 0xab80, 16, 3);
638 clks[IMX7D_USDHC3_ROOT_PRE_DIV] = imx_clk_divider("usdhc3_pre_div", "usdhc3_cg", base + 0xac00, 16, 3);
639 clks[IMX7D_CAN1_ROOT_PRE_DIV] = imx_clk_divider("can1_pre_div", "can1_cg", base + 0xac80, 16, 3);
640 clks[IMX7D_CAN2_ROOT_PRE_DIV] = imx_clk_divider("can2_pre_div", "can2_cg", base + 0xad00, 16, 3);
641 clks[IMX7D_I2C1_ROOT_PRE_DIV] = imx_clk_divider("i2c1_pre_div", "i2c1_cg", base + 0xad80, 16, 3);
642 clks[IMX7D_I2C2_ROOT_PRE_DIV] = imx_clk_divider("i2c2_pre_div", "i2c2_cg", base + 0xae00, 16, 3);
643 clks[IMX7D_I2C3_ROOT_PRE_DIV] = imx_clk_divider("i2c3_pre_div", "i2c3_cg", base + 0xae80, 16, 3);
644 clks[IMX7D_I2C4_ROOT_PRE_DIV] = imx_clk_divider("i2c4_pre_div", "i2c4_cg", base + 0xaf00, 16, 3);
645 clks[IMX7D_UART1_ROOT_PRE_DIV] = imx_clk_divider("uart1_pre_div", "uart1_cg", base + 0xaf80, 16, 3);
646 clks[IMX7D_UART2_ROOT_PRE_DIV] = imx_clk_divider("uart2_pre_div", "uart2_cg", base + 0xb000, 16, 3);
647 clks[IMX7D_UART3_ROOT_PRE_DIV] = imx_clk_divider("uart3_pre_div", "uart3_cg", base + 0xb080, 16, 3);
648 clks[IMX7D_UART4_ROOT_PRE_DIV] = imx_clk_divider("uart4_pre_div", "uart4_cg", base + 0xb100, 16, 3);
649 clks[IMX7D_UART5_ROOT_PRE_DIV] = imx_clk_divider("uart5_pre_div", "uart5_cg", base + 0xb180, 16, 3);
650 clks[IMX7D_UART6_ROOT_PRE_DIV] = imx_clk_divider("uart6_pre_div", "uart6_cg", base + 0xb200, 16, 3);
651 clks[IMX7D_UART7_ROOT_PRE_DIV] = imx_clk_divider("uart7_pre_div", "uart7_cg", base + 0xb280, 16, 3);
652 clks[IMX7D_ECSPI1_ROOT_PRE_DIV] = imx_clk_divider("ecspi1_pre_div", "ecspi1_cg", base + 0xb300, 16, 3);
653 clks[IMX7D_ECSPI2_ROOT_PRE_DIV] = imx_clk_divider("ecspi2_pre_div", "ecspi2_cg", base + 0xb380, 16, 3);
654 clks[IMX7D_ECSPI3_ROOT_PRE_DIV] = imx_clk_divider("ecspi3_pre_div", "ecspi3_cg", base + 0xb400, 16, 3);
655 clks[IMX7D_ECSPI4_ROOT_PRE_DIV] = imx_clk_divider("ecspi4_pre_div", "ecspi4_cg", base + 0xb480, 16, 3);
656 clks[IMX7D_PWM1_ROOT_PRE_DIV] = imx_clk_divider("pwm1_pre_div", "pwm1_cg", base + 0xb500, 16, 3);
657 clks[IMX7D_PWM2_ROOT_PRE_DIV] = imx_clk_divider("pwm2_pre_div", "pwm2_cg", base + 0xb580, 16, 3);
658 clks[IMX7D_PWM3_ROOT_PRE_DIV] = imx_clk_divider("pwm3_pre_div", "pwm3_cg", base + 0xb600, 16, 3);
659 clks[IMX7D_PWM4_ROOT_PRE_DIV] = imx_clk_divider("pwm4_pre_div", "pwm4_cg", base + 0xb680, 16, 3);
660 clks[IMX7D_FLEXTIMER1_ROOT_PRE_DIV] = imx_clk_divider("flextimer1_pre_div", "flextimer1_cg", base + 0xb700, 16, 3);
661 clks[IMX7D_FLEXTIMER2_ROOT_PRE_DIV] = imx_clk_divider("flextimer2_pre_div", "flextimer2_cg", base + 0xb780, 16, 3);
662 clks[IMX7D_SIM1_ROOT_PRE_DIV] = imx_clk_divider("sim1_pre_div", "sim1_cg", base + 0xb800, 16, 3);
663 clks[IMX7D_SIM2_ROOT_PRE_DIV] = imx_clk_divider("sim2_pre_div", "sim2_cg", base + 0xb880, 16, 3);
664 clks[IMX7D_GPT1_ROOT_PRE_DIV] = imx_clk_divider("gpt1_pre_div", "gpt1_cg", base + 0xb900, 16, 3);
665 clks[IMX7D_GPT2_ROOT_PRE_DIV] = imx_clk_divider("gpt2_pre_div", "gpt2_cg", base + 0xb980, 16, 3);
666 clks[IMX7D_GPT3_ROOT_PRE_DIV] = imx_clk_divider("gpt3_pre_div", "gpt3_cg", base + 0xba00, 16, 3);
667 clks[IMX7D_GPT4_ROOT_PRE_DIV] = imx_clk_divider("gpt4_pre_div", "gpt4_cg", base + 0xba80, 16, 3);
668 clks[IMX7D_TRACE_ROOT_PRE_DIV] = imx_clk_divider("trace_pre_div", "trace_cg", base + 0xbb00, 16, 3);
669 clks[IMX7D_WDOG_ROOT_PRE_DIV] = imx_clk_divider("wdog_pre_div", "wdog_cg", base + 0xbb80, 16, 3);
670 clks[IMX7D_CSI_MCLK_ROOT_PRE_DIV] = imx_clk_divider("csi_mclk_pre_div", "csi_mclk_cg", base + 0xbc00, 16, 3);
671 clks[IMX7D_AUDIO_MCLK_ROOT_PRE_DIV] = imx_clk_divider("audio_mclk_pre_div", "audio_mclk_cg", base + 0xbc80, 16, 3);
672 clks[IMX7D_WRCLK_ROOT_PRE_DIV] = imx_clk_divider("wrclk_pre_div", "wrclk_cg", base + 0xbd00, 16, 3);
673 clks[IMX7D_CLKO1_ROOT_PRE_DIV] = imx_clk_divider("clko1_pre_div", "clko1_cg", base + 0xbd80, 16, 3);
674 clks[IMX7D_CLKO2_ROOT_PRE_DIV] = imx_clk_divider("clko2_pre_div", "clko2_cg", base + 0xbe00, 16, 3);
675
676 clks[IMX7D_ARM_A7_ROOT_DIV] = imx_clk_divider("arm_a7_div", "arm_a7_cg", base + 0x8000, 0, 3);
677 clks[IMX7D_ARM_M4_ROOT_DIV] = imx_clk_divider("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
678 clks[IMX7D_ARM_M0_ROOT_DIV] = imx_clk_divider("arm_m0_div", "arm_m0_cg", base + 0x8100, 0, 3);
679 clks[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_divider("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6);
680 clks[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_divider("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6);
681 clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6);
682 clks[IMX7D_NAND_USDHC_BUS_ROOT_DIV] = imx_clk_divider("nand_usdhc_post_div", "nand_usdhc_pre_div", base + 0x8980, 0, 6);
683 clks[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_divider("ahb_post_div", "ahb_pre_div", base + 0x9000, 0, 6);
684 clks[IMX7D_DRAM_ROOT_DIV] = imx_clk_divider("dram_post_div", "dram_cg", base + 0x9880, 0, 3);
685 clks[IMX7D_DRAM_PHYM_ALT_ROOT_DIV] = imx_clk_divider("dram_phym_alt_post_div", "dram_phym_alt_pre_div", base + 0xa000, 0, 3);
686 clks[IMX7D_DRAM_ALT_ROOT_DIV] = imx_clk_divider("dram_alt_post_div", "dram_alt_pre_div", base + 0xa080, 0, 3);
687 clks[IMX7D_USB_HSIC_ROOT_DIV] = imx_clk_divider("usb_hsic_post_div", "usb_hsic_pre_div", base + 0xa100, 0, 6);
688 clks[IMX7D_PCIE_CTRL_ROOT_DIV] = imx_clk_divider("pcie_ctrl_post_div", "pcie_ctrl_pre_div", base + 0xa180, 0, 6);
689 clks[IMX7D_PCIE_PHY_ROOT_DIV] = imx_clk_divider("pcie_phy_post_div", "pcie_phy_pre_div", base + 0xa200, 0, 6);
690 clks[IMX7D_EPDC_PIXEL_ROOT_DIV] = imx_clk_divider("epdc_pixel_post_div", "epdc_pixel_pre_div", base + 0xa280, 0, 6);
691 clks[IMX7D_LCDIF_PIXEL_ROOT_DIV] = imx_clk_divider("lcdif_pixel_post_div", "lcdif_pixel_pre_div", base + 0xa300, 0, 6);
692 clks[IMX7D_MIPI_DSI_ROOT_DIV] = imx_clk_divider("mipi_dsi_post_div", "mipi_dsi_pre_div", base + 0xa380, 0, 6);
693 clks[IMX7D_MIPI_CSI_ROOT_DIV] = imx_clk_divider("mipi_csi_post_div", "mipi_csi_pre_div", base + 0xa400, 0, 6);
694 clks[IMX7D_MIPI_DPHY_ROOT_DIV] = imx_clk_divider("mipi_dphy_post_div", "mipi_csi_dphy_div", base + 0xa480, 0, 6);
695 clks[IMX7D_SAI1_ROOT_DIV] = imx_clk_divider("sai1_post_div", "sai1_pre_div", base + 0xa500, 0, 6);
696 clks[IMX7D_SAI2_ROOT_DIV] = imx_clk_divider("sai2_post_div", "sai2_pre_div", base + 0xa580, 0, 6);
697 clks[IMX7D_SAI3_ROOT_DIV] = imx_clk_divider("sai3_post_div", "sai3_pre_div", base + 0xa600, 0, 6);
698 clks[IMX7D_SPDIF_ROOT_DIV] = imx_clk_divider("spdif_post_div", "spdif_pre_div", base + 0xa680, 0, 6);
699 clks[IMX7D_ENET1_REF_ROOT_DIV] = imx_clk_divider("enet1_ref_post_div", "enet1_ref_pre_div", base + 0xa700, 0, 6);
700 clks[IMX7D_ENET1_TIME_ROOT_DIV] = imx_clk_divider("enet1_time_post_div", "enet1_time_pre_div", base + 0xa780, 0, 6);
701 clks[IMX7D_ENET2_REF_ROOT_DIV] = imx_clk_divider("enet2_ref_post_div", "enet2_ref_pre_div", base + 0xa800, 0, 6);
702 clks[IMX7D_ENET2_TIME_ROOT_DIV] = imx_clk_divider("enet2_time_post_div", "enet2_time_pre_div", base + 0xa880, 0, 6);
703 clks[IMX7D_ENET_PHY_REF_ROOT_DIV] = imx_clk_divider("enet_phy_ref_post_div", "enet_phy_ref_pre_div", base + 0xa900, 0, 6);
704 clks[IMX7D_EIM_ROOT_DIV] = imx_clk_divider("eim_post_div", "eim_pre_div", base + 0xa980, 0, 6);
705 clks[IMX7D_NAND_ROOT_DIV] = imx_clk_divider("nand_post_div", "nand_pre_div", base + 0xaa00, 0, 6);
706 clks[IMX7D_QSPI_ROOT_DIV] = imx_clk_divider("qspi_post_div", "qspi_pre_div", base + 0xaa80, 0, 6);
707 clks[IMX7D_USDHC1_ROOT_DIV] = imx_clk_divider("usdhc1_post_div", "usdhc1_pre_div", base + 0xab00, 0, 6);
708 clks[IMX7D_USDHC2_ROOT_DIV] = imx_clk_divider("usdhc2_post_div", "usdhc2_pre_div", base + 0xab80, 0, 6);
709 clks[IMX7D_USDHC3_ROOT_DIV] = imx_clk_divider("usdhc3_post_div", "usdhc3_pre_div", base + 0xac00, 0, 6);
710 clks[IMX7D_CAN1_ROOT_DIV] = imx_clk_divider("can1_post_div", "can1_pre_div", base + 0xac80, 0, 6);
711 clks[IMX7D_CAN2_ROOT_DIV] = imx_clk_divider("can2_post_div", "can2_pre_div", base + 0xad00, 0, 6);
712 clks[IMX7D_I2C1_ROOT_DIV] = imx_clk_divider("i2c1_post_div", "i2c1_pre_div", base + 0xad80, 0, 6);
713 clks[IMX7D_I2C2_ROOT_DIV] = imx_clk_divider("i2c2_post_div", "i2c2_pre_div", base + 0xae00, 0, 6);
714 clks[IMX7D_I2C3_ROOT_DIV] = imx_clk_divider("i2c3_post_div", "i2c3_pre_div", base + 0xae80, 0, 6);
715 clks[IMX7D_I2C4_ROOT_DIV] = imx_clk_divider("i2c4_post_div", "i2c4_pre_div", base + 0xaf00, 0, 6);
716 clks[IMX7D_UART1_ROOT_DIV] = imx_clk_divider("uart1_post_div", "uart1_pre_div", base + 0xaf80, 0, 6);
717 clks[IMX7D_UART2_ROOT_DIV] = imx_clk_divider("uart2_post_div", "uart2_pre_div", base + 0xb000, 0, 6);
718 clks[IMX7D_UART3_ROOT_DIV] = imx_clk_divider("uart3_post_div", "uart3_pre_div", base + 0xb080, 0, 6);
719 clks[IMX7D_UART4_ROOT_DIV] = imx_clk_divider("uart4_post_div", "uart4_pre_div", base + 0xb100, 0, 6);
720 clks[IMX7D_UART5_ROOT_DIV] = imx_clk_divider("uart5_post_div", "uart5_pre_div", base + 0xb180, 0, 6);
721 clks[IMX7D_UART6_ROOT_DIV] = imx_clk_divider("uart6_post_div", "uart6_pre_div", base + 0xb200, 0, 6);
722 clks[IMX7D_UART7_ROOT_DIV] = imx_clk_divider("uart7_post_div", "uart7_pre_div", base + 0xb280, 0, 6);
723 clks[IMX7D_ECSPI1_ROOT_DIV] = imx_clk_divider("ecspi1_post_div", "ecspi1_pre_div", base + 0xb300, 0, 6);
724 clks[IMX7D_ECSPI2_ROOT_DIV] = imx_clk_divider("ecspi2_post_div", "ecspi2_pre_div", base + 0xb380, 0, 6);
725 clks[IMX7D_ECSPI3_ROOT_DIV] = imx_clk_divider("ecspi3_post_div", "ecspi3_pre_div", base + 0xb400, 0, 6);
726 clks[IMX7D_ECSPI4_ROOT_DIV] = imx_clk_divider("ecspi4_post_div", "ecspi4_pre_div", base + 0xb480, 0, 6);
727 clks[IMX7D_PWM1_ROOT_DIV] = imx_clk_divider("pwm1_post_div", "pwm1_pre_div", base + 0xb500, 0, 6);
728 clks[IMX7D_PWM2_ROOT_DIV] = imx_clk_divider("pwm2_post_div", "pwm2_pre_div", base + 0xb580, 0, 6);
729 clks[IMX7D_PWM3_ROOT_DIV] = imx_clk_divider("pwm3_post_div", "pwm3_pre_div", base + 0xb600, 0, 6);
730 clks[IMX7D_PWM4_ROOT_DIV] = imx_clk_divider("pwm4_post_div", "pwm4_pre_div", base + 0xb680, 0, 6);
731 clks[IMX7D_FLEXTIMER1_ROOT_DIV] = imx_clk_divider("flextimer1_post_div", "flextimer1_pre_div", base + 0xb700, 0, 6);
732 clks[IMX7D_FLEXTIMER2_ROOT_DIV] = imx_clk_divider("flextimer2_post_div", "flextimer2_pre_div", base + 0xb780, 0, 6);
733 clks[IMX7D_SIM1_ROOT_DIV] = imx_clk_divider("sim1_post_div", "sim1_pre_div", base + 0xb800, 0, 6);
734 clks[IMX7D_SIM2_ROOT_DIV] = imx_clk_divider("sim2_post_div", "sim2_pre_div", base + 0xb880, 0, 6);
735 clks[IMX7D_GPT1_ROOT_DIV] = imx_clk_divider("gpt1_post_div", "gpt1_pre_div", base + 0xb900, 0, 6);
736 clks[IMX7D_GPT2_ROOT_DIV] = imx_clk_divider("gpt2_post_div", "gpt2_pre_div", base + 0xb980, 0, 6);
737 clks[IMX7D_GPT3_ROOT_DIV] = imx_clk_divider("gpt3_post_div", "gpt3_pre_div", base + 0xba00, 0, 6);
738 clks[IMX7D_GPT4_ROOT_DIV] = imx_clk_divider("gpt4_post_div", "gpt4_pre_div", base + 0xba80, 0, 6);
739 clks[IMX7D_TRACE_ROOT_DIV] = imx_clk_divider("trace_post_div", "trace_pre_div", base + 0xbb00, 0, 6);
740 clks[IMX7D_WDOG_ROOT_DIV] = imx_clk_divider("wdog_post_div", "wdog_pre_div", base + 0xbb80, 0, 6);
741 clks[IMX7D_CSI_MCLK_ROOT_DIV] = imx_clk_divider("csi_mclk_post_div", "csi_mclk_pre_div", base + 0xbc00, 0, 6);
742 clks[IMX7D_AUDIO_MCLK_ROOT_DIV] = imx_clk_divider("audio_mclk_post_div", "audio_mclk_pre_div", base + 0xbc80, 0, 6);
743 clks[IMX7D_WRCLK_ROOT_DIV] = imx_clk_divider("wrclk_post_div", "wrclk_pre_div", base + 0xbd00, 0, 6);
744 clks[IMX7D_CLKO1_ROOT_DIV] = imx_clk_divider("clko1_post_div", "clko1_pre_div", base + 0xbd80, 0, 6);
745 clks[IMX7D_CLKO2_ROOT_DIV] = imx_clk_divider("clko2_post_div", "clko2_pre_div", base + 0xbe00, 0, 6);
746
747 clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate2("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0);
748 clks[IMX7D_ARM_M4_ROOT_CLK] = imx_clk_gate2("arm_m4_root_clk", "arm_m4_div", base + 0x4010, 0);
749 clks[IMX7D_ARM_M0_ROOT_CLK] = imx_clk_gate2("arm_m0_root_clk", "arm_m0_div", base + 0x4020, 0);
750 clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate2("main_axi_root_clk", "axi_post_div", base + 0x4040, 0);
751 clks[IMX7D_DISP_AXI_ROOT_CLK] = imx_clk_gate2("disp_axi_root_clk", "disp_axi_post_div", base + 0x4050, 0);
752 clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate2("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0);
753 clks[IMX7D_OCRAM_CLK] = imx_clk_gate2("ocram_clk", "axi_post_div", base + 0x4110, 0);
754 clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate2("ocram_s_clk", "ahb_post_div", base + 0x4120, 0);
755 clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_gate2("nand_usdhc_root_clk", "nand_usdhc_post_div", base + 0x4130, 0);
756 clks[IMX7D_AHB_CHANNEL_ROOT_CLK] = imx_clk_gate2("ahb_root_clk", "ahb_post_div", base + 0x4200, 0);
757 clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate2("dram_root_clk", "dram_post_div", base + 0x4130, 0);
758 clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate2("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
759 clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate2("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
760 clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate2("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
761 clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate2("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0);
762 clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate2("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0);
763 clks[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_gate2("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0);
764 clks[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_gate2("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0);
765 clks[IMX7D_LCDIF_PIXEL_ROOT_CLK] = imx_clk_gate2("lcdif_pixel_root_clk", "lcdif_pixel_post_div", base + 0x44b0, 0);
766 clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate2("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0);
767 clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate2("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0);
768 clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate2("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0);
769 clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0);
770 clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0);
771 clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0);
772 clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate2("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0);
773 clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate2("enet1_ref_root_clk", "enet1_ref_post_div", base + 0x44e0, 0);
774 clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate2("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0, 0);
775 clks[IMX7D_ENET2_REF_ROOT_CLK] = imx_clk_gate2("enet2_ref_root_clk", "enet2_ref_post_div", base + 0x4500, 0);
776 clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate2("enet2_time_root_clk", "enet2_time_post_div", base + 0x4510, 0);
777 clks[IMX7D_ENET_PHY_REF_ROOT_CLK] = imx_clk_gate2("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base + 0x4520, 0);
778 clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate2("eim_root_clk", "eim_post_div", base + 0x4160, 0);
779 clks[IMX7D_NAND_ROOT_CLK] = imx_clk_gate2("nand_root_clk", "nand_post_div", base + 0x4140, 0);
780 clks[IMX7D_QSPI_ROOT_CLK] = imx_clk_gate2("qspi_root_clk", "qspi_post_div", base + 0x4150, 0);
781 clks[IMX7D_USDHC1_ROOT_CLK] = imx_clk_gate2("usdhc1_root_clk", "usdhc1_post_div", base + 0x46c0, 0);
782 clks[IMX7D_USDHC2_ROOT_CLK] = imx_clk_gate2("usdhc2_root_clk", "usdhc2_post_div", base + 0x46d0, 0);
783 clks[IMX7D_USDHC3_ROOT_CLK] = imx_clk_gate2("usdhc3_root_clk", "usdhc3_post_div", base + 0x46e0, 0);
784 clks[IMX7D_CAN1_ROOT_CLK] = imx_clk_gate2("can1_root_clk", "can1_post_div", base + 0x4740, 0);
785 clks[IMX7D_CAN2_ROOT_CLK] = imx_clk_gate2("can2_root_clk", "can2_post_div", base + 0x4750, 0);
786 clks[IMX7D_I2C1_ROOT_CLK] = imx_clk_gate2("i2c1_root_clk", "i2c1_post_div", base + 0x4880, 0);
787 clks[IMX7D_I2C2_ROOT_CLK] = imx_clk_gate2("i2c2_root_clk", "i2c2_post_div", base + 0x4890, 0);
788 clks[IMX7D_I2C3_ROOT_CLK] = imx_clk_gate2("i2c3_root_clk", "i2c3_post_div", base + 0x48a0, 0);
789 clks[IMX7D_I2C4_ROOT_CLK] = imx_clk_gate2("i2c4_root_clk", "i2c4_post_div", base + 0x48b0, 0);
790 clks[IMX7D_UART1_ROOT_CLK] = imx_clk_gate2("uart1_root_clk", "uart1_post_div", base + 0x4940, 0);
791 clks[IMX7D_UART2_ROOT_CLK] = imx_clk_gate2("uart2_root_clk", "uart2_post_div", base + 0x4950, 0);
792 clks[IMX7D_UART3_ROOT_CLK] = imx_clk_gate2("uart3_root_clk", "uart3_post_div", base + 0x4960, 0);
793 clks[IMX7D_UART4_ROOT_CLK] = imx_clk_gate2("uart4_root_clk", "uart4_post_div", base + 0x4970, 0);
794 clks[IMX7D_UART5_ROOT_CLK] = imx_clk_gate2("uart5_root_clk", "uart5_post_div", base + 0x4980, 0);
795 clks[IMX7D_UART6_ROOT_CLK] = imx_clk_gate2("uart6_root_clk", "uart6_post_div", base + 0x4990, 0);
796 clks[IMX7D_UART7_ROOT_CLK] = imx_clk_gate2("uart7_root_clk", "uart7_post_div", base + 0x49a0, 0);
797 clks[IMX7D_ECSPI1_ROOT_CLK] = imx_clk_gate2("ecspi1_root_clk", "ecspi1_post_div", base + 0x4780, 0);
798 clks[IMX7D_ECSPI2_ROOT_CLK] = imx_clk_gate2("ecspi2_root_clk", "ecspi2_post_div", base + 0x4790, 0);
799 clks[IMX7D_ECSPI3_ROOT_CLK] = imx_clk_gate2("ecspi3_root_clk", "ecspi3_post_div", base + 0x47a0, 0);
800 clks[IMX7D_ECSPI4_ROOT_CLK] = imx_clk_gate2("ecspi4_root_clk", "ecspi4_post_div", base + 0x47b0, 0);
801 clks[IMX7D_PWM1_ROOT_CLK] = imx_clk_gate2("pwm1_root_clk", "pwm1_post_div", base + 0x4840, 0);
802 clks[IMX7D_PWM2_ROOT_CLK] = imx_clk_gate2("pwm2_root_clk", "pwm2_post_div", base + 0x4850, 0);
803 clks[IMX7D_PWM3_ROOT_CLK] = imx_clk_gate2("pwm3_root_clk", "pwm3_post_div", base + 0x4860, 0);
804 clks[IMX7D_PWM4_ROOT_CLK] = imx_clk_gate2("pwm4_root_clk", "pwm4_post_div", base + 0x4870, 0);
805 clks[IMX7D_FLEXTIMER1_ROOT_CLK] = imx_clk_gate2("flextimer1_root_clk", "flextimer1_post_div", base + 0x4800, 0);
806 clks[IMX7D_FLEXTIMER2_ROOT_CLK] = imx_clk_gate2("flextimer2_root_clk", "flextimer2_post_div", base + 0x4810, 0);
807 clks[IMX7D_SIM1_ROOT_CLK] = imx_clk_gate2("sim1_root_clk", "sim1_post_div", base + 0x4900, 0);
808 clks[IMX7D_SIM2_ROOT_CLK] = imx_clk_gate2("sim2_root_clk", "sim2_post_div", base + 0x4910, 0);
809 clks[IMX7D_GPT1_ROOT_CLK] = imx_clk_gate2("gpt1_root_clk", "gpt1_post_div", base + 0x47c0, 0);
810 clks[IMX7D_GPT2_ROOT_CLK] = imx_clk_gate2("gpt2_root_clk", "gpt2_post_div", base + 0x47d0, 0);
811 clks[IMX7D_GPT3_ROOT_CLK] = imx_clk_gate2("gpt3_root_clk", "gpt3_post_div", base + 0x47e0, 0);
812 clks[IMX7D_GPT4_ROOT_CLK] = imx_clk_gate2("gpt4_root_clk", "gpt4_post_div", base + 0x47f0, 0);
813 clks[IMX7D_TRACE_ROOT_CLK] = imx_clk_gate2("trace_root_clk", "trace_post_div", base + 0x4300, 0);
814 clks[IMX7D_WDOG1_ROOT_CLK] = imx_clk_gate2("wdog1_root_clk", "wdog_post_div", base + 0x49c0, 0);
815 clks[IMX7D_WDOG2_ROOT_CLK] = imx_clk_gate2("wdog2_root_clk", "wdog_post_div", base + 0x49d0, 0);
816 clks[IMX7D_WDOG3_ROOT_CLK] = imx_clk_gate2("wdog3_root_clk", "wdog_post_div", base + 0x49e0, 0);
817 clks[IMX7D_WDOG4_ROOT_CLK] = imx_clk_gate2("wdog4_root_clk", "wdog_post_div", base + 0x49f0, 0);
818 clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate2("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0);
819 clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate2("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0);
820 clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate2("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0);
821
822 clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
823
824 for (i = 0; i < ARRAY_SIZE(clks); i++)
825 if (IS_ERR(clks[i]))
826 pr_err("i.MX7D clk %d: register failed with %ld\n",
827 i, PTR_ERR(clks[i]));
828
829 clk_data.clks = clks;
830 clk_data.clk_num = ARRAY_SIZE(clks);
831 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
832
833 /* TO BE FIXED LATER
834 * Enable all clock to bring up imx7, otherwise system will be halt and block
835 * the other part upstream Because imx7d clock design changed, clock framework
836 * need do a little modify.
837 * Dong Aisheng is working on this. After that, this part need be changed.
838 */
839 for (i = 0; i < IMX7D_CLK_END; i++)
840 clk_prepare_enable(clks[i]);
841
842 /* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */
843 clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
844
845 /*
846 * init enet clock source:
847 * AXI clock source is 250MHz
848 * Phy refrence clock is 25MHz
849 * 1588 time clock source is 100MHz
850 */
851 clk_set_parent(clks[IMX7D_ENET_AXI_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_250M_CLK]);
852 clk_set_parent(clks[IMX7D_ENET_PHY_REF_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_25M_CLK]);
853 clk_set_parent(clks[IMX7D_ENET1_TIME_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_100M_CLK]);
854 clk_set_parent(clks[IMX7D_ENET2_TIME_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_100M_CLK]);
855
856 /* set uart module clock's parent clock source that must be great then 80MHz */
857 clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
858
859}
860CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init);
diff --git a/drivers/clk/imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c
new file mode 100644
index 000000000000..0b0f6f66ec56
--- /dev/null
+++ b/drivers/clk/imx/clk-pfd.c
@@ -0,0 +1,158 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/clk.h>
14#include <linux/clk-provider.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include <linux/err.h>
18#include "clk.h"
19
20/**
21 * struct clk_pfd - IMX PFD clock
22 * @clk_hw: clock source
23 * @reg: PFD register address
24 * @idx: the index of PFD encoded in the register
25 *
26 * PFD clock found on i.MX6 series. Each register for PFD has 4 clk_pfd
27 * data encoded, and member idx is used to specify the one. And each
28 * register has SET, CLR and TOG registers at offset 0x4 0x8 and 0xc.
29 */
30struct clk_pfd {
31 struct clk_hw hw;
32 void __iomem *reg;
33 u8 idx;
34};
35
36#define to_clk_pfd(_hw) container_of(_hw, struct clk_pfd, hw)
37
38#define SET 0x4
39#define CLR 0x8
40#define OTG 0xc
41
42static int clk_pfd_enable(struct clk_hw *hw)
43{
44 struct clk_pfd *pfd = to_clk_pfd(hw);
45
46 writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR);
47
48 return 0;
49}
50
51static void clk_pfd_disable(struct clk_hw *hw)
52{
53 struct clk_pfd *pfd = to_clk_pfd(hw);
54
55 writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET);
56}
57
58static unsigned long clk_pfd_recalc_rate(struct clk_hw *hw,
59 unsigned long parent_rate)
60{
61 struct clk_pfd *pfd = to_clk_pfd(hw);
62 u64 tmp = parent_rate;
63 u8 frac = (readl_relaxed(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
64
65 tmp *= 18;
66 do_div(tmp, frac);
67
68 return tmp;
69}
70
71static long clk_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
72 unsigned long *prate)
73{
74 u64 tmp = *prate;
75 u8 frac;
76
77 tmp = tmp * 18 + rate / 2;
78 do_div(tmp, rate);
79 frac = tmp;
80 if (frac < 12)
81 frac = 12;
82 else if (frac > 35)
83 frac = 35;
84 tmp = *prate;
85 tmp *= 18;
86 do_div(tmp, frac);
87
88 return tmp;
89}
90
91static int clk_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
92 unsigned long parent_rate)
93{
94 struct clk_pfd *pfd = to_clk_pfd(hw);
95 u64 tmp = parent_rate;
96 u8 frac;
97
98 tmp = tmp * 18 + rate / 2;
99 do_div(tmp, rate);
100 frac = tmp;
101 if (frac < 12)
102 frac = 12;
103 else if (frac > 35)
104 frac = 35;
105
106 writel_relaxed(0x3f << (pfd->idx * 8), pfd->reg + CLR);
107 writel_relaxed(frac << (pfd->idx * 8), pfd->reg + SET);
108
109 return 0;
110}
111
112static int clk_pfd_is_enabled(struct clk_hw *hw)
113{
114 struct clk_pfd *pfd = to_clk_pfd(hw);
115
116 if (readl_relaxed(pfd->reg) & (1 << ((pfd->idx + 1) * 8 - 1)))
117 return 0;
118
119 return 1;
120}
121
122static const struct clk_ops clk_pfd_ops = {
123 .enable = clk_pfd_enable,
124 .disable = clk_pfd_disable,
125 .recalc_rate = clk_pfd_recalc_rate,
126 .round_rate = clk_pfd_round_rate,
127 .set_rate = clk_pfd_set_rate,
128 .is_enabled = clk_pfd_is_enabled,
129};
130
131struct clk *imx_clk_pfd(const char *name, const char *parent_name,
132 void __iomem *reg, u8 idx)
133{
134 struct clk_pfd *pfd;
135 struct clk *clk;
136 struct clk_init_data init;
137
138 pfd = kzalloc(sizeof(*pfd), GFP_KERNEL);
139 if (!pfd)
140 return ERR_PTR(-ENOMEM);
141
142 pfd->reg = reg;
143 pfd->idx = idx;
144
145 init.name = name;
146 init.ops = &clk_pfd_ops;
147 init.flags = 0;
148 init.parent_names = &parent_name;
149 init.num_parents = 1;
150
151 pfd->hw.init = &init;
152
153 clk = clk_register(NULL, &pfd->hw);
154 if (IS_ERR(clk))
155 kfree(pfd);
156
157 return clk;
158}
diff --git a/drivers/clk/imx/clk-pllv1.c b/drivers/clk/imx/clk-pllv1.c
new file mode 100644
index 000000000000..c34ad8a611dd
--- /dev/null
+++ b/drivers/clk/imx/clk-pllv1.c
@@ -0,0 +1,141 @@
1#include <linux/clk.h>
2#include <linux/clk-provider.h>
3#include <linux/io.h>
4#include <linux/slab.h>
5#include <linux/kernel.h>
6#include <linux/err.h>
7
8#include "clk.h"
9
10/**
11 * pll v1
12 *
13 * @clk_hw clock source
14 * @parent the parent clock name
15 * @base base address of pll registers
16 *
17 * PLL clock version 1, found on i.MX1/21/25/27/31/35
18 */
19
20#define MFN_BITS (10)
21#define MFN_SIGN (BIT(MFN_BITS - 1))
22#define MFN_MASK (MFN_SIGN - 1)
23
24struct clk_pllv1 {
25 struct clk_hw hw;
26 void __iomem *base;
27 enum imx_pllv1_type type;
28};
29
30#define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk))
31
32static inline bool is_imx1_pllv1(struct clk_pllv1 *pll)
33{
34 return pll->type == IMX_PLLV1_IMX1;
35}
36
37static inline bool is_imx21_pllv1(struct clk_pllv1 *pll)
38{
39 return pll->type == IMX_PLLV1_IMX21;
40}
41
42static inline bool is_imx27_pllv1(struct clk_pllv1 *pll)
43{
44 return pll->type == IMX_PLLV1_IMX27;
45}
46
47static inline bool mfn_is_negative(struct clk_pllv1 *pll, unsigned int mfn)
48{
49 return !is_imx1_pllv1(pll) && !is_imx21_pllv1(pll) && (mfn & MFN_SIGN);
50}
51
52static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
53 unsigned long parent_rate)
54{
55 struct clk_pllv1 *pll = to_clk_pllv1(hw);
56 long long ll;
57 int mfn_abs;
58 unsigned int mfi, mfn, mfd, pd;
59 u32 reg;
60 unsigned long rate;
61
62 reg = readl(pll->base);
63
64 /*
65 * Get the resulting clock rate from a PLL register value and the input
66 * frequency. PLLs with this register layout can be found on i.MX1,
67 * i.MX21, i.MX27 and i,MX31
68 *
69 * mfi + mfn / (mfd + 1)
70 * f = 2 * f_ref * --------------------
71 * pd + 1
72 */
73
74 mfi = (reg >> 10) & 0xf;
75 mfn = reg & 0x3ff;
76 mfd = (reg >> 16) & 0x3ff;
77 pd = (reg >> 26) & 0xf;
78
79 mfi = mfi <= 5 ? 5 : mfi;
80
81 mfn_abs = mfn;
82
83 /*
84 * On all i.MXs except i.MX1 and i.MX21 mfn is a 10bit
85 * 2's complements number.
86 * On i.MX27 the bit 9 is the sign bit.
87 */
88 if (mfn_is_negative(pll, mfn)) {
89 if (is_imx27_pllv1(pll))
90 mfn_abs = mfn & MFN_MASK;
91 else
92 mfn_abs = BIT(MFN_BITS) - mfn;
93 }
94
95 rate = parent_rate * 2;
96 rate /= pd + 1;
97
98 ll = (unsigned long long)rate * mfn_abs;
99
100 do_div(ll, mfd + 1);
101
102 if (mfn_is_negative(pll, mfn))
103 ll = -ll;
104
105 ll = (rate * mfi) + ll;
106
107 return ll;
108}
109
110static struct clk_ops clk_pllv1_ops = {
111 .recalc_rate = clk_pllv1_recalc_rate,
112};
113
114struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
115 const char *parent, void __iomem *base)
116{
117 struct clk_pllv1 *pll;
118 struct clk *clk;
119 struct clk_init_data init;
120
121 pll = kmalloc(sizeof(*pll), GFP_KERNEL);
122 if (!pll)
123 return ERR_PTR(-ENOMEM);
124
125 pll->base = base;
126 pll->type = type;
127
128 init.name = name;
129 init.ops = &clk_pllv1_ops;
130 init.flags = 0;
131 init.parent_names = &parent;
132 init.num_parents = 1;
133
134 pll->hw.init = &init;
135
136 clk = clk_register(NULL, &pll->hw);
137 if (IS_ERR(clk))
138 kfree(pll);
139
140 return clk;
141}
diff --git a/drivers/clk/imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c
new file mode 100644
index 000000000000..20889d59b44d
--- /dev/null
+++ b/drivers/clk/imx/clk-pllv2.c
@@ -0,0 +1,266 @@
1#include <linux/kernel.h>
2#include <linux/clk.h>
3#include <linux/io.h>
4#include <linux/errno.h>
5#include <linux/delay.h>
6#include <linux/slab.h>
7#include <linux/err.h>
8
9#include <asm/div64.h>
10
11#include "clk.h"
12
13#define to_clk_pllv2(clk) (container_of(clk, struct clk_pllv2, clk))
14
15/* PLL Register Offsets */
16#define MXC_PLL_DP_CTL 0x00
17#define MXC_PLL_DP_CONFIG 0x04
18#define MXC_PLL_DP_OP 0x08
19#define MXC_PLL_DP_MFD 0x0C
20#define MXC_PLL_DP_MFN 0x10
21#define MXC_PLL_DP_MFNMINUS 0x14
22#define MXC_PLL_DP_MFNPLUS 0x18
23#define MXC_PLL_DP_HFS_OP 0x1C
24#define MXC_PLL_DP_HFS_MFD 0x20
25#define MXC_PLL_DP_HFS_MFN 0x24
26#define MXC_PLL_DP_MFN_TOGC 0x28
27#define MXC_PLL_DP_DESTAT 0x2c
28
29/* PLL Register Bit definitions */
30#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000
31#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000
32#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12
33#define MXC_PLL_DP_CTL_ADE 0x800
34#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400
35#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8)
36#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8
37#define MXC_PLL_DP_CTL_HFSM 0x80
38#define MXC_PLL_DP_CTL_PRE 0x40
39#define MXC_PLL_DP_CTL_UPEN 0x20
40#define MXC_PLL_DP_CTL_RST 0x10
41#define MXC_PLL_DP_CTL_RCP 0x8
42#define MXC_PLL_DP_CTL_PLM 0x4
43#define MXC_PLL_DP_CTL_BRM0 0x2
44#define MXC_PLL_DP_CTL_LRF 0x1
45
46#define MXC_PLL_DP_CONFIG_BIST 0x8
47#define MXC_PLL_DP_CONFIG_SJC_CE 0x4
48#define MXC_PLL_DP_CONFIG_AREN 0x2
49#define MXC_PLL_DP_CONFIG_LDREQ 0x1
50
51#define MXC_PLL_DP_OP_MFI_OFFSET 4
52#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4)
53#define MXC_PLL_DP_OP_PDF_OFFSET 0
54#define MXC_PLL_DP_OP_PDF_MASK 0xF
55
56#define MXC_PLL_DP_MFD_OFFSET 0
57#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF
58
59#define MXC_PLL_DP_MFN_OFFSET 0x0
60#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF
61
62#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17)
63#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16)
64#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0
65#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF
66
67#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31)
68#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF
69
70#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
71
72struct clk_pllv2 {
73 struct clk_hw hw;
74 void __iomem *base;
75};
76
77static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
78 u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn)
79{
80 long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
81 unsigned long dbl;
82 s64 temp;
83
84 dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
85
86 pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
87 mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
88 mfi = (mfi <= 5) ? 5 : mfi;
89 mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
90 mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
91 /* Sign extend to 32-bits */
92 if (mfn >= 0x04000000) {
93 mfn |= 0xFC000000;
94 mfn_abs = -mfn;
95 }
96
97 ref_clk = 2 * parent_rate;
98 if (dbl != 0)
99 ref_clk *= 2;
100
101 ref_clk /= (pdf + 1);
102 temp = (u64) ref_clk * mfn_abs;
103 do_div(temp, mfd + 1);
104 if (mfn < 0)
105 temp = -temp;
106 temp = (ref_clk * mfi) + temp;
107
108 return temp;
109}
110
111static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw,
112 unsigned long parent_rate)
113{
114 u32 dp_op, dp_mfd, dp_mfn, dp_ctl;
115 void __iomem *pllbase;
116 struct clk_pllv2 *pll = to_clk_pllv2(hw);
117
118 pllbase = pll->base;
119
120 dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
121 dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
122 dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
123 dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
124
125 return __clk_pllv2_recalc_rate(parent_rate, dp_ctl, dp_op, dp_mfd, dp_mfn);
126}
127
128static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate,
129 u32 *dp_op, u32 *dp_mfd, u32 *dp_mfn)
130{
131 u32 reg;
132 long mfi, pdf, mfn, mfd = 999999;
133 s64 temp64;
134 unsigned long quad_parent_rate;
135
136 quad_parent_rate = 4 * parent_rate;
137 pdf = mfi = -1;
138 while (++pdf < 16 && mfi < 5)
139 mfi = rate * (pdf+1) / quad_parent_rate;
140 if (mfi > 15)
141 return -EINVAL;
142 pdf--;
143
144 temp64 = rate * (pdf + 1) - quad_parent_rate * mfi;
145 do_div(temp64, quad_parent_rate / 1000000);
146 mfn = (long)temp64;
147
148 reg = mfi << 4 | pdf;
149
150 *dp_op = reg;
151 *dp_mfd = mfd;
152 *dp_mfn = mfn;
153
154 return 0;
155}
156
157static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate,
158 unsigned long parent_rate)
159{
160 struct clk_pllv2 *pll = to_clk_pllv2(hw);
161 void __iomem *pllbase;
162 u32 dp_ctl, dp_op, dp_mfd, dp_mfn;
163 int ret;
164
165 pllbase = pll->base;
166
167
168 ret = __clk_pllv2_set_rate(rate, parent_rate, &dp_op, &dp_mfd, &dp_mfn);
169 if (ret)
170 return ret;
171
172 dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
173 /* use dpdck0_2 */
174 __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
175
176 __raw_writel(dp_op, pllbase + MXC_PLL_DP_OP);
177 __raw_writel(dp_mfd, pllbase + MXC_PLL_DP_MFD);
178 __raw_writel(dp_mfn, pllbase + MXC_PLL_DP_MFN);
179
180 return 0;
181}
182
183static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate,
184 unsigned long *prate)
185{
186 u32 dp_op, dp_mfd, dp_mfn;
187
188 __clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn);
189 return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN,
190 dp_op, dp_mfd, dp_mfn);
191}
192
193static int clk_pllv2_prepare(struct clk_hw *hw)
194{
195 struct clk_pllv2 *pll = to_clk_pllv2(hw);
196 u32 reg;
197 void __iomem *pllbase;
198 int i = 0;
199
200 pllbase = pll->base;
201 reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
202 __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
203
204 /* Wait for lock */
205 do {
206 reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
207 if (reg & MXC_PLL_DP_CTL_LRF)
208 break;
209
210 udelay(1);
211 } while (++i < MAX_DPLL_WAIT_TRIES);
212
213 if (i == MAX_DPLL_WAIT_TRIES) {
214 pr_err("MX5: pll locking failed\n");
215 return -EINVAL;
216 }
217
218 return 0;
219}
220
221static void clk_pllv2_unprepare(struct clk_hw *hw)
222{
223 struct clk_pllv2 *pll = to_clk_pllv2(hw);
224 u32 reg;
225 void __iomem *pllbase;
226
227 pllbase = pll->base;
228 reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
229 __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
230}
231
232static struct clk_ops clk_pllv2_ops = {
233 .prepare = clk_pllv2_prepare,
234 .unprepare = clk_pllv2_unprepare,
235 .recalc_rate = clk_pllv2_recalc_rate,
236 .round_rate = clk_pllv2_round_rate,
237 .set_rate = clk_pllv2_set_rate,
238};
239
240struct clk *imx_clk_pllv2(const char *name, const char *parent,
241 void __iomem *base)
242{
243 struct clk_pllv2 *pll;
244 struct clk *clk;
245 struct clk_init_data init;
246
247 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
248 if (!pll)
249 return ERR_PTR(-ENOMEM);
250
251 pll->base = base;
252
253 init.name = name;
254 init.ops = &clk_pllv2_ops;
255 init.flags = 0;
256 init.parent_names = &parent;
257 init.num_parents = 1;
258
259 pll->hw.init = &init;
260
261 clk = clk_register(NULL, &pll->hw);
262 if (IS_ERR(clk))
263 kfree(pll);
264
265 return clk;
266}
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
new file mode 100644
index 000000000000..f0d15fb9d783
--- /dev/null
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -0,0 +1,338 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/clk.h>
14#include <linux/clk-provider.h>
15#include <linux/delay.h>
16#include <linux/io.h>
17#include <linux/slab.h>
18#include <linux/jiffies.h>
19#include <linux/err.h>
20#include "clk.h"
21
22#define PLL_NUM_OFFSET 0x10
23#define PLL_DENOM_OFFSET 0x20
24
25#define BM_PLL_POWER (0x1 << 12)
26#define BM_PLL_LOCK (0x1 << 31)
27#define IMX7_ENET_PLL_POWER (0x1 << 5)
28
29/**
30 * struct clk_pllv3 - IMX PLL clock version 3
31 * @clk_hw: clock source
32 * @base: base address of PLL registers
33 * @powerup_set: set POWER bit to power up the PLL
34 * @powerdown: pll powerdown offset bit
35 * @div_mask: mask of divider bits
36 * @div_shift: shift of divider bits
37 *
38 * IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3
39 * is actually a multiplier, and always sits at bit 0.
40 */
41struct clk_pllv3 {
42 struct clk_hw hw;
43 void __iomem *base;
44 bool powerup_set;
45 u32 powerdown;
46 u32 div_mask;
47 u32 div_shift;
48};
49
50#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
51
52static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
53{
54 unsigned long timeout = jiffies + msecs_to_jiffies(10);
55 u32 val = readl_relaxed(pll->base) & pll->powerdown;
56
57 /* No need to wait for lock when pll is not powered up */
58 if ((pll->powerup_set && !val) || (!pll->powerup_set && val))
59 return 0;
60
61 /* Wait for PLL to lock */
62 do {
63 if (readl_relaxed(pll->base) & BM_PLL_LOCK)
64 break;
65 if (time_after(jiffies, timeout))
66 break;
67 usleep_range(50, 500);
68 } while (1);
69
70 return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT;
71}
72
73static int clk_pllv3_prepare(struct clk_hw *hw)
74{
75 struct clk_pllv3 *pll = to_clk_pllv3(hw);
76 u32 val;
77
78 val = readl_relaxed(pll->base);
79 if (pll->powerup_set)
80 val |= BM_PLL_POWER;
81 else
82 val &= ~BM_PLL_POWER;
83 writel_relaxed(val, pll->base);
84
85 return clk_pllv3_wait_lock(pll);
86}
87
88static void clk_pllv3_unprepare(struct clk_hw *hw)
89{
90 struct clk_pllv3 *pll = to_clk_pllv3(hw);
91 u32 val;
92
93 val = readl_relaxed(pll->base);
94 if (pll->powerup_set)
95 val &= ~BM_PLL_POWER;
96 else
97 val |= BM_PLL_POWER;
98 writel_relaxed(val, pll->base);
99}
100
101static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
102 unsigned long parent_rate)
103{
104 struct clk_pllv3 *pll = to_clk_pllv3(hw);
105 u32 div = (readl_relaxed(pll->base) >> pll->div_shift) & pll->div_mask;
106
107 return (div == 1) ? parent_rate * 22 : parent_rate * 20;
108}
109
110static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate,
111 unsigned long *prate)
112{
113 unsigned long parent_rate = *prate;
114
115 return (rate >= parent_rate * 22) ? parent_rate * 22 :
116 parent_rate * 20;
117}
118
119static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate,
120 unsigned long parent_rate)
121{
122 struct clk_pllv3 *pll = to_clk_pllv3(hw);
123 u32 val, div;
124
125 if (rate == parent_rate * 22)
126 div = 1;
127 else if (rate == parent_rate * 20)
128 div = 0;
129 else
130 return -EINVAL;
131
132 val = readl_relaxed(pll->base);
133 val &= ~(pll->div_mask << pll->div_shift);
134 val |= (div << pll->div_shift);
135 writel_relaxed(val, pll->base);
136
137 return clk_pllv3_wait_lock(pll);
138}
139
140static const struct clk_ops clk_pllv3_ops = {
141 .prepare = clk_pllv3_prepare,
142 .unprepare = clk_pllv3_unprepare,
143 .recalc_rate = clk_pllv3_recalc_rate,
144 .round_rate = clk_pllv3_round_rate,
145 .set_rate = clk_pllv3_set_rate,
146};
147
148static unsigned long clk_pllv3_sys_recalc_rate(struct clk_hw *hw,
149 unsigned long parent_rate)
150{
151 struct clk_pllv3 *pll = to_clk_pllv3(hw);
152 u32 div = readl_relaxed(pll->base) & pll->div_mask;
153
154 return parent_rate * div / 2;
155}
156
157static long clk_pllv3_sys_round_rate(struct clk_hw *hw, unsigned long rate,
158 unsigned long *prate)
159{
160 unsigned long parent_rate = *prate;
161 unsigned long min_rate = parent_rate * 54 / 2;
162 unsigned long max_rate = parent_rate * 108 / 2;
163 u32 div;
164
165 if (rate > max_rate)
166 rate = max_rate;
167 else if (rate < min_rate)
168 rate = min_rate;
169 div = rate * 2 / parent_rate;
170
171 return parent_rate * div / 2;
172}
173
174static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate,
175 unsigned long parent_rate)
176{
177 struct clk_pllv3 *pll = to_clk_pllv3(hw);
178 unsigned long min_rate = parent_rate * 54 / 2;
179 unsigned long max_rate = parent_rate * 108 / 2;
180 u32 val, div;
181
182 if (rate < min_rate || rate > max_rate)
183 return -EINVAL;
184
185 div = rate * 2 / parent_rate;
186 val = readl_relaxed(pll->base);
187 val &= ~pll->div_mask;
188 val |= div;
189 writel_relaxed(val, pll->base);
190
191 return clk_pllv3_wait_lock(pll);
192}
193
194static const struct clk_ops clk_pllv3_sys_ops = {
195 .prepare = clk_pllv3_prepare,
196 .unprepare = clk_pllv3_unprepare,
197 .recalc_rate = clk_pllv3_sys_recalc_rate,
198 .round_rate = clk_pllv3_sys_round_rate,
199 .set_rate = clk_pllv3_sys_set_rate,
200};
201
202static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
203 unsigned long parent_rate)
204{
205 struct clk_pllv3 *pll = to_clk_pllv3(hw);
206 u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
207 u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
208 u32 div = readl_relaxed(pll->base) & pll->div_mask;
209
210 return (parent_rate * div) + ((parent_rate / mfd) * mfn);
211}
212
213static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
214 unsigned long *prate)
215{
216 unsigned long parent_rate = *prate;
217 unsigned long min_rate = parent_rate * 27;
218 unsigned long max_rate = parent_rate * 54;
219 u32 div;
220 u32 mfn, mfd = 1000000;
221 u64 temp64;
222
223 if (rate > max_rate)
224 rate = max_rate;
225 else if (rate < min_rate)
226 rate = min_rate;
227
228 div = rate / parent_rate;
229 temp64 = (u64) (rate - div * parent_rate);
230 temp64 *= mfd;
231 do_div(temp64, parent_rate);
232 mfn = temp64;
233
234 return parent_rate * div + parent_rate / mfd * mfn;
235}
236
237static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
238 unsigned long parent_rate)
239{
240 struct clk_pllv3 *pll = to_clk_pllv3(hw);
241 unsigned long min_rate = parent_rate * 27;
242 unsigned long max_rate = parent_rate * 54;
243 u32 val, div;
244 u32 mfn, mfd = 1000000;
245 u64 temp64;
246
247 if (rate < min_rate || rate > max_rate)
248 return -EINVAL;
249
250 div = rate / parent_rate;
251 temp64 = (u64) (rate - div * parent_rate);
252 temp64 *= mfd;
253 do_div(temp64, parent_rate);
254 mfn = temp64;
255
256 val = readl_relaxed(pll->base);
257 val &= ~pll->div_mask;
258 val |= div;
259 writel_relaxed(val, pll->base);
260 writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
261 writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
262
263 return clk_pllv3_wait_lock(pll);
264}
265
266static const struct clk_ops clk_pllv3_av_ops = {
267 .prepare = clk_pllv3_prepare,
268 .unprepare = clk_pllv3_unprepare,
269 .recalc_rate = clk_pllv3_av_recalc_rate,
270 .round_rate = clk_pllv3_av_round_rate,
271 .set_rate = clk_pllv3_av_set_rate,
272};
273
274static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
275 unsigned long parent_rate)
276{
277 return 500000000;
278}
279
280static const struct clk_ops clk_pllv3_enet_ops = {
281 .prepare = clk_pllv3_prepare,
282 .unprepare = clk_pllv3_unprepare,
283 .recalc_rate = clk_pllv3_enet_recalc_rate,
284};
285
286struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
287 const char *parent_name, void __iomem *base,
288 u32 div_mask)
289{
290 struct clk_pllv3 *pll;
291 const struct clk_ops *ops;
292 struct clk *clk;
293 struct clk_init_data init;
294
295 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
296 if (!pll)
297 return ERR_PTR(-ENOMEM);
298
299 pll->powerdown = BM_PLL_POWER;
300
301 switch (type) {
302 case IMX_PLLV3_SYS:
303 ops = &clk_pllv3_sys_ops;
304 break;
305 case IMX_PLLV3_USB_VF610:
306 pll->div_shift = 1;
307 case IMX_PLLV3_USB:
308 ops = &clk_pllv3_ops;
309 pll->powerup_set = true;
310 break;
311 case IMX_PLLV3_AV:
312 ops = &clk_pllv3_av_ops;
313 break;
314 case IMX_PLLV3_ENET_IMX7:
315 pll->powerdown = IMX7_ENET_PLL_POWER;
316 case IMX_PLLV3_ENET:
317 ops = &clk_pllv3_enet_ops;
318 break;
319 default:
320 ops = &clk_pllv3_ops;
321 }
322 pll->base = base;
323 pll->div_mask = div_mask;
324
325 init.name = name;
326 init.ops = ops;
327 init.flags = 0;
328 init.parent_names = &parent_name;
329 init.num_parents = 1;
330
331 pll->hw.init = &init;
332
333 clk = clk_register(NULL, &pll->hw);
334 if (IS_ERR(clk))
335 kfree(pll);
336
337 return clk;
338}
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
new file mode 100644
index 000000000000..bff45ead7389
--- /dev/null
+++ b/drivers/clk/imx/clk-vf610.c
@@ -0,0 +1,416 @@
1/*
2 * Copyright 2012-2013 Freescale Semiconductor, Inc.
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 as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 */
10
11#include <linux/of_address.h>
12#include <linux/clk.h>
13#include <dt-bindings/clock/vf610-clock.h>
14
15#include "clk.h"
16
17#define CCM_CCR (ccm_base + 0x00)
18#define CCM_CSR (ccm_base + 0x04)
19#define CCM_CCSR (ccm_base + 0x08)
20#define CCM_CACRR (ccm_base + 0x0c)
21#define CCM_CSCMR1 (ccm_base + 0x10)
22#define CCM_CSCDR1 (ccm_base + 0x14)
23#define CCM_CSCDR2 (ccm_base + 0x18)
24#define CCM_CSCDR3 (ccm_base + 0x1c)
25#define CCM_CSCMR2 (ccm_base + 0x20)
26#define CCM_CSCDR4 (ccm_base + 0x24)
27#define CCM_CLPCR (ccm_base + 0x2c)
28#define CCM_CISR (ccm_base + 0x30)
29#define CCM_CIMR (ccm_base + 0x34)
30#define CCM_CGPR (ccm_base + 0x3c)
31#define CCM_CCGR0 (ccm_base + 0x40)
32#define CCM_CCGR1 (ccm_base + 0x44)
33#define CCM_CCGR2 (ccm_base + 0x48)
34#define CCM_CCGR3 (ccm_base + 0x4c)
35#define CCM_CCGR4 (ccm_base + 0x50)
36#define CCM_CCGR5 (ccm_base + 0x54)
37#define CCM_CCGR6 (ccm_base + 0x58)
38#define CCM_CCGR7 (ccm_base + 0x5c)
39#define CCM_CCGR8 (ccm_base + 0x60)
40#define CCM_CCGR9 (ccm_base + 0x64)
41#define CCM_CCGR10 (ccm_base + 0x68)
42#define CCM_CCGR11 (ccm_base + 0x6c)
43#define CCM_CMEOR0 (ccm_base + 0x70)
44#define CCM_CMEOR1 (ccm_base + 0x74)
45#define CCM_CMEOR2 (ccm_base + 0x78)
46#define CCM_CMEOR3 (ccm_base + 0x7c)
47#define CCM_CMEOR4 (ccm_base + 0x80)
48#define CCM_CMEOR5 (ccm_base + 0x84)
49#define CCM_CPPDSR (ccm_base + 0x88)
50#define CCM_CCOWR (ccm_base + 0x8c)
51#define CCM_CCPGR0 (ccm_base + 0x90)
52#define CCM_CCPGR1 (ccm_base + 0x94)
53#define CCM_CCPGR2 (ccm_base + 0x98)
54#define CCM_CCPGR3 (ccm_base + 0x9c)
55
56#define CCM_CCGRx_CGn(n) ((n) * 2)
57
58#define PFD_PLL1_BASE (anatop_base + 0x2b0)
59#define PFD_PLL2_BASE (anatop_base + 0x100)
60#define PFD_PLL3_BASE (anatop_base + 0xf0)
61#define PLL1_CTRL (anatop_base + 0x270)
62#define PLL2_CTRL (anatop_base + 0x30)
63#define PLL3_CTRL (anatop_base + 0x10)
64#define PLL4_CTRL (anatop_base + 0x70)
65#define PLL5_CTRL (anatop_base + 0xe0)
66#define PLL6_CTRL (anatop_base + 0xa0)
67#define PLL7_CTRL (anatop_base + 0x20)
68#define ANA_MISC1 (anatop_base + 0x160)
69
70static void __iomem *anatop_base;
71static void __iomem *ccm_base;
72
73/* sources for multiplexer clocks, this is used multiple times */
74static const char *fast_sels[] = { "firc", "fxosc", };
75static const char *slow_sels[] = { "sirc_32k", "sxosc", };
76static const char *pll1_sels[] = { "pll1_sys", "pll1_pfd1", "pll1_pfd2", "pll1_pfd3", "pll1_pfd4", };
77static const char *pll2_sels[] = { "pll2_bus", "pll2_pfd1", "pll2_pfd2", "pll2_pfd3", "pll2_pfd4", };
78static const char *pll_bypass_src_sels[] = { "fast_clk_sel", "lvds1_in", };
79static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
80static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
81static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
82static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
83static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
84static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
85static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
86static const char *sys_sels[] = { "fast_clk_sel", "slow_clk_sel", "pll2_pfd_sel", "pll2_bus", "pll1_pfd_sel", "pll3_usb_otg", };
87static const char *ddr_sels[] = { "pll2_pfd2", "sys_sel", };
88static const char *rmii_sels[] = { "enet_ext", "audio_ext", "enet_50m", "enet_25m", };
89static const char *enet_ts_sels[] = { "enet_ext", "fxosc", "audio_ext", "usb", "enet_ts", "enet_25m", "enet_50m", };
90static const char *esai_sels[] = { "audio_ext", "mlb", "spdif_rx", "pll4_audio_div", };
91static const char *sai_sels[] = { "audio_ext", "mlb", "spdif_rx", "pll4_audio_div", };
92static const char *nfc_sels[] = { "platform_bus", "pll1_pfd1", "pll3_pfd1", "pll3_pfd3", };
93static const char *qspi_sels[] = { "pll3_usb_otg", "pll3_pfd4", "pll2_pfd4", "pll1_pfd4", };
94static const char *esdhc_sels[] = { "pll3_usb_otg", "pll3_pfd3", "pll1_pfd3", "platform_bus", };
95static const char *dcu_sels[] = { "pll1_pfd2", "pll3_usb_otg", };
96static const char *gpu_sels[] = { "pll2_pfd2", "pll3_pfd2", };
97static const char *vadc_sels[] = { "pll6_video_div", "pll3_usb_otg_div", "pll3_usb_otg", };
98/* FTM counter clock source, not module clock */
99static const char *ftm_ext_sels[] = {"sirc_128k", "sxosc", "fxosc_half", "audio_ext", };
100static const char *ftm_fix_sels[] = { "sxosc", "ipg_bus", };
101
102
103static struct clk_div_table pll4_audio_div_table[] = {
104 { .val = 0, .div = 1 },
105 { .val = 1, .div = 2 },
106 { .val = 2, .div = 6 },
107 { .val = 3, .div = 8 },
108 { .val = 4, .div = 10 },
109 { .val = 5, .div = 12 },
110 { .val = 6, .div = 14 },
111 { .val = 7, .div = 16 },
112 { }
113};
114
115static struct clk *clk[VF610_CLK_END];
116static struct clk_onecell_data clk_data;
117
118static unsigned int const clks_init_on[] __initconst = {
119 VF610_CLK_SYS_BUS,
120 VF610_CLK_DDR_SEL,
121 VF610_CLK_DAP,
122};
123
124static struct clk * __init vf610_get_fixed_clock(
125 struct device_node *ccm_node, const char *name)
126{
127 struct clk *clk = of_clk_get_by_name(ccm_node, name);
128
129 /* Backward compatibility if device tree is missing clks assignments */
130 if (IS_ERR(clk))
131 clk = imx_obtain_fixed_clock(name, 0);
132 return clk;
133};
134
135static void __init vf610_clocks_init(struct device_node *ccm_node)
136{
137 struct device_node *np;
138 int i;
139
140 clk[VF610_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
141 clk[VF610_CLK_SIRC_128K] = imx_clk_fixed("sirc_128k", 128000);
142 clk[VF610_CLK_SIRC_32K] = imx_clk_fixed("sirc_32k", 32000);
143 clk[VF610_CLK_FIRC] = imx_clk_fixed("firc", 24000000);
144
145 clk[VF610_CLK_SXOSC] = vf610_get_fixed_clock(ccm_node, "sxosc");
146 clk[VF610_CLK_FXOSC] = vf610_get_fixed_clock(ccm_node, "fxosc");
147 clk[VF610_CLK_AUDIO_EXT] = vf610_get_fixed_clock(ccm_node, "audio_ext");
148 clk[VF610_CLK_ENET_EXT] = vf610_get_fixed_clock(ccm_node, "enet_ext");
149
150 /* Clock source from external clock via LVDs PAD */
151 clk[VF610_CLK_ANACLK1] = vf610_get_fixed_clock(ccm_node, "anaclk1");
152
153 clk[VF610_CLK_FXOSC_HALF] = imx_clk_fixed_factor("fxosc_half", "fxosc", 1, 2);
154
155 np = of_find_compatible_node(NULL, NULL, "fsl,vf610-anatop");
156 anatop_base = of_iomap(np, 0);
157 BUG_ON(!anatop_base);
158
159 np = ccm_node;
160 ccm_base = of_iomap(np, 0);
161 BUG_ON(!ccm_base);
162
163 clk[VF610_CLK_SLOW_CLK_SEL] = imx_clk_mux("slow_clk_sel", CCM_CCSR, 4, 1, slow_sels, ARRAY_SIZE(slow_sels));
164 clk[VF610_CLK_FASK_CLK_SEL] = imx_clk_mux("fast_clk_sel", CCM_CCSR, 5, 1, fast_sels, ARRAY_SIZE(fast_sels));
165
166 clk[VF610_CLK_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", PLL1_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
167 clk[VF610_CLK_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", PLL2_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
168 clk[VF610_CLK_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", PLL3_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
169 clk[VF610_CLK_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", PLL4_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
170 clk[VF610_CLK_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", PLL5_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
171 clk[VF610_CLK_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", PLL6_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
172 clk[VF610_CLK_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", PLL7_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
173
174 clk[VF610_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll1", "pll1_bypass_src", PLL1_CTRL, 0x1);
175 clk[VF610_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", PLL2_CTRL, 0x1);
176 clk[VF610_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll3", "pll3_bypass_src", PLL3_CTRL, 0x2);
177 clk[VF610_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", PLL4_CTRL, 0x7f);
178 clk[VF610_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll5", "pll5_bypass_src", PLL5_CTRL, 0x3);
179 clk[VF610_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_AV, "pll6", "pll6_bypass_src", PLL6_CTRL, 0x7f);
180 clk[VF610_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll7", "pll7_bypass_src", PLL7_CTRL, 0x2);
181
182 clk[VF610_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", PLL1_CTRL, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
183 clk[VF610_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", PLL2_CTRL, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
184 clk[VF610_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", PLL3_CTRL, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
185 clk[VF610_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", PLL4_CTRL, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
186 clk[VF610_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", PLL5_CTRL, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
187 clk[VF610_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", PLL6_CTRL, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
188 clk[VF610_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", PLL7_CTRL, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
189
190 /* Do not bypass PLLs initially */
191 clk_set_parent(clk[VF610_PLL1_BYPASS], clk[VF610_CLK_PLL1]);
192 clk_set_parent(clk[VF610_PLL2_BYPASS], clk[VF610_CLK_PLL2]);
193 clk_set_parent(clk[VF610_PLL3_BYPASS], clk[VF610_CLK_PLL3]);
194 clk_set_parent(clk[VF610_PLL4_BYPASS], clk[VF610_CLK_PLL4]);
195 clk_set_parent(clk[VF610_PLL5_BYPASS], clk[VF610_CLK_PLL5]);
196 clk_set_parent(clk[VF610_PLL6_BYPASS], clk[VF610_CLK_PLL6]);
197 clk_set_parent(clk[VF610_PLL7_BYPASS], clk[VF610_CLK_PLL7]);
198
199 clk[VF610_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", PLL1_CTRL, 13);
200 clk[VF610_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", PLL2_CTRL, 13);
201 clk[VF610_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", PLL3_CTRL, 13);
202 clk[VF610_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", PLL4_CTRL, 13);
203 clk[VF610_CLK_PLL5_ENET] = imx_clk_gate("pll5_enet", "pll5_bypass", PLL5_CTRL, 13);
204 clk[VF610_CLK_PLL6_VIDEO] = imx_clk_gate("pll6_video", "pll6_bypass", PLL6_CTRL, 13);
205 clk[VF610_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", PLL7_CTRL, 13);
206
207 clk[VF610_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", ANA_MISC1, 12, BIT(10));
208
209 clk[VF610_CLK_PLL1_PFD1] = imx_clk_pfd("pll1_pfd1", "pll1_sys", PFD_PLL1_BASE, 0);
210 clk[VF610_CLK_PLL1_PFD2] = imx_clk_pfd("pll1_pfd2", "pll1_sys", PFD_PLL1_BASE, 1);
211 clk[VF610_CLK_PLL1_PFD3] = imx_clk_pfd("pll1_pfd3", "pll1_sys", PFD_PLL1_BASE, 2);
212 clk[VF610_CLK_PLL1_PFD4] = imx_clk_pfd("pll1_pfd4", "pll1_sys", PFD_PLL1_BASE, 3);
213
214 clk[VF610_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_bus", PFD_PLL2_BASE, 0);
215 clk[VF610_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_bus", PFD_PLL2_BASE, 1);
216 clk[VF610_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3", "pll2_bus", PFD_PLL2_BASE, 2);
217 clk[VF610_CLK_PLL2_PFD4] = imx_clk_pfd("pll2_pfd4", "pll2_bus", PFD_PLL2_BASE, 3);
218
219 clk[VF610_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_usb_otg", PFD_PLL3_BASE, 0);
220 clk[VF610_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", PFD_PLL3_BASE, 1);
221 clk[VF610_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", PFD_PLL3_BASE, 2);
222 clk[VF610_CLK_PLL3_PFD4] = imx_clk_pfd("pll3_pfd4", "pll3_usb_otg", PFD_PLL3_BASE, 3);
223
224 clk[VF610_CLK_PLL1_PFD_SEL] = imx_clk_mux("pll1_pfd_sel", CCM_CCSR, 16, 3, pll1_sels, 5);
225 clk[VF610_CLK_PLL2_PFD_SEL] = imx_clk_mux("pll2_pfd_sel", CCM_CCSR, 19, 3, pll2_sels, 5);
226 clk[VF610_CLK_SYS_SEL] = imx_clk_mux("sys_sel", CCM_CCSR, 0, 3, sys_sels, ARRAY_SIZE(sys_sels));
227 clk[VF610_CLK_DDR_SEL] = imx_clk_mux("ddr_sel", CCM_CCSR, 6, 1, ddr_sels, ARRAY_SIZE(ddr_sels));
228 clk[VF610_CLK_SYS_BUS] = imx_clk_divider("sys_bus", "sys_sel", CCM_CACRR, 0, 3);
229 clk[VF610_CLK_PLATFORM_BUS] = imx_clk_divider("platform_bus", "sys_bus", CCM_CACRR, 3, 3);
230 clk[VF610_CLK_IPG_BUS] = imx_clk_divider("ipg_bus", "platform_bus", CCM_CACRR, 11, 2);
231
232 clk[VF610_CLK_PLL3_MAIN_DIV] = imx_clk_divider("pll3_usb_otg_div", "pll3_usb_otg", CCM_CACRR, 20, 1);
233 clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_audio_div", "pll4_audio", 0, CCM_CACRR, 6, 3, 0, pll4_audio_div_table, &imx_ccm_lock);
234 clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_video_div", "pll6_video", CCM_CACRR, 21, 1);
235
236 clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_usb_otg", PLL3_CTRL, 6);
237 clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_usb_host", PLL7_CTRL, 6);
238
239 clk[VF610_CLK_USBC0] = imx_clk_gate2("usbc0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(4));
240 clk[VF610_CLK_USBC1] = imx_clk_gate2("usbc1", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(4));
241
242 clk[VF610_CLK_QSPI0_SEL] = imx_clk_mux("qspi0_sel", CCM_CSCMR1, 22, 2, qspi_sels, 4);
243 clk[VF610_CLK_QSPI0_EN] = imx_clk_gate("qspi0_en", "qspi0_sel", CCM_CSCDR3, 4);
244 clk[VF610_CLK_QSPI0_X4_DIV] = imx_clk_divider("qspi0_x4", "qspi0_en", CCM_CSCDR3, 0, 2);
245 clk[VF610_CLK_QSPI0_X2_DIV] = imx_clk_divider("qspi0_x2", "qspi0_x4", CCM_CSCDR3, 2, 1);
246 clk[VF610_CLK_QSPI0_X1_DIV] = imx_clk_divider("qspi0_x1", "qspi0_x2", CCM_CSCDR3, 3, 1);
247 clk[VF610_CLK_QSPI0] = imx_clk_gate2("qspi0", "qspi0_x1", CCM_CCGR2, CCM_CCGRx_CGn(4));
248
249 clk[VF610_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", CCM_CSCMR1, 24, 2, qspi_sels, 4);
250 clk[VF610_CLK_QSPI1_EN] = imx_clk_gate("qspi1_en", "qspi1_sel", CCM_CSCDR3, 12);
251 clk[VF610_CLK_QSPI1_X4_DIV] = imx_clk_divider("qspi1_x4", "qspi1_en", CCM_CSCDR3, 8, 2);
252 clk[VF610_CLK_QSPI1_X2_DIV] = imx_clk_divider("qspi1_x2", "qspi1_x4", CCM_CSCDR3, 10, 1);
253 clk[VF610_CLK_QSPI1_X1_DIV] = imx_clk_divider("qspi1_x1", "qspi1_x2", CCM_CSCDR3, 11, 1);
254 clk[VF610_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_x1", CCM_CCGR8, CCM_CCGRx_CGn(4));
255
256 clk[VF610_CLK_ENET_50M] = imx_clk_fixed_factor("enet_50m", "pll5_enet", 1, 10);
257 clk[VF610_CLK_ENET_25M] = imx_clk_fixed_factor("enet_25m", "pll5_enet", 1, 20);
258 clk[VF610_CLK_ENET_SEL] = imx_clk_mux("enet_sel", CCM_CSCMR2, 4, 2, rmii_sels, 4);
259 clk[VF610_CLK_ENET_TS_SEL] = imx_clk_mux("enet_ts_sel", CCM_CSCMR2, 0, 3, enet_ts_sels, 7);
260 clk[VF610_CLK_ENET] = imx_clk_gate("enet", "enet_sel", CCM_CSCDR1, 24);
261 clk[VF610_CLK_ENET_TS] = imx_clk_gate("enet_ts", "enet_ts_sel", CCM_CSCDR1, 23);
262 clk[VF610_CLK_ENET0] = imx_clk_gate2("enet0", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(0));
263 clk[VF610_CLK_ENET1] = imx_clk_gate2("enet1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(1));
264
265 clk[VF610_CLK_PIT] = imx_clk_gate2("pit", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(7));
266
267 clk[VF610_CLK_UART0] = imx_clk_gate2("uart0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(7));
268 clk[VF610_CLK_UART1] = imx_clk_gate2("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8));
269 clk[VF610_CLK_UART2] = imx_clk_gate2("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9));
270 clk[VF610_CLK_UART3] = imx_clk_gate2("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10));
271 clk[VF610_CLK_UART4] = imx_clk_gate2("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9));
272 clk[VF610_CLK_UART5] = imx_clk_gate2("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10));
273
274 clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6));
275 clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7));
276 clk[VF610_CLK_I2C2] = imx_clk_gate2("i2c2", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(6));
277 clk[VF610_CLK_I2C3] = imx_clk_gate2("i2c3", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(7));
278
279 clk[VF610_CLK_DSPI0] = imx_clk_gate2("dspi0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(12));
280 clk[VF610_CLK_DSPI1] = imx_clk_gate2("dspi1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(13));
281 clk[VF610_CLK_DSPI2] = imx_clk_gate2("dspi2", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(12));
282 clk[VF610_CLK_DSPI3] = imx_clk_gate2("dspi3", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(13));
283
284 clk[VF610_CLK_WDT] = imx_clk_gate2("wdt", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(14));
285
286 clk[VF610_CLK_ESDHC0_SEL] = imx_clk_mux("esdhc0_sel", CCM_CSCMR1, 16, 2, esdhc_sels, 4);
287 clk[VF610_CLK_ESDHC0_EN] = imx_clk_gate("esdhc0_en", "esdhc0_sel", CCM_CSCDR2, 28);
288 clk[VF610_CLK_ESDHC0_DIV] = imx_clk_divider("esdhc0_div", "esdhc0_en", CCM_CSCDR2, 16, 4);
289 clk[VF610_CLK_ESDHC0] = imx_clk_gate2("eshc0", "esdhc0_div", CCM_CCGR7, CCM_CCGRx_CGn(1));
290
291 clk[VF610_CLK_ESDHC1_SEL] = imx_clk_mux("esdhc1_sel", CCM_CSCMR1, 18, 2, esdhc_sels, 4);
292 clk[VF610_CLK_ESDHC1_EN] = imx_clk_gate("esdhc1_en", "esdhc1_sel", CCM_CSCDR2, 29);
293 clk[VF610_CLK_ESDHC1_DIV] = imx_clk_divider("esdhc1_div", "esdhc1_en", CCM_CSCDR2, 20, 4);
294 clk[VF610_CLK_ESDHC1] = imx_clk_gate2("eshc1", "esdhc1_div", CCM_CCGR7, CCM_CCGRx_CGn(2));
295
296 /*
297 * ftm_ext_clk and ftm_fix_clk are FTM timer counter's
298 * selectable clock sources, both use a common enable bit
299 * in CCM_CSCDR1, selecting "dummy" clock as parent of
300 * "ftm0_ext_fix" make it serve only for enable/disable.
301 */
302 clk[VF610_CLK_FTM0_EXT_SEL] = imx_clk_mux("ftm0_ext_sel", CCM_CSCMR2, 6, 2, ftm_ext_sels, 4);
303 clk[VF610_CLK_FTM0_FIX_SEL] = imx_clk_mux("ftm0_fix_sel", CCM_CSCMR2, 14, 1, ftm_fix_sels, 2);
304 clk[VF610_CLK_FTM0_EXT_FIX_EN] = imx_clk_gate("ftm0_ext_fix_en", "dummy", CCM_CSCDR1, 25);
305 clk[VF610_CLK_FTM1_EXT_SEL] = imx_clk_mux("ftm1_ext_sel", CCM_CSCMR2, 8, 2, ftm_ext_sels, 4);
306 clk[VF610_CLK_FTM1_FIX_SEL] = imx_clk_mux("ftm1_fix_sel", CCM_CSCMR2, 15, 1, ftm_fix_sels, 2);
307 clk[VF610_CLK_FTM1_EXT_FIX_EN] = imx_clk_gate("ftm1_ext_fix_en", "dummy", CCM_CSCDR1, 26);
308 clk[VF610_CLK_FTM2_EXT_SEL] = imx_clk_mux("ftm2_ext_sel", CCM_CSCMR2, 10, 2, ftm_ext_sels, 4);
309 clk[VF610_CLK_FTM2_FIX_SEL] = imx_clk_mux("ftm2_fix_sel", CCM_CSCMR2, 16, 1, ftm_fix_sels, 2);
310 clk[VF610_CLK_FTM2_EXT_FIX_EN] = imx_clk_gate("ftm2_ext_fix_en", "dummy", CCM_CSCDR1, 27);
311 clk[VF610_CLK_FTM3_EXT_SEL] = imx_clk_mux("ftm3_ext_sel", CCM_CSCMR2, 12, 2, ftm_ext_sels, 4);
312 clk[VF610_CLK_FTM3_FIX_SEL] = imx_clk_mux("ftm3_fix_sel", CCM_CSCMR2, 17, 1, ftm_fix_sels, 2);
313 clk[VF610_CLK_FTM3_EXT_FIX_EN] = imx_clk_gate("ftm3_ext_fix_en", "dummy", CCM_CSCDR1, 28);
314
315 /* ftm(n)_clk are FTM module operation clock */
316 clk[VF610_CLK_FTM0] = imx_clk_gate2("ftm0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(8));
317 clk[VF610_CLK_FTM1] = imx_clk_gate2("ftm1", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(9));
318 clk[VF610_CLK_FTM2] = imx_clk_gate2("ftm2", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(8));
319 clk[VF610_CLK_FTM3] = imx_clk_gate2("ftm3", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(9));
320
321 clk[VF610_CLK_DCU0_SEL] = imx_clk_mux("dcu0_sel", CCM_CSCMR1, 28, 1, dcu_sels, 2);
322 clk[VF610_CLK_DCU0_EN] = imx_clk_gate("dcu0_en", "dcu0_sel", CCM_CSCDR3, 19);
323 clk[VF610_CLK_DCU0_DIV] = imx_clk_divider("dcu0_div", "dcu0_en", CCM_CSCDR3, 16, 3);
324 clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "dcu0_div", CCM_CCGR3, CCM_CCGRx_CGn(8));
325 clk[VF610_CLK_DCU1_SEL] = imx_clk_mux("dcu1_sel", CCM_CSCMR1, 29, 1, dcu_sels, 2);
326 clk[VF610_CLK_DCU1_EN] = imx_clk_gate("dcu1_en", "dcu1_sel", CCM_CSCDR3, 23);
327 clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", CCM_CSCDR3, 20, 3);
328 clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "dcu1_div", CCM_CCGR9, CCM_CCGRx_CGn(8));
329
330 clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, esai_sels, 4);
331 clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", CCM_CSCDR2, 30);
332 clk[VF610_CLK_ESAI_DIV] = imx_clk_divider("esai_div", "esai_en", CCM_CSCDR2, 24, 4);
333 clk[VF610_CLK_ESAI] = imx_clk_gate2("esai", "esai_div", CCM_CCGR4, CCM_CCGRx_CGn(2));
334
335 clk[VF610_CLK_SAI0_SEL] = imx_clk_mux("sai0_sel", CCM_CSCMR1, 0, 2, sai_sels, 4);
336 clk[VF610_CLK_SAI0_EN] = imx_clk_gate("sai0_en", "sai0_sel", CCM_CSCDR1, 16);
337 clk[VF610_CLK_SAI0_DIV] = imx_clk_divider("sai0_div", "sai0_en", CCM_CSCDR1, 0, 4);
338 clk[VF610_CLK_SAI0] = imx_clk_gate2("sai0", "sai0_div", CCM_CCGR0, CCM_CCGRx_CGn(15));
339
340 clk[VF610_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", CCM_CSCMR1, 2, 2, sai_sels, 4);
341 clk[VF610_CLK_SAI1_EN] = imx_clk_gate("sai1_en", "sai1_sel", CCM_CSCDR1, 17);
342 clk[VF610_CLK_SAI1_DIV] = imx_clk_divider("sai1_div", "sai1_en", CCM_CSCDR1, 4, 4);
343 clk[VF610_CLK_SAI1] = imx_clk_gate2("sai1", "sai1_div", CCM_CCGR1, CCM_CCGRx_CGn(0));
344
345 clk[VF610_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", CCM_CSCMR1, 4, 2, sai_sels, 4);
346 clk[VF610_CLK_SAI2_EN] = imx_clk_gate("sai2_en", "sai2_sel", CCM_CSCDR1, 18);
347 clk[VF610_CLK_SAI2_DIV] = imx_clk_divider("sai2_div", "sai2_en", CCM_CSCDR1, 8, 4);
348 clk[VF610_CLK_SAI2] = imx_clk_gate2("sai2", "sai2_div", CCM_CCGR1, CCM_CCGRx_CGn(1));
349
350 clk[VF610_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", CCM_CSCMR1, 6, 2, sai_sels, 4);
351 clk[VF610_CLK_SAI3_EN] = imx_clk_gate("sai3_en", "sai3_sel", CCM_CSCDR1, 19);
352 clk[VF610_CLK_SAI3_DIV] = imx_clk_divider("sai3_div", "sai3_en", CCM_CSCDR1, 12, 4);
353 clk[VF610_CLK_SAI3] = imx_clk_gate2("sai3", "sai3_div", CCM_CCGR1, CCM_CCGRx_CGn(2));
354
355 clk[VF610_CLK_NFC_SEL] = imx_clk_mux("nfc_sel", CCM_CSCMR1, 12, 2, nfc_sels, 4);
356 clk[VF610_CLK_NFC_EN] = imx_clk_gate("nfc_en", "nfc_sel", CCM_CSCDR2, 9);
357 clk[VF610_CLK_NFC_PRE_DIV] = imx_clk_divider("nfc_pre_div", "nfc_en", CCM_CSCDR3, 13, 3);
358 clk[VF610_CLK_NFC_FRAC_DIV] = imx_clk_divider("nfc_frac_div", "nfc_pre_div", CCM_CSCDR2, 4, 4);
359 clk[VF610_CLK_NFC] = imx_clk_gate2("nfc", "nfc_frac_div", CCM_CCGR10, CCM_CCGRx_CGn(0));
360
361 clk[VF610_CLK_GPU_SEL] = imx_clk_mux("gpu_sel", CCM_CSCMR1, 14, 1, gpu_sels, 2);
362 clk[VF610_CLK_GPU_EN] = imx_clk_gate("gpu_en", "gpu_sel", CCM_CSCDR2, 10);
363 clk[VF610_CLK_GPU2D] = imx_clk_gate2("gpu", "gpu_en", CCM_CCGR8, CCM_CCGRx_CGn(15));
364
365 clk[VF610_CLK_VADC_SEL] = imx_clk_mux("vadc_sel", CCM_CSCMR1, 8, 2, vadc_sels, 3);
366 clk[VF610_CLK_VADC_EN] = imx_clk_gate("vadc_en", "vadc_sel", CCM_CSCDR1, 22);
367 clk[VF610_CLK_VADC_DIV] = imx_clk_divider("vadc_div", "vadc_en", CCM_CSCDR1, 20, 2);
368 clk[VF610_CLK_VADC_DIV_HALF] = imx_clk_fixed_factor("vadc_div_half", "vadc_div", 1, 2);
369 clk[VF610_CLK_VADC] = imx_clk_gate2("vadc", "vadc_div", CCM_CCGR8, CCM_CCGRx_CGn(7));
370
371 clk[VF610_CLK_ADC0] = imx_clk_gate2("adc0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(11));
372 clk[VF610_CLK_ADC1] = imx_clk_gate2("adc1", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(11));
373 clk[VF610_CLK_DAC0] = imx_clk_gate2("dac0", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(12));
374 clk[VF610_CLK_DAC1] = imx_clk_gate2("dac1", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(13));
375
376 clk[VF610_CLK_ASRC] = imx_clk_gate2("asrc", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(1));
377
378 clk[VF610_CLK_FLEXCAN0_EN] = imx_clk_gate("flexcan0_en", "ipg_bus", CCM_CSCDR2, 11);
379 clk[VF610_CLK_FLEXCAN0] = imx_clk_gate2("flexcan0", "flexcan0_en", CCM_CCGR0, CCM_CCGRx_CGn(0));
380 clk[VF610_CLK_FLEXCAN1_EN] = imx_clk_gate("flexcan1_en", "ipg_bus", CCM_CSCDR2, 12);
381 clk[VF610_CLK_FLEXCAN1] = imx_clk_gate2("flexcan1", "flexcan1_en", CCM_CCGR9, CCM_CCGRx_CGn(4));
382
383 clk[VF610_CLK_DMAMUX0] = imx_clk_gate2("dmamux0", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(4));
384 clk[VF610_CLK_DMAMUX1] = imx_clk_gate2("dmamux1", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(5));
385 clk[VF610_CLK_DMAMUX2] = imx_clk_gate2("dmamux2", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(1));
386 clk[VF610_CLK_DMAMUX3] = imx_clk_gate2("dmamux3", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(2));
387
388 clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7));
389 clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24);
390
391 imx_check_clocks(clk, ARRAY_SIZE(clk));
392
393 clk_set_parent(clk[VF610_CLK_QSPI0_SEL], clk[VF610_CLK_PLL1_PFD4]);
394 clk_set_rate(clk[VF610_CLK_QSPI0_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_SEL]) / 2);
395 clk_set_rate(clk[VF610_CLK_QSPI0_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X4_DIV]) / 2);
396 clk_set_rate(clk[VF610_CLK_QSPI0_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X2_DIV]) / 2);
397
398 clk_set_parent(clk[VF610_CLK_QSPI1_SEL], clk[VF610_CLK_PLL1_PFD4]);
399 clk_set_rate(clk[VF610_CLK_QSPI1_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_SEL]) / 2);
400 clk_set_rate(clk[VF610_CLK_QSPI1_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X4_DIV]) / 2);
401 clk_set_rate(clk[VF610_CLK_QSPI1_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X2_DIV]) / 2);
402
403 clk_set_parent(clk[VF610_CLK_SAI0_SEL], clk[VF610_CLK_AUDIO_EXT]);
404 clk_set_parent(clk[VF610_CLK_SAI1_SEL], clk[VF610_CLK_AUDIO_EXT]);
405 clk_set_parent(clk[VF610_CLK_SAI2_SEL], clk[VF610_CLK_AUDIO_EXT]);
406 clk_set_parent(clk[VF610_CLK_SAI3_SEL], clk[VF610_CLK_AUDIO_EXT]);
407
408 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
409 clk_prepare_enable(clk[clks_init_on[i]]);
410
411 /* Add the clocks to provider list */
412 clk_data.clks = clk;
413 clk_data.clk_num = ARRAY_SIZE(clk);
414 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
415}
416CLK_OF_DECLARE(vf610, "fsl,vf610-ccm", vf610_clocks_init);
diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
new file mode 100644
index 000000000000..df12b5307175
--- /dev/null
+++ b/drivers/clk/imx/clk.c
@@ -0,0 +1,75 @@
1#include <linux/clk.h>
2#include <linux/err.h>
3#include <linux/of.h>
4#include <linux/slab.h>
5#include <linux/spinlock.h>
6#include "clk.h"
7
8DEFINE_SPINLOCK(imx_ccm_lock);
9
10void __init imx_check_clocks(struct clk *clks[], unsigned int count)
11{
12 unsigned i;
13
14 for (i = 0; i < count; i++)
15 if (IS_ERR(clks[i]))
16 pr_err("i.MX clk %u: register failed with %ld\n",
17 i, PTR_ERR(clks[i]));
18}
19
20static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name)
21{
22 struct of_phandle_args phandle;
23 struct clk *clk = ERR_PTR(-ENODEV);
24 char *path;
25
26 path = kasprintf(GFP_KERNEL, "/clocks/%s", name);
27 if (!path)
28 return ERR_PTR(-ENOMEM);
29
30 phandle.np = of_find_node_by_path(path);
31 kfree(path);
32
33 if (phandle.np) {
34 clk = of_clk_get_from_provider(&phandle);
35 of_node_put(phandle.np);
36 }
37 return clk;
38}
39
40struct clk * __init imx_obtain_fixed_clock(
41 const char *name, unsigned long rate)
42{
43 struct clk *clk;
44
45 clk = imx_obtain_fixed_clock_from_dt(name);
46 if (IS_ERR(clk))
47 clk = imx_clk_fixed(name, rate);
48 return clk;
49}
50
51/*
52 * This fixups the register CCM_CSCMR1 write value.
53 * The write/read/divider values of the aclk_podf field
54 * of that register have the relationship described by
55 * the following table:
56 *
57 * write value read value divider
58 * 3b'000 3b'110 7
59 * 3b'001 3b'111 8
60 * 3b'010 3b'100 5
61 * 3b'011 3b'101 6
62 * 3b'100 3b'010 3
63 * 3b'101 3b'011 4
64 * 3b'110 3b'000 1
65 * 3b'111 3b'001 2(default)
66 *
67 * That's why we do the xor operation below.
68 */
69#define CSCMR1_FIXUP 0x00600000
70
71void imx_cscmr1_fixup(u32 *val)
72{
73 *val ^= CSCMR1_FIXUP;
74 return;
75}
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
new file mode 100644
index 000000000000..1049b0c7d818
--- /dev/null
+++ b/drivers/clk/imx/clk.h
@@ -0,0 +1,149 @@
1#ifndef __MACH_IMX_CLK_H
2#define __MACH_IMX_CLK_H
3
4#include <linux/spinlock.h>
5#include <linux/clk-provider.h>
6
7extern spinlock_t imx_ccm_lock;
8
9void imx_check_clocks(struct clk *clks[], unsigned int count);
10
11extern void imx_cscmr1_fixup(u32 *val);
12
13enum imx_pllv1_type {
14 IMX_PLLV1_IMX1,
15 IMX_PLLV1_IMX21,
16 IMX_PLLV1_IMX25,
17 IMX_PLLV1_IMX27,
18 IMX_PLLV1_IMX31,
19 IMX_PLLV1_IMX35,
20};
21
22struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
23 const char *parent, void __iomem *base);
24
25struct clk *imx_clk_pllv2(const char *name, const char *parent,
26 void __iomem *base);
27
28enum imx_pllv3_type {
29 IMX_PLLV3_GENERIC,
30 IMX_PLLV3_SYS,
31 IMX_PLLV3_USB,
32 IMX_PLLV3_USB_VF610,
33 IMX_PLLV3_AV,
34 IMX_PLLV3_ENET,
35 IMX_PLLV3_ENET_IMX7,
36};
37
38struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
39 const char *parent_name, void __iomem *base, u32 div_mask);
40
41struct clk *clk_register_gate2(struct device *dev, const char *name,
42 const char *parent_name, unsigned long flags,
43 void __iomem *reg, u8 bit_idx,
44 u8 clk_gate_flags, spinlock_t *lock,
45 unsigned int *share_count);
46
47struct clk * imx_obtain_fixed_clock(
48 const char *name, unsigned long rate);
49
50struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
51 void __iomem *reg, u8 shift, u32 exclusive_mask);
52
53static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
54 void __iomem *reg, u8 shift)
55{
56 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
57 shift, 0, &imx_ccm_lock, NULL);
58}
59
60static inline struct clk *imx_clk_gate2_shared(const char *name,
61 const char *parent, void __iomem *reg, u8 shift,
62 unsigned int *share_count)
63{
64 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
65 shift, 0, &imx_ccm_lock, share_count);
66}
67
68struct clk *imx_clk_pfd(const char *name, const char *parent_name,
69 void __iomem *reg, u8 idx);
70
71struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
72 void __iomem *reg, u8 shift, u8 width,
73 void __iomem *busy_reg, u8 busy_shift);
74
75struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
76 u8 width, void __iomem *busy_reg, u8 busy_shift,
77 const char **parent_names, int num_parents);
78
79struct clk *imx_clk_fixup_divider(const char *name, const char *parent,
80 void __iomem *reg, u8 shift, u8 width,
81 void (*fixup)(u32 *val));
82
83struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
84 u8 shift, u8 width, const char **parents,
85 int num_parents, void (*fixup)(u32 *val));
86
87static inline struct clk *imx_clk_fixed(const char *name, int rate)
88{
89 return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
90}
91
92static inline struct clk *imx_clk_divider(const char *name, const char *parent,
93 void __iomem *reg, u8 shift, u8 width)
94{
95 return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
96 reg, shift, width, 0, &imx_ccm_lock);
97}
98
99static inline struct clk *imx_clk_divider_flags(const char *name,
100 const char *parent, void __iomem *reg, u8 shift, u8 width,
101 unsigned long flags)
102{
103 return clk_register_divider(NULL, name, parent, flags,
104 reg, shift, width, 0, &imx_ccm_lock);
105}
106
107static inline struct clk *imx_clk_gate(const char *name, const char *parent,
108 void __iomem *reg, u8 shift)
109{
110 return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
111 shift, 0, &imx_ccm_lock);
112}
113
114static inline struct clk *imx_clk_gate_dis(const char *name, const char *parent,
115 void __iomem *reg, u8 shift)
116{
117 return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
118 shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
119}
120
121static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
122 u8 shift, u8 width, const char **parents, int num_parents)
123{
124 return clk_register_mux(NULL, name, parents, num_parents,
125 CLK_SET_RATE_NO_REPARENT, reg, shift,
126 width, 0, &imx_ccm_lock);
127}
128
129static inline struct clk *imx_clk_mux_flags(const char *name,
130 void __iomem *reg, u8 shift, u8 width, const char **parents,
131 int num_parents, unsigned long flags)
132{
133 return clk_register_mux(NULL, name, parents, num_parents,
134 flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0,
135 &imx_ccm_lock);
136}
137
138static inline struct clk *imx_clk_fixed_factor(const char *name,
139 const char *parent, unsigned int mult, unsigned int div)
140{
141 return clk_register_fixed_factor(NULL, name, parent,
142 CLK_SET_RATE_PARENT, mult, div);
143}
144
145struct clk *imx_clk_cpu(const char *name, const char *parent_name,
146 struct clk *div, struct clk *mux, struct clk *pll,
147 struct clk *step);
148
149#endif