Commit 8f8f484bf355e546c62c47b8a8c8d19b28787798

Authored by Prashant Gaikwad
Committed by Stephen Warren
1 parent 9598566721

clk: tegra: add Tegra specific clocks

Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.

Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>

Showing 11 changed files with 2126 additions and 0 deletions Inline Diff

drivers/clk/Makefile
1 # common clock types 1 # common clock types
2 obj-$(CONFIG_HAVE_CLK) += clk-devres.o 2 obj-$(CONFIG_HAVE_CLK) += clk-devres.o
3 obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o 3 obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
4 obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \ 4 obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \
5 clk-mux.o clk-divider.o clk-fixed-factor.o 5 clk-mux.o clk-divider.o clk-fixed-factor.o
6 # SoCs specific 6 # SoCs specific
7 obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o 7 obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
8 obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o 8 obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
9 obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o 9 obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
10 obj-$(CONFIG_ARCH_MXS) += mxs/ 10 obj-$(CONFIG_ARCH_MXS) += mxs/
11 obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ 11 obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
12 obj-$(CONFIG_PLAT_SPEAR) += spear/ 12 obj-$(CONFIG_PLAT_SPEAR) += spear/
13 obj-$(CONFIG_ARCH_U300) += clk-u300.o 13 obj-$(CONFIG_ARCH_U300) += clk-u300.o
14 obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ 14 obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
15 obj-$(CONFIG_ARCH_PRIMA2) += clk-prima2.o 15 obj-$(CONFIG_ARCH_PRIMA2) += clk-prima2.o
16 obj-$(CONFIG_PLAT_ORION) += mvebu/ 16 obj-$(CONFIG_PLAT_ORION) += mvebu/
17 ifeq ($(CONFIG_COMMON_CLK), y) 17 ifeq ($(CONFIG_COMMON_CLK), y)
18 obj-$(CONFIG_ARCH_MMP) += mmp/ 18 obj-$(CONFIG_ARCH_MMP) += mmp/
19 endif 19 endif
20 obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o 20 obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
21 obj-$(CONFIG_ARCH_U8500) += ux500/ 21 obj-$(CONFIG_ARCH_U8500) += ux500/
22 obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o 22 obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
23 obj-$(CONFIG_ARCH_SUNXI) += clk-sunxi.o 23 obj-$(CONFIG_ARCH_SUNXI) += clk-sunxi.o
24 obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o 24 obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o
25 obj-$(CONFIG_ARCH_TEGRA) += tegra/
25 26
26 # Chip specific 27 # Chip specific
27 obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o 28 obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
28 obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o 29 obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
29 obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o 30 obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
30 31
drivers/clk/tegra/Makefile
File was created 1 obj-y += clk.o
2 obj-y += clk-audio-sync.o
3 obj-y += clk-divider.o
4 obj-y += clk-periph.o
5 obj-y += clk-periph-gate.o
6 obj-y += clk-pll.o
7 obj-y += clk-pll-out.o
8 obj-y += clk-super.o
9
drivers/clk/tegra/clk-audio-sync.c
File was created 1 /*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <linux/clk-provider.h>
18 #include <linux/slab.h>
19 #include <linux/err.h>
20
21 #include "clk.h"
22
23 static unsigned long clk_sync_source_recalc_rate(struct clk_hw *hw,
24 unsigned long parent_rate)
25 {
26 struct tegra_clk_sync_source *sync = to_clk_sync_source(hw);
27
28 return sync->rate;
29 }
30
31 static long clk_sync_source_round_rate(struct clk_hw *hw, unsigned long rate,
32 unsigned long *prate)
33 {
34 struct tegra_clk_sync_source *sync = to_clk_sync_source(hw);
35
36 if (rate > sync->max_rate)
37 return -EINVAL;
38 else
39 return rate;
40 }
41
42 static int clk_sync_source_set_rate(struct clk_hw *hw, unsigned long rate,
43 unsigned long parent_rate)
44 {
45 struct tegra_clk_sync_source *sync = to_clk_sync_source(hw);
46
47 sync->rate = rate;
48 return 0;
49 }
50
51 const struct clk_ops tegra_clk_sync_source_ops = {
52 .round_rate = clk_sync_source_round_rate,
53 .set_rate = clk_sync_source_set_rate,
54 .recalc_rate = clk_sync_source_recalc_rate,
55 };
56
57 struct clk *tegra_clk_register_sync_source(const char *name,
58 unsigned long rate, unsigned long max_rate)
59 {
60 struct tegra_clk_sync_source *sync;
61 struct clk_init_data init;
62 struct clk *clk;
63
64 sync = kzalloc(sizeof(*sync), GFP_KERNEL);
65 if (!sync) {
66 pr_err("%s: could not allocate sync source clk\n", __func__);
67 return ERR_PTR(-ENOMEM);
68 }
69
70 sync->rate = rate;
71 sync->max_rate = max_rate;
72
73 init.ops = &tegra_clk_sync_source_ops;
74 init.name = name;
75 init.flags = CLK_IS_ROOT;
76 init.parent_names = NULL;
77 init.num_parents = 0;
78
79 /* Data in .init is copied by clk_register(), so stack variable OK */
80 sync->hw.init = &init;
81
82 clk = clk_register(NULL, &sync->hw);
83 if (IS_ERR(clk))
84 kfree(sync);
85
86 return clk;
87 }
88
drivers/clk/tegra/clk-divider.c
File was created 1 /*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <linux/kernel.h>
18 #include <linux/io.h>
19 #include <linux/err.h>
20 #include <linux/slab.h>
21 #include <linux/clk-provider.h>
22 #include <linux/clk.h>
23
24 #include "clk.h"
25
26 #define pll_out_override(p) (BIT((p->shift - 6)))
27 #define div_mask(d) ((1 << (d->width)) - 1)
28 #define get_mul(d) (1 << d->frac_width)
29 #define get_max_div(d) div_mask(d)
30
31 #define PERIPH_CLK_UART_DIV_ENB BIT(24)
32
33 static int get_div(struct tegra_clk_frac_div *divider, unsigned long rate,
34 unsigned long parent_rate)
35 {
36 s64 divider_ux1 = parent_rate;
37 u8 flags = divider->flags;
38 int mul;
39
40 if (!rate)
41 return 0;
42
43 mul = get_mul(divider);
44
45 if (!(flags & TEGRA_DIVIDER_INT))
46 divider_ux1 *= mul;
47
48 if (flags & TEGRA_DIVIDER_ROUND_UP)
49 divider_ux1 += rate - 1;
50
51 do_div(divider_ux1, rate);
52
53 if (flags & TEGRA_DIVIDER_INT)
54 divider_ux1 *= mul;
55
56 divider_ux1 -= mul;
57
58 if (divider_ux1 < 0)
59 return 0;
60
61 if (divider_ux1 > get_max_div(divider))
62 return -EINVAL;
63
64 return divider_ux1;
65 }
66
67 static unsigned long clk_frac_div_recalc_rate(struct clk_hw *hw,
68 unsigned long parent_rate)
69 {
70 struct tegra_clk_frac_div *divider = to_clk_frac_div(hw);
71 u32 reg;
72 int div, mul;
73 u64 rate = parent_rate;
74
75 reg = readl_relaxed(divider->reg) >> divider->shift;
76 div = reg & div_mask(divider);
77
78 mul = get_mul(divider);
79 div += mul;
80
81 rate *= mul;
82 rate += div - 1;
83 do_div(rate, div);
84
85 return rate;
86 }
87
88 static long clk_frac_div_round_rate(struct clk_hw *hw, unsigned long rate,
89 unsigned long *prate)
90 {
91 struct tegra_clk_frac_div *divider = to_clk_frac_div(hw);
92 int div, mul;
93 unsigned long output_rate = *prate;
94
95 if (!rate)
96 return output_rate;
97
98 div = get_div(divider, rate, output_rate);
99 if (div < 0)
100 return *prate;
101
102 mul = get_mul(divider);
103
104 return DIV_ROUND_UP(output_rate * mul, div + mul);
105 }
106
107 static int clk_frac_div_set_rate(struct clk_hw *hw, unsigned long rate,
108 unsigned long parent_rate)
109 {
110 struct tegra_clk_frac_div *divider = to_clk_frac_div(hw);
111 int div;
112 unsigned long flags = 0;
113 u32 val;
114
115 div = get_div(divider, rate, parent_rate);
116 if (div < 0)
117 return div;
118
119 if (divider->lock)
120 spin_lock_irqsave(divider->lock, flags);
121
122 val = readl_relaxed(divider->reg);
123 val &= ~(div_mask(divider) << divider->shift);
124 val |= div << divider->shift;
125
126 if (divider->flags & TEGRA_DIVIDER_UART) {
127 if (div)
128 val |= PERIPH_CLK_UART_DIV_ENB;
129 else
130 val &= ~PERIPH_CLK_UART_DIV_ENB;
131 }
132
133 if (divider->flags & TEGRA_DIVIDER_FIXED)
134 val |= pll_out_override(divider);
135
136 writel_relaxed(val, divider->reg);
137
138 if (divider->lock)
139 spin_unlock_irqrestore(divider->lock, flags);
140
141 return 0;
142 }
143
144 const struct clk_ops tegra_clk_frac_div_ops = {
145 .recalc_rate = clk_frac_div_recalc_rate,
146 .set_rate = clk_frac_div_set_rate,
147 .round_rate = clk_frac_div_round_rate,
148 };
149
150 struct clk *tegra_clk_register_divider(const char *name,
151 const char *parent_name, void __iomem *reg,
152 unsigned long flags, u8 clk_divider_flags, u8 shift, u8 width,
153 u8 frac_width, spinlock_t *lock)
154 {
155 struct tegra_clk_frac_div *divider;
156 struct clk *clk;
157 struct clk_init_data init;
158
159 divider = kzalloc(sizeof(*divider), GFP_KERNEL);
160 if (!divider) {
161 pr_err("%s: could not allocate fractional divider clk\n",
162 __func__);
163 return ERR_PTR(-ENOMEM);
164 }
165
166 init.name = name;
167 init.ops = &tegra_clk_frac_div_ops;
168 init.flags = flags;
169 init.parent_names = parent_name ? &parent_name : NULL;
170 init.num_parents = parent_name ? 1 : 0;
171
172 divider->reg = reg;
173 divider->shift = shift;
174 divider->width = width;
175 divider->frac_width = frac_width;
176 divider->lock = lock;
177 divider->flags = clk_divider_flags;
178
179 /* Data in .init is copied by clk_register(), so stack variable OK */
180 divider->hw.init = &init;
181
182 clk = clk_register(NULL, &divider->hw);
183 if (IS_ERR(clk))
184 kfree(divider);
185
186 return clk;
187 }
188
drivers/clk/tegra/clk-periph-gate.c
File was created 1 /*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <linux/clk.h>
18 #include <linux/clk-provider.h>
19 #include <linux/slab.h>
20 #include <linux/io.h>
21 #include <linux/delay.h>
22 #include <linux/err.h>
23 #include <linux/tegra-soc.h>
24
25 #include "clk.h"
26
27 static DEFINE_SPINLOCK(periph_ref_lock);
28
29 /* Macros to assist peripheral gate clock */
30 #define read_enb(gate) \
31 readl_relaxed(gate->clk_base + (gate->regs->enb_reg))
32 #define write_enb_set(val, gate) \
33 writel_relaxed(val, gate->clk_base + (gate->regs->enb_set_reg))
34 #define write_enb_clr(val, gate) \
35 writel_relaxed(val, gate->clk_base + (gate->regs->enb_clr_reg))
36
37 #define read_rst(gate) \
38 readl_relaxed(gate->clk_base + (gate->regs->rst_reg))
39 #define write_rst_set(val, gate) \
40 writel_relaxed(val, gate->clk_base + (gate->regs->rst_set_reg))
41 #define write_rst_clr(val, gate) \
42 writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg))
43
44 #define periph_clk_to_bit(periph) (1 << (gate->clk_num % 32))
45
46 /* Peripheral gate clock ops */
47 static int clk_periph_is_enabled(struct clk_hw *hw)
48 {
49 struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw);
50 int state = 1;
51
52 if (!(read_enb(gate) & periph_clk_to_bit(gate)))
53 state = 0;
54
55 if (!(gate->flags & TEGRA_PERIPH_NO_RESET))
56 if (read_rst(gate) & periph_clk_to_bit(gate))
57 state = 0;
58
59 return state;
60 }
61
62 static int clk_periph_enable(struct clk_hw *hw)
63 {
64 struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw);
65 unsigned long flags = 0;
66
67 spin_lock_irqsave(&periph_ref_lock, flags);
68
69 gate->enable_refcnt[gate->clk_num]++;
70 if (gate->enable_refcnt[gate->clk_num] > 1) {
71 spin_unlock_irqrestore(&periph_ref_lock, flags);
72 return 0;
73 }
74
75 write_enb_set(periph_clk_to_bit(gate), gate);
76 udelay(2);
77
78 if (!(gate->flags & TEGRA_PERIPH_NO_RESET) &&
79 !(gate->flags & TEGRA_PERIPH_MANUAL_RESET)) {
80 if (read_rst(gate) & periph_clk_to_bit(gate)) {
81 udelay(5); /* reset propogation delay */
82 write_rst_clr(periph_clk_to_bit(gate), gate);
83 }
84 }
85
86 spin_unlock_irqrestore(&periph_ref_lock, flags);
87
88 return 0;
89 }
90
91 static void clk_periph_disable(struct clk_hw *hw)
92 {
93 struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw);
94 unsigned long flags = 0;
95
96 spin_lock_irqsave(&periph_ref_lock, flags);
97
98 gate->enable_refcnt[gate->clk_num]--;
99 if (gate->enable_refcnt[gate->clk_num] > 0) {
100 spin_unlock_irqrestore(&periph_ref_lock, flags);
101 return;
102 }
103
104 /*
105 * If peripheral is in the APB bus then read the APB bus to
106 * flush the write operation in apb bus. This will avoid the
107 * peripheral access after disabling clock
108 */
109 if (gate->flags & TEGRA_PERIPH_ON_APB)
110 tegra_read_chipid();
111
112 write_enb_clr(periph_clk_to_bit(gate), gate);
113
114 spin_unlock_irqrestore(&periph_ref_lock, flags);
115 }
116
117 void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert)
118 {
119 if (gate->flags & TEGRA_PERIPH_NO_RESET)
120 return;
121
122 if (assert) {
123 /*
124 * If peripheral is in the APB bus then read the APB bus to
125 * flush the write operation in apb bus. This will avoid the
126 * peripheral access after disabling clock
127 */
128 if (gate->flags & TEGRA_PERIPH_ON_APB)
129 tegra_read_chipid();
130
131 write_rst_set(periph_clk_to_bit(gate), gate);
132 } else {
133 write_rst_clr(periph_clk_to_bit(gate), gate);
134 }
135 }
136
137 const struct clk_ops tegra_clk_periph_gate_ops = {
138 .is_enabled = clk_periph_is_enabled,
139 .enable = clk_periph_enable,
140 .disable = clk_periph_disable,
141 };
142
143 struct clk *tegra_clk_register_periph_gate(const char *name,
144 const char *parent_name, u8 gate_flags, void __iomem *clk_base,
145 unsigned long flags, int clk_num,
146 struct tegra_clk_periph_regs *pregs, int *enable_refcnt)
147 {
148 struct tegra_clk_periph_gate *gate;
149 struct clk *clk;
150 struct clk_init_data init;
151
152 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
153 if (!gate) {
154 pr_err("%s: could not allocate periph gate clk\n", __func__);
155 return ERR_PTR(-ENOMEM);
156 }
157
158 init.name = name;
159 init.flags = flags;
160 init.parent_names = parent_name ? &parent_name : NULL;
161 init.num_parents = parent_name ? 1 : 0;
162 init.ops = &tegra_clk_periph_gate_ops;
163
164 gate->magic = TEGRA_CLK_PERIPH_GATE_MAGIC;
165 gate->clk_base = clk_base;
166 gate->clk_num = clk_num;
167 gate->flags = gate_flags;
168 gate->enable_refcnt = enable_refcnt;
169 gate->regs = pregs;
170
171 /* Data in .init is copied by clk_register(), so stack variable OK */
172 gate->hw.init = &init;
173
174 clk = clk_register(NULL, &gate->hw);
175 if (IS_ERR(clk))
176 kfree(gate);
177
178 return clk;
179 }
180
drivers/clk/tegra/clk-periph.c
File was created 1 /*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <linux/clk.h>
18 #include <linux/clk-provider.h>
19 #include <linux/slab.h>
20 #include <linux/err.h>
21
22 #include "clk.h"
23
24 static u8 clk_periph_get_parent(struct clk_hw *hw)
25 {
26 struct tegra_clk_periph *periph = to_clk_periph(hw);
27 const struct clk_ops *mux_ops = periph->mux_ops;
28 struct clk_hw *mux_hw = &periph->mux.hw;
29
30 mux_hw->clk = hw->clk;
31
32 return mux_ops->get_parent(mux_hw);
33 }
34
35 static int clk_periph_set_parent(struct clk_hw *hw, u8 index)
36 {
37 struct tegra_clk_periph *periph = to_clk_periph(hw);
38 const struct clk_ops *mux_ops = periph->mux_ops;
39 struct clk_hw *mux_hw = &periph->mux.hw;
40
41 mux_hw->clk = hw->clk;
42
43 return mux_ops->set_parent(mux_hw, index);
44 }
45
46 static unsigned long clk_periph_recalc_rate(struct clk_hw *hw,
47 unsigned long parent_rate)
48 {
49 struct tegra_clk_periph *periph = to_clk_periph(hw);
50 const struct clk_ops *div_ops = periph->div_ops;
51 struct clk_hw *div_hw = &periph->divider.hw;
52
53 div_hw->clk = hw->clk;
54
55 return div_ops->recalc_rate(div_hw, parent_rate);
56 }
57
58 static long clk_periph_round_rate(struct clk_hw *hw, unsigned long rate,
59 unsigned long *prate)
60 {
61 struct tegra_clk_periph *periph = to_clk_periph(hw);
62 const struct clk_ops *div_ops = periph->div_ops;
63 struct clk_hw *div_hw = &periph->divider.hw;
64
65 div_hw->clk = hw->clk;
66
67 return div_ops->round_rate(div_hw, rate, prate);
68 }
69
70 static int clk_periph_set_rate(struct clk_hw *hw, unsigned long rate,
71 unsigned long parent_rate)
72 {
73 struct tegra_clk_periph *periph = to_clk_periph(hw);
74 const struct clk_ops *div_ops = periph->div_ops;
75 struct clk_hw *div_hw = &periph->divider.hw;
76
77 div_hw->clk = hw->clk;
78
79 return div_ops->set_rate(div_hw, rate, parent_rate);
80 }
81
82 static int clk_periph_is_enabled(struct clk_hw *hw)
83 {
84 struct tegra_clk_periph *periph = to_clk_periph(hw);
85 const struct clk_ops *gate_ops = periph->gate_ops;
86 struct clk_hw *gate_hw = &periph->gate.hw;
87
88 gate_hw->clk = hw->clk;
89
90 return gate_ops->is_enabled(gate_hw);
91 }
92
93 static int clk_periph_enable(struct clk_hw *hw)
94 {
95 struct tegra_clk_periph *periph = to_clk_periph(hw);
96 const struct clk_ops *gate_ops = periph->gate_ops;
97 struct clk_hw *gate_hw = &periph->gate.hw;
98
99 gate_hw->clk = hw->clk;
100
101 return gate_ops->enable(gate_hw);
102 }
103
104 static void clk_periph_disable(struct clk_hw *hw)
105 {
106 struct tegra_clk_periph *periph = to_clk_periph(hw);
107 const struct clk_ops *gate_ops = periph->gate_ops;
108 struct clk_hw *gate_hw = &periph->gate.hw;
109
110 gate_ops->disable(gate_hw);
111 }
112
113 const struct clk_ops tegra_clk_periph_ops = {
114 .get_parent = clk_periph_get_parent,
115 .set_parent = clk_periph_set_parent,
116 .recalc_rate = clk_periph_recalc_rate,
117 .round_rate = clk_periph_round_rate,
118 .set_rate = clk_periph_set_rate,
119 .is_enabled = clk_periph_is_enabled,
120 .enable = clk_periph_enable,
121 .disable = clk_periph_disable,
122 };
123
124 const struct clk_ops tegra_clk_periph_nodiv_ops = {
125 .get_parent = clk_periph_get_parent,
126 .set_parent = clk_periph_set_parent,
127 .is_enabled = clk_periph_is_enabled,
128 .enable = clk_periph_enable,
129 .disable = clk_periph_disable,
130 };
131
132 static struct clk *_tegra_clk_register_periph(const char *name,
133 const char **parent_names, int num_parents,
134 struct tegra_clk_periph *periph,
135 void __iomem *clk_base, u32 offset, bool div)
136 {
137 struct clk *clk;
138 struct clk_init_data init;
139
140 init.name = name;
141 init.ops = div ? &tegra_clk_periph_ops : &tegra_clk_periph_nodiv_ops;
142 init.flags = div ? 0 : CLK_SET_RATE_PARENT;
143 init.parent_names = parent_names;
144 init.num_parents = num_parents;
145
146 /* Data in .init is copied by clk_register(), so stack variable OK */
147 periph->hw.init = &init;
148 periph->magic = TEGRA_CLK_PERIPH_MAGIC;
149 periph->mux.reg = clk_base + offset;
150 periph->divider.reg = div ? (clk_base + offset) : NULL;
151 periph->gate.clk_base = clk_base;
152
153 clk = clk_register(NULL, &periph->hw);
154 if (IS_ERR(clk))
155 return clk;
156
157 periph->mux.hw.clk = clk;
158 periph->divider.hw.clk = div ? clk : NULL;
159 periph->gate.hw.clk = clk;
160
161 return clk;
162 }
163
164 struct clk *tegra_clk_register_periph(const char *name,
165 const char **parent_names, int num_parents,
166 struct tegra_clk_periph *periph, void __iomem *clk_base,
167 u32 offset)
168 {
169 return _tegra_clk_register_periph(name, parent_names, num_parents,
170 periph, clk_base, offset, true);
171 }
172
173 struct clk *tegra_clk_register_periph_nodiv(const char *name,
174 const char **parent_names, int num_parents,
175 struct tegra_clk_periph *periph, void __iomem *clk_base,
176 u32 offset)
177 {
178 return _tegra_clk_register_periph(name, parent_names, num_parents,
179 periph, clk_base, offset, false);
180 }
181
drivers/clk/tegra/clk-pll-out.c
File was created 1 /*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <linux/kernel.h>
18 #include <linux/io.h>
19 #include <linux/err.h>
20 #include <linux/delay.h>
21 #include <linux/slab.h>
22 #include <linux/clk-provider.h>
23 #include <linux/clk.h>
24
25 #include "clk.h"
26
27 #define pll_out_enb(p) (BIT(p->enb_bit_idx))
28 #define pll_out_rst(p) (BIT(p->rst_bit_idx))
29
30 static int clk_pll_out_is_enabled(struct clk_hw *hw)
31 {
32 struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
33 u32 val = readl_relaxed(pll_out->reg);
34 int state;
35
36 state = (val & pll_out_enb(pll_out)) ? 1 : 0;
37 if (!(val & (pll_out_rst(pll_out))))
38 state = 0;
39 return state;
40 }
41
42 static int clk_pll_out_enable(struct clk_hw *hw)
43 {
44 struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
45 unsigned long flags = 0;
46 u32 val;
47
48 if (pll_out->lock)
49 spin_lock_irqsave(pll_out->lock, flags);
50
51 val = readl_relaxed(pll_out->reg);
52
53 val |= (pll_out_enb(pll_out) | pll_out_rst(pll_out));
54
55 writel_relaxed(val, pll_out->reg);
56 udelay(2);
57
58 if (pll_out->lock)
59 spin_unlock_irqrestore(pll_out->lock, flags);
60
61 return 0;
62 }
63
64 static void clk_pll_out_disable(struct clk_hw *hw)
65 {
66 struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
67 unsigned long flags = 0;
68 u32 val;
69
70 if (pll_out->lock)
71 spin_lock_irqsave(pll_out->lock, flags);
72
73 val = readl_relaxed(pll_out->reg);
74
75 val &= ~(pll_out_enb(pll_out) | pll_out_rst(pll_out));
76
77 writel_relaxed(val, pll_out->reg);
78 udelay(2);
79
80 if (pll_out->lock)
81 spin_unlock_irqrestore(pll_out->lock, flags);
82 }
83
84 const struct clk_ops tegra_clk_pll_out_ops = {
85 .is_enabled = clk_pll_out_is_enabled,
86 .enable = clk_pll_out_enable,
87 .disable = clk_pll_out_disable,
88 };
89
90 struct clk *tegra_clk_register_pll_out(const char *name,
91 const char *parent_name, void __iomem *reg, u8 enb_bit_idx,
92 u8 rst_bit_idx, unsigned long flags, u8 pll_out_flags,
93 spinlock_t *lock)
94 {
95 struct tegra_clk_pll_out *pll_out;
96 struct clk *clk;
97 struct clk_init_data init;
98
99 pll_out = kzalloc(sizeof(*pll_out), GFP_KERNEL);
100 if (!pll_out)
101 return ERR_PTR(-ENOMEM);
102
103 init.name = name;
104 init.ops = &tegra_clk_pll_out_ops;
105 init.parent_names = (parent_name ? &parent_name : NULL);
106 init.num_parents = (parent_name ? 1 : 0);
107 init.flags = flags;
108
109 pll_out->reg = reg;
110 pll_out->enb_bit_idx = enb_bit_idx;
111 pll_out->rst_bit_idx = rst_bit_idx;
112 pll_out->flags = pll_out_flags;
113 pll_out->lock = lock;
114
115 /* Data in .init is copied by clk_register(), so stack variable OK */
116 pll_out->hw.init = &init;
117
118 clk = clk_register(NULL, &pll_out->hw);
119 if (IS_ERR(clk))
120 kfree(pll_out);
121
122 return clk;
123 }
124
drivers/clk/tegra/clk-pll.c
File was created 1 /*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <linux/slab.h>
18 #include <linux/io.h>
19 #include <linux/delay.h>
20 #include <linux/err.h>
21 #include <linux/clk-provider.h>
22 #include <linux/clk.h>
23
24 #include "clk.h"
25
26 #define PLL_BASE_BYPASS BIT(31)
27 #define PLL_BASE_ENABLE BIT(30)
28 #define PLL_BASE_REF_ENABLE BIT(29)
29 #define PLL_BASE_OVERRIDE BIT(28)
30
31 #define PLL_BASE_DIVP_SHIFT 20
32 #define PLL_BASE_DIVP_WIDTH 3
33 #define PLL_BASE_DIVN_SHIFT 8
34 #define PLL_BASE_DIVN_WIDTH 10
35 #define PLL_BASE_DIVM_SHIFT 0
36 #define PLL_BASE_DIVM_WIDTH 5
37 #define PLLU_POST_DIVP_MASK 0x1
38
39 #define PLL_MISC_DCCON_SHIFT 20
40 #define PLL_MISC_CPCON_SHIFT 8
41 #define PLL_MISC_CPCON_WIDTH 4
42 #define PLL_MISC_CPCON_MASK ((1 << PLL_MISC_CPCON_WIDTH) - 1)
43 #define PLL_MISC_LFCON_SHIFT 4
44 #define PLL_MISC_LFCON_WIDTH 4
45 #define PLL_MISC_LFCON_MASK ((1 << PLL_MISC_LFCON_WIDTH) - 1)
46 #define PLL_MISC_VCOCON_SHIFT 0
47 #define PLL_MISC_VCOCON_WIDTH 4
48 #define PLL_MISC_VCOCON_MASK ((1 << PLL_MISC_VCOCON_WIDTH) - 1)
49
50 #define OUT_OF_TABLE_CPCON 8
51
52 #define PMC_PLLP_WB0_OVERRIDE 0xf8
53 #define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE BIT(12)
54 #define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE BIT(11)
55
56 #define PLL_POST_LOCK_DELAY 50
57
58 #define PLLDU_LFCON_SET_DIVN 600
59
60 #define PLLE_BASE_DIVCML_SHIFT 24
61 #define PLLE_BASE_DIVCML_WIDTH 4
62 #define PLLE_BASE_DIVP_SHIFT 16
63 #define PLLE_BASE_DIVP_WIDTH 7
64 #define PLLE_BASE_DIVN_SHIFT 8
65 #define PLLE_BASE_DIVN_WIDTH 8
66 #define PLLE_BASE_DIVM_SHIFT 0
67 #define PLLE_BASE_DIVM_WIDTH 8
68
69 #define PLLE_MISC_SETUP_BASE_SHIFT 16
70 #define PLLE_MISC_SETUP_BASE_MASK (0xffff << PLLE_MISC_SETUP_BASE_SHIFT)
71 #define PLLE_MISC_LOCK_ENABLE BIT(9)
72 #define PLLE_MISC_READY BIT(15)
73 #define PLLE_MISC_SETUP_EX_SHIFT 2
74 #define PLLE_MISC_SETUP_EX_MASK (3 << PLLE_MISC_SETUP_EX_SHIFT)
75 #define PLLE_MISC_SETUP_MASK (PLLE_MISC_SETUP_BASE_MASK | \
76 PLLE_MISC_SETUP_EX_MASK)
77 #define PLLE_MISC_SETUP_VALUE (7 << PLLE_MISC_SETUP_BASE_SHIFT)
78
79 #define PLLE_SS_CTRL 0x68
80 #define PLLE_SS_DISABLE (7 << 10)
81
82 #define PMC_SATA_PWRGT 0x1ac
83 #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
84 #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
85
86 #define pll_readl(offset, p) readl_relaxed(p->clk_base + offset)
87 #define pll_readl_base(p) pll_readl(p->params->base_reg, p)
88 #define pll_readl_misc(p) pll_readl(p->params->misc_reg, p)
89
90 #define pll_writel(val, offset, p) writel_relaxed(val, p->clk_base + offset)
91 #define pll_writel_base(val, p) pll_writel(val, p->params->base_reg, p)
92 #define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p)
93
94 #define mask(w) ((1 << (w)) - 1)
95 #define divm_mask(p) mask(p->divm_width)
96 #define divn_mask(p) mask(p->divn_width)
97 #define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \
98 mask(p->divp_width))
99
100 #define divm_max(p) (divm_mask(p))
101 #define divn_max(p) (divn_mask(p))
102 #define divp_max(p) (1 << (divp_mask(p)))
103
104 static void clk_pll_enable_lock(struct tegra_clk_pll *pll)
105 {
106 u32 val;
107
108 if (!(pll->flags & TEGRA_PLL_USE_LOCK))
109 return;
110
111 val = pll_readl_misc(pll);
112 val |= BIT(pll->params->lock_enable_bit_idx);
113 pll_writel_misc(val, pll);
114 }
115
116 static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll,
117 void __iomem *lock_addr, u32 lock_bit_idx)
118 {
119 int i;
120 u32 val;
121
122 if (!(pll->flags & TEGRA_PLL_USE_LOCK)) {
123 udelay(pll->params->lock_delay);
124 return 0;
125 }
126
127 for (i = 0; i < pll->params->lock_delay; i++) {
128 val = readl_relaxed(lock_addr);
129 if (val & BIT(lock_bit_idx)) {
130 udelay(PLL_POST_LOCK_DELAY);
131 return 0;
132 }
133 udelay(2); /* timeout = 2 * lock time */
134 }
135
136 pr_err("%s: Timed out waiting for pll %s lock\n", __func__,
137 __clk_get_name(pll->hw.clk));
138
139 return -1;
140 }
141
142 static int clk_pll_is_enabled(struct clk_hw *hw)
143 {
144 struct tegra_clk_pll *pll = to_clk_pll(hw);
145 u32 val;
146
147 if (pll->flags & TEGRA_PLLM) {
148 val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
149 if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)
150 return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0;
151 }
152
153 val = pll_readl_base(pll);
154
155 return val & PLL_BASE_ENABLE ? 1 : 0;
156 }
157
158 static int _clk_pll_enable(struct clk_hw *hw)
159 {
160 struct tegra_clk_pll *pll = to_clk_pll(hw);
161 u32 val;
162
163 clk_pll_enable_lock(pll);
164
165 val = pll_readl_base(pll);
166 val &= ~PLL_BASE_BYPASS;
167 val |= PLL_BASE_ENABLE;
168 pll_writel_base(val, pll);
169
170 if (pll->flags & TEGRA_PLLM) {
171 val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
172 val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
173 writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE);
174 }
175
176 clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->base_reg,
177 pll->params->lock_bit_idx);
178
179 return 0;
180 }
181
182 static void _clk_pll_disable(struct clk_hw *hw)
183 {
184 struct tegra_clk_pll *pll = to_clk_pll(hw);
185 u32 val;
186
187 val = pll_readl_base(pll);
188 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
189 pll_writel_base(val, pll);
190
191 if (pll->flags & TEGRA_PLLM) {
192 val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
193 val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
194 writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE);
195 }
196 }
197
198 static int clk_pll_enable(struct clk_hw *hw)
199 {
200 struct tegra_clk_pll *pll = to_clk_pll(hw);
201 unsigned long flags = 0;
202 int ret;
203
204 if (pll->lock)
205 spin_lock_irqsave(pll->lock, flags);
206
207 ret = _clk_pll_enable(hw);
208
209 if (pll->lock)
210 spin_unlock_irqrestore(pll->lock, flags);
211
212 return ret;
213 }
214
215 static void clk_pll_disable(struct clk_hw *hw)
216 {
217 struct tegra_clk_pll *pll = to_clk_pll(hw);
218 unsigned long flags = 0;
219
220 if (pll->lock)
221 spin_lock_irqsave(pll->lock, flags);
222
223 _clk_pll_disable(hw);
224
225 if (pll->lock)
226 spin_unlock_irqrestore(pll->lock, flags);
227 }
228
229 static int _get_table_rate(struct clk_hw *hw,
230 struct tegra_clk_pll_freq_table *cfg,
231 unsigned long rate, unsigned long parent_rate)
232 {
233 struct tegra_clk_pll *pll = to_clk_pll(hw);
234 struct tegra_clk_pll_freq_table *sel;
235
236 for (sel = pll->freq_table; sel->input_rate != 0; sel++)
237 if (sel->input_rate == parent_rate &&
238 sel->output_rate == rate)
239 break;
240
241 if (sel->input_rate == 0)
242 return -EINVAL;
243
244 BUG_ON(sel->p < 1);
245
246 cfg->input_rate = sel->input_rate;
247 cfg->output_rate = sel->output_rate;
248 cfg->m = sel->m;
249 cfg->n = sel->n;
250 cfg->p = sel->p;
251 cfg->cpcon = sel->cpcon;
252
253 return 0;
254 }
255
256 static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
257 unsigned long rate, unsigned long parent_rate)
258 {
259 struct tegra_clk_pll *pll = to_clk_pll(hw);
260 unsigned long cfreq;
261 u32 p_div = 0;
262
263 switch (parent_rate) {
264 case 12000000:
265 case 26000000:
266 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000;
267 break;
268 case 13000000:
269 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000;
270 break;
271 case 16800000:
272 case 19200000:
273 cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000;
274 break;
275 case 9600000:
276 case 28800000:
277 /*
278 * PLL_P_OUT1 rate is not listed in PLLA table
279 */
280 cfreq = parent_rate/(parent_rate/1000000);
281 break;
282 default:
283 pr_err("%s Unexpected reference rate %lu\n",
284 __func__, parent_rate);
285 BUG();
286 }
287
288 /* Raise VCO to guarantee 0.5% accuracy */
289 for (cfg->output_rate = rate; cfg->output_rate < 200 * cfreq;
290 cfg->output_rate <<= 1)
291 p_div++;
292
293 cfg->p = 1 << p_div;
294 cfg->m = parent_rate / cfreq;
295 cfg->n = cfg->output_rate / cfreq;
296 cfg->cpcon = OUT_OF_TABLE_CPCON;
297
298 if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) ||
299 cfg->p > divp_max(pll) || cfg->output_rate > pll->params->vco_max) {
300 pr_err("%s: Failed to set %s rate %lu\n",
301 __func__, __clk_get_name(hw->clk), rate);
302 return -EINVAL;
303 }
304
305 return 0;
306 }
307
308 static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
309 unsigned long rate)
310 {
311 struct tegra_clk_pll *pll = to_clk_pll(hw);
312 unsigned long flags = 0;
313 u32 divp, val, old_base;
314 int state;
315
316 divp = __ffs(cfg->p);
317
318 if (pll->flags & TEGRA_PLLU)
319 divp ^= 1;
320
321 if (pll->lock)
322 spin_lock_irqsave(pll->lock, flags);
323
324 old_base = val = pll_readl_base(pll);
325 val &= ~((divm_mask(pll) << pll->divm_shift) |
326 (divn_mask(pll) << pll->divn_shift) |
327 (divp_mask(pll) << pll->divp_shift));
328 val |= ((cfg->m << pll->divm_shift) |
329 (cfg->n << pll->divn_shift) |
330 (divp << pll->divp_shift));
331 if (val == old_base) {
332 if (pll->lock)
333 spin_unlock_irqrestore(pll->lock, flags);
334 return 0;
335 }
336
337 state = clk_pll_is_enabled(hw);
338
339 if (state) {
340 _clk_pll_disable(hw);
341 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
342 }
343 pll_writel_base(val, pll);
344
345 if (pll->flags & TEGRA_PLL_HAS_CPCON) {
346 val = pll_readl_misc(pll);
347 val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT);
348 val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT;
349 if (pll->flags & TEGRA_PLL_SET_LFCON) {
350 val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT);
351 if (cfg->n >= PLLDU_LFCON_SET_DIVN)
352 val |= 0x1 << PLL_MISC_LFCON_SHIFT;
353 } else if (pll->flags & TEGRA_PLL_SET_DCCON) {
354 val &= ~(0x1 << PLL_MISC_DCCON_SHIFT);
355 if (rate >= (pll->params->vco_max >> 1))
356 val |= 0x1 << PLL_MISC_DCCON_SHIFT;
357 }
358 pll_writel_misc(val, pll);
359 }
360
361 if (pll->lock)
362 spin_unlock_irqrestore(pll->lock, flags);
363
364 if (state)
365 clk_pll_enable(hw);
366
367 return 0;
368 }
369
370 static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
371 unsigned long parent_rate)
372 {
373 struct tegra_clk_pll *pll = to_clk_pll(hw);
374 struct tegra_clk_pll_freq_table cfg;
375
376 if (pll->flags & TEGRA_PLL_FIXED) {
377 if (rate != pll->fixed_rate) {
378 pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
379 __func__, __clk_get_name(hw->clk),
380 pll->fixed_rate, rate);
381 return -EINVAL;
382 }
383 return 0;
384 }
385
386 if (_get_table_rate(hw, &cfg, rate, parent_rate) &&
387 _calc_rate(hw, &cfg, rate, parent_rate))
388 return -EINVAL;
389
390 return _program_pll(hw, &cfg, rate);
391 }
392
393 static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
394 unsigned long *prate)
395 {
396 struct tegra_clk_pll *pll = to_clk_pll(hw);
397 struct tegra_clk_pll_freq_table cfg;
398 u64 output_rate = *prate;
399
400 if (pll->flags & TEGRA_PLL_FIXED)
401 return pll->fixed_rate;
402
403 /* PLLM is used for memory; we do not change rate */
404 if (pll->flags & TEGRA_PLLM)
405 return __clk_get_rate(hw->clk);
406
407 if (_get_table_rate(hw, &cfg, rate, *prate) &&
408 _calc_rate(hw, &cfg, rate, *prate))
409 return -EINVAL;
410
411 output_rate *= cfg.n;
412 do_div(output_rate, cfg.m * cfg.p);
413
414 return output_rate;
415 }
416
417 static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
418 unsigned long parent_rate)
419 {
420 struct tegra_clk_pll *pll = to_clk_pll(hw);
421 u32 val = pll_readl_base(pll);
422 u32 divn = 0, divm = 0, divp = 0;
423 u64 rate = parent_rate;
424
425 if (val & PLL_BASE_BYPASS)
426 return parent_rate;
427
428 if ((pll->flags & TEGRA_PLL_FIXED) && !(val & PLL_BASE_OVERRIDE)) {
429 struct tegra_clk_pll_freq_table sel;
430 if (_get_table_rate(hw, &sel, pll->fixed_rate, parent_rate)) {
431 pr_err("Clock %s has unknown fixed frequency\n",
432 __clk_get_name(hw->clk));
433 BUG();
434 }
435 return pll->fixed_rate;
436 }
437
438 divp = (val >> pll->divp_shift) & (divp_mask(pll));
439 if (pll->flags & TEGRA_PLLU)
440 divp ^= 1;
441
442 divn = (val >> pll->divn_shift) & (divn_mask(pll));
443 divm = (val >> pll->divm_shift) & (divm_mask(pll));
444 divm *= (1 << divp);
445
446 rate *= divn;
447 do_div(rate, divm);
448 return rate;
449 }
450
451 static int clk_plle_training(struct tegra_clk_pll *pll)
452 {
453 u32 val;
454 unsigned long timeout;
455
456 if (!pll->pmc)
457 return -ENOSYS;
458
459 /*
460 * PLLE is already disabled, and setup cleared;
461 * create falling edge on PLLE IDDQ input.
462 */
463 val = readl(pll->pmc + PMC_SATA_PWRGT);
464 val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
465 writel(val, pll->pmc + PMC_SATA_PWRGT);
466
467 val = readl(pll->pmc + PMC_SATA_PWRGT);
468 val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
469 writel(val, pll->pmc + PMC_SATA_PWRGT);
470
471 val = readl(pll->pmc + PMC_SATA_PWRGT);
472 val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
473 writel(val, pll->pmc + PMC_SATA_PWRGT);
474
475 val = pll_readl_misc(pll);
476
477 timeout = jiffies + msecs_to_jiffies(100);
478 while (1) {
479 val = pll_readl_misc(pll);
480 if (val & PLLE_MISC_READY)
481 break;
482 if (time_after(jiffies, timeout)) {
483 pr_err("%s: timeout waiting for PLLE\n", __func__);
484 return -EBUSY;
485 }
486 udelay(300);
487 }
488
489 return 0;
490 }
491
492 static int clk_plle_enable(struct clk_hw *hw)
493 {
494 struct tegra_clk_pll *pll = to_clk_pll(hw);
495 unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk));
496 struct tegra_clk_pll_freq_table sel;
497 u32 val;
498 int err;
499
500 if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate))
501 return -EINVAL;
502
503 clk_pll_disable(hw);
504
505 val = pll_readl_misc(pll);
506 val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK);
507 pll_writel_misc(val, pll);
508
509 val = pll_readl_misc(pll);
510 if (!(val & PLLE_MISC_READY)) {
511 err = clk_plle_training(pll);
512 if (err)
513 return err;
514 }
515
516 if (pll->flags & TEGRA_PLLE_CONFIGURE) {
517 /* configure dividers */
518 val = pll_readl_base(pll);
519 val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll));
520 val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
521 val |= sel.m << pll->divm_shift;
522 val |= sel.n << pll->divn_shift;
523 val |= sel.p << pll->divp_shift;
524 val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
525 pll_writel_base(val, pll);
526 }
527
528 val = pll_readl_misc(pll);
529 val |= PLLE_MISC_SETUP_VALUE;
530 val |= PLLE_MISC_LOCK_ENABLE;
531 pll_writel_misc(val, pll);
532
533 val = readl(pll->clk_base + PLLE_SS_CTRL);
534 val |= PLLE_SS_DISABLE;
535 writel(val, pll->clk_base + PLLE_SS_CTRL);
536
537 val |= pll_readl_base(pll);
538 val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE);
539 pll_writel_base(val, pll);
540
541 clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->misc_reg,
542 pll->params->lock_bit_idx);
543 return 0;
544 }
545
546 static unsigned long clk_plle_recalc_rate(struct clk_hw *hw,
547 unsigned long parent_rate)
548 {
549 struct tegra_clk_pll *pll = to_clk_pll(hw);
550 u32 val = pll_readl_base(pll);
551 u32 divn = 0, divm = 0, divp = 0;
552 u64 rate = parent_rate;
553
554 divp = (val >> pll->divp_shift) & (divp_mask(pll));
555 divn = (val >> pll->divn_shift) & (divn_mask(pll));
556 divm = (val >> pll->divm_shift) & (divm_mask(pll));
557 divm *= divp;
558
559 rate *= divn;
560 do_div(rate, divm);
561 return rate;
562 }
563
564 const struct clk_ops tegra_clk_pll_ops = {
565 .is_enabled = clk_pll_is_enabled,
566 .enable = clk_pll_enable,
567 .disable = clk_pll_disable,
568 .recalc_rate = clk_pll_recalc_rate,
569 .round_rate = clk_pll_round_rate,
570 .set_rate = clk_pll_set_rate,
571 };
572
573 const struct clk_ops tegra_clk_plle_ops = {
574 .recalc_rate = clk_plle_recalc_rate,
575 .is_enabled = clk_pll_is_enabled,
576 .disable = clk_pll_disable,
577 .enable = clk_plle_enable,
578 };
579
580 static struct clk *_tegra_clk_register_pll(const char *name,
581 const char *parent_name, void __iomem *clk_base,
582 void __iomem *pmc, unsigned long flags,
583 unsigned long fixed_rate,
584 struct tegra_clk_pll_params *pll_params, u8 pll_flags,
585 struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock,
586 const struct clk_ops *ops)
587 {
588 struct tegra_clk_pll *pll;
589 struct clk *clk;
590 struct clk_init_data init;
591
592 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
593 if (!pll)
594 return ERR_PTR(-ENOMEM);
595
596 init.name = name;
597 init.ops = ops;
598 init.flags = flags;
599 init.parent_names = (parent_name ? &parent_name : NULL);
600 init.num_parents = (parent_name ? 1 : 0);
601
602 pll->clk_base = clk_base;
603 pll->pmc = pmc;
604
605 pll->freq_table = freq_table;
606 pll->params = pll_params;
607 pll->fixed_rate = fixed_rate;
608 pll->flags = pll_flags;
609 pll->lock = lock;
610
611 pll->divp_shift = PLL_BASE_DIVP_SHIFT;
612 pll->divp_width = PLL_BASE_DIVP_WIDTH;
613 pll->divn_shift = PLL_BASE_DIVN_SHIFT;
614 pll->divn_width = PLL_BASE_DIVN_WIDTH;
615 pll->divm_shift = PLL_BASE_DIVM_SHIFT;
616 pll->divm_width = PLL_BASE_DIVM_WIDTH;
617
618 /* Data in .init is copied by clk_register(), so stack variable OK */
619 pll->hw.init = &init;
620
621 clk = clk_register(NULL, &pll->hw);
622 if (IS_ERR(clk))
623 kfree(pll);
624
625 return clk;
626 }
627
628 struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
629 void __iomem *clk_base, void __iomem *pmc,
630 unsigned long flags, unsigned long fixed_rate,
631 struct tegra_clk_pll_params *pll_params, u8 pll_flags,
632 struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
633 {
634 return _tegra_clk_register_pll(name, parent_name, clk_base, pmc,
635 flags, fixed_rate, pll_params, pll_flags, freq_table,
636 lock, &tegra_clk_pll_ops);
637 }
638
639 struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
640 void __iomem *clk_base, void __iomem *pmc,
641 unsigned long flags, unsigned long fixed_rate,
642 struct tegra_clk_pll_params *pll_params, u8 pll_flags,
643 struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
644 {
645 return _tegra_clk_register_pll(name, parent_name, clk_base, pmc,
646 flags, fixed_rate, pll_params, pll_flags, freq_table,
647 lock, &tegra_clk_plle_ops);
648 }
649
drivers/clk/tegra/clk-super.c
File was created 1 /*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <linux/kernel.h>
18 #include <linux/io.h>
19 #include <linux/delay.h>
20 #include <linux/err.h>
21 #include <linux/slab.h>
22 #include <linux/clk-provider.h>
23 #include <linux/clk.h>
24
25 #include "clk.h"
26
27 #define SUPER_STATE_IDLE 0
28 #define SUPER_STATE_RUN 1
29 #define SUPER_STATE_IRQ 2
30 #define SUPER_STATE_FIQ 3
31
32 #define SUPER_STATE_SHIFT 28
33 #define SUPER_STATE_MASK ((BIT(SUPER_STATE_IDLE) | BIT(SUPER_STATE_RUN) | \
34 BIT(SUPER_STATE_IRQ) | BIT(SUPER_STATE_FIQ)) \
35 << SUPER_STATE_SHIFT)
36
37 #define SUPER_LP_DIV2_BYPASS (1 << 16)
38
39 #define super_state(s) (BIT(s) << SUPER_STATE_SHIFT)
40 #define super_state_to_src_shift(m, s) ((m->width * s))
41 #define super_state_to_src_mask(m) (((1 << m->width) - 1))
42
43 static u8 clk_super_get_parent(struct clk_hw *hw)
44 {
45 struct tegra_clk_super_mux *mux = to_clk_super_mux(hw);
46 u32 val, state;
47 u8 source, shift;
48
49 val = readl_relaxed(mux->reg);
50
51 state = val & SUPER_STATE_MASK;
52
53 BUG_ON((state != super_state(SUPER_STATE_RUN)) &&
54 (state != super_state(SUPER_STATE_IDLE)));
55 shift = (state == super_state(SUPER_STATE_IDLE)) ?
56 super_state_to_src_shift(mux, SUPER_STATE_IDLE) :
57 super_state_to_src_shift(mux, SUPER_STATE_RUN);
58
59 source = (val >> shift) & super_state_to_src_mask(mux);
60
61 /*
62 * If LP_DIV2_BYPASS is not set and PLLX is current parent then
63 * PLLX/2 is the input source to CCLKLP.
64 */
65 if ((mux->flags & TEGRA_DIVIDER_2) && !(val & SUPER_LP_DIV2_BYPASS) &&
66 (source == mux->pllx_index))
67 source = mux->div2_index;
68
69 return source;
70 }
71
72 static int clk_super_set_parent(struct clk_hw *hw, u8 index)
73 {
74 struct tegra_clk_super_mux *mux = to_clk_super_mux(hw);
75 u32 val, state;
76 u8 parent_index, shift;
77
78 val = readl_relaxed(mux->reg);
79 state = val & SUPER_STATE_MASK;
80 BUG_ON((state != super_state(SUPER_STATE_RUN)) &&
81 (state != super_state(SUPER_STATE_IDLE)));
82 shift = (state == super_state(SUPER_STATE_IDLE)) ?
83 super_state_to_src_shift(mux, SUPER_STATE_IDLE) :
84 super_state_to_src_shift(mux, SUPER_STATE_RUN);
85
86 /*
87 * For LP mode super-clock switch between PLLX direct
88 * and divided-by-2 outputs is allowed only when other
89 * than PLLX clock source is current parent.
90 */
91 if ((mux->flags & TEGRA_DIVIDER_2) && ((index == mux->div2_index) ||
92 (index == mux->pllx_index))) {
93 parent_index = clk_super_get_parent(hw);
94 if ((parent_index == mux->div2_index) ||
95 (parent_index == mux->pllx_index))
96 return -EINVAL;
97
98 val ^= SUPER_LP_DIV2_BYPASS;
99 writel_relaxed(val, mux->reg);
100 udelay(2);
101
102 if (index == mux->div2_index)
103 index = mux->pllx_index;
104 }
105 val &= ~((super_state_to_src_mask(mux)) << shift);
106 val |= (index & (super_state_to_src_mask(mux))) << shift;
107
108 writel_relaxed(val, mux->reg);
109 udelay(2);
110 return 0;
111 }
112
113 const struct clk_ops tegra_clk_super_ops = {
114 .get_parent = clk_super_get_parent,
115 .set_parent = clk_super_set_parent,
116 };
117
118 struct clk *tegra_clk_register_super_mux(const char *name,
119 const char **parent_names, u8 num_parents,
120 unsigned long flags, void __iomem *reg, u8 clk_super_flags,
121 u8 width, u8 pllx_index, u8 div2_index, spinlock_t *lock)
122 {
123 struct tegra_clk_super_mux *super;
124 struct clk *clk;
125 struct clk_init_data init;
126
127 super = kzalloc(sizeof(*super), GFP_KERNEL);
128 if (!super) {
129 pr_err("%s: could not allocate super clk\n", __func__);
130 return ERR_PTR(-ENOMEM);
131 }
132
133 init.name = name;
134 init.ops = &tegra_clk_super_ops;
135 init.flags = flags;
136 init.parent_names = parent_names;
137 init.num_parents = num_parents;
138
139 super->reg = reg;
140 super->pllx_index = pllx_index;
141 super->div2_index = div2_index;
142 super->lock = lock;
143 super->width = width;
144 super->flags = clk_super_flags;
145
146 /* Data in .init is copied by clk_register(), so stack variable OK */
147 super->hw.init = &init;
148
149 clk = clk_register(NULL, &super->hw);
150 if (IS_ERR(clk))
151 kfree(super);
152
153 return clk;
154 }
155
drivers/clk/tegra/clk.c
File was created 1 /*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <linux/clk.h>
18 #include <linux/clk-provider.h>
19
20 #include "clk.h"
21
22 void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
23 struct clk *clks[], int clk_max)
24 {
25 struct clk *clk;
26
27 for (; dup_list->clk_id < clk_max; dup_list++) {
28 clk = clks[dup_list->clk_id];
29 dup_list->lookup.clk = clk;
30 clkdev_add(&dup_list->lookup);
31 }
32 }
33
34 void __init tegra_init_from_table(struct tegra_clk_init_table *tbl,
35 struct clk *clks[], int clk_max)
36 {
37 struct clk *clk;
38
39 for (; tbl->clk_id < clk_max; tbl++) {
40 clk = clks[tbl->clk_id];
41 if (IS_ERR_OR_NULL(clk))
42 return;
43
44 if (tbl->parent_id < clk_max) {
45 struct clk *parent = clks[tbl->parent_id];
46 if (clk_set_parent(clk, parent)) {
47 pr_err("%s: Failed to set parent %s of %s\n",
48 __func__, __clk_get_name(parent),
49 __clk_get_name(clk));
50 WARN_ON(1);
51 }
52 }
53
54 if (tbl->rate)
55 if (clk_set_rate(clk, tbl->rate)) {
56 pr_err("%s: Failed to set rate %lu of %s\n",
57 __func__, tbl->rate,
58 __clk_get_name(clk));
59 WARN_ON(1);
60 }
61
62 if (tbl->state)
63 if (clk_prepare_enable(clk)) {
64 pr_err("%s: Failed to enable %s\n", __func__,
65 __clk_get_name(clk));
66 WARN_ON(1);
67 }
68 }
69 }
70
drivers/clk/tegra/clk.h
File was created 1 /*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef __TEGRA_CLK_H
18 #define __TEGRA_CLK_H
19
20 #include <linux/clk-provider.h>
21 #include <linux/clkdev.h>
22
23 /**
24 * struct tegra_clk_sync_source - external clock source from codec
25 *
26 * @hw: handle between common and hardware-specific interfaces
27 * @rate: input frequency from source
28 * @max_rate: max rate allowed
29 */
30 struct tegra_clk_sync_source {
31 struct clk_hw hw;
32 unsigned long rate;
33 unsigned long max_rate;
34 };
35
36 #define to_clk_sync_source(_hw) \
37 container_of(_hw, struct tegra_clk_sync_source, hw)
38
39 extern const struct clk_ops tegra_clk_sync_source_ops;
40 struct clk *tegra_clk_register_sync_source(const char *name,
41 unsigned long fixed_rate, unsigned long max_rate);
42
43 /**
44 * struct tegra_clk_frac_div - fractional divider clock
45 *
46 * @hw: handle between common and hardware-specific interfaces
47 * @reg: register containing divider
48 * @flags: hardware-specific flags
49 * @shift: shift to the divider bit field
50 * @width: width of the divider bit field
51 * @frac_width: width of the fractional bit field
52 * @lock: register lock
53 *
54 * Flags:
55 * TEGRA_DIVIDER_ROUND_UP - This flags indicates to round up the divider value.
56 * TEGRA_DIVIDER_FIXED - Fixed rate PLL dividers has addition override bit, this
57 * flag indicates that this divider is for fixed rate PLL.
58 * TEGRA_DIVIDER_INT - Some modules can not cope with the duty cycle when
59 * fraction bit is set. This flags indicates to calculate divider for which
60 * fracton bit will be zero.
61 * TEGRA_DIVIDER_UART - UART module divider has additional enable bit which is
62 * set when divider value is not 0. This flags indicates that the divider
63 * is for UART module.
64 */
65 struct tegra_clk_frac_div {
66 struct clk_hw hw;
67 void __iomem *reg;
68 u8 flags;
69 u8 shift;
70 u8 width;
71 u8 frac_width;
72 spinlock_t *lock;
73 };
74
75 #define to_clk_frac_div(_hw) container_of(_hw, struct tegra_clk_frac_div, hw)
76
77 #define TEGRA_DIVIDER_ROUND_UP BIT(0)
78 #define TEGRA_DIVIDER_FIXED BIT(1)
79 #define TEGRA_DIVIDER_INT BIT(2)
80 #define TEGRA_DIVIDER_UART BIT(3)
81
82 extern const struct clk_ops tegra_clk_frac_div_ops;
83 struct clk *tegra_clk_register_divider(const char *name,
84 const char *parent_name, void __iomem *reg,
85 unsigned long flags, u8 clk_divider_flags, u8 shift, u8 width,
86 u8 frac_width, spinlock_t *lock);
87
88 /*
89 * Tegra PLL:
90 *
91 * In general, there are 3 requirements for each PLL
92 * that SW needs to be comply with.
93 * (1) Input frequency range (REF).
94 * (2) Comparison frequency range (CF). CF = REF/DIVM.
95 * (3) VCO frequency range (VCO). VCO = CF * DIVN.
96 *
97 * The final PLL output frequency (FO) = VCO >> DIVP.
98 */
99
100 /**
101 * struct tegra_clk_pll_freq_table - PLL frequecy table
102 *
103 * @input_rate: input rate from source
104 * @output_rate: output rate from PLL for the input rate
105 * @n: feedback divider
106 * @m: input divider
107 * @p: post divider
108 * @cpcon: charge pump current
109 */
110 struct tegra_clk_pll_freq_table {
111 unsigned long input_rate;
112 unsigned long output_rate;
113 u16 n;
114 u16 m;
115 u8 p;
116 u8 cpcon;
117 };
118
119 /**
120 * struct clk_pll_params - PLL parameters
121 *
122 * @input_min: Minimum input frequency
123 * @input_max: Maximum input frequency
124 * @cf_min: Minimum comparison frequency
125 * @cf_max: Maximum comparison frequency
126 * @vco_min: Minimum VCO frequency
127 * @vco_max: Maximum VCO frequency
128 * @base_reg: PLL base reg offset
129 * @misc_reg: PLL misc reg offset
130 * @lock_reg: PLL lock reg offset
131 * @lock_bit_idx: Bit index for PLL lock status
132 * @lock_enable_bit_idx: Bit index to enable PLL lock
133 * @lock_delay: Delay in us if PLL lock is not used
134 */
135 struct tegra_clk_pll_params {
136 unsigned long input_min;
137 unsigned long input_max;
138 unsigned long cf_min;
139 unsigned long cf_max;
140 unsigned long vco_min;
141 unsigned long vco_max;
142
143 u32 base_reg;
144 u32 misc_reg;
145 u32 lock_reg;
146 u32 lock_bit_idx;
147 u32 lock_enable_bit_idx;
148 int lock_delay;
149 };
150
151 /**
152 * struct tegra_clk_pll - Tegra PLL clock
153 *
154 * @hw: handle between common and hardware-specifix interfaces
155 * @clk_base: address of CAR controller
156 * @pmc: address of PMC, required to read override bits
157 * @freq_table: array of frequencies supported by PLL
158 * @params: PLL parameters
159 * @flags: PLL flags
160 * @fixed_rate: PLL rate if it is fixed
161 * @lock: register lock
162 * @divn_shift: shift to the feedback divider bit field
163 * @divn_width: width of the feedback divider bit field
164 * @divm_shift: shift to the input divider bit field
165 * @divm_width: width of the input divider bit field
166 * @divp_shift: shift to the post divider bit field
167 * @divp_width: width of the post divider bit field
168 *
169 * Flags:
170 * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
171 * PLL locking. If not set it will use lock_delay value to wait.
172 * TEGRA_PLL_HAS_CPCON - This flag indicates that CPCON value needs
173 * to be programmed to change output frequency of the PLL.
174 * TEGRA_PLL_SET_LFCON - This flag indicates that LFCON value needs
175 * to be programmed to change output frequency of the PLL.
176 * TEGRA_PLL_SET_DCCON - This flag indicates that DCCON value needs
177 * to be programmed to change output frequency of the PLL.
178 * TEGRA_PLLU - PLLU has inverted post divider. This flags indicated
179 * that it is PLLU and invert post divider value.
180 * TEGRA_PLLM - PLLM has additional override settings in PMC. This
181 * flag indicates that it is PLLM and use override settings.
182 * TEGRA_PLL_FIXED - We are not supposed to change output frequency
183 * of some plls.
184 * TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling.
185 */
186 struct tegra_clk_pll {
187 struct clk_hw hw;
188 void __iomem *clk_base;
189 void __iomem *pmc;
190 u8 flags;
191 unsigned long fixed_rate;
192 spinlock_t *lock;
193 u8 divn_shift;
194 u8 divn_width;
195 u8 divm_shift;
196 u8 divm_width;
197 u8 divp_shift;
198 u8 divp_width;
199 struct tegra_clk_pll_freq_table *freq_table;
200 struct tegra_clk_pll_params *params;
201 };
202
203 #define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw)
204
205 #define TEGRA_PLL_USE_LOCK BIT(0)
206 #define TEGRA_PLL_HAS_CPCON BIT(1)
207 #define TEGRA_PLL_SET_LFCON BIT(2)
208 #define TEGRA_PLL_SET_DCCON BIT(3)
209 #define TEGRA_PLLU BIT(4)
210 #define TEGRA_PLLM BIT(5)
211 #define TEGRA_PLL_FIXED BIT(6)
212 #define TEGRA_PLLE_CONFIGURE BIT(7)
213
214 extern const struct clk_ops tegra_clk_pll_ops;
215 extern const struct clk_ops tegra_clk_plle_ops;
216 struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
217 void __iomem *clk_base, void __iomem *pmc,
218 unsigned long flags, unsigned long fixed_rate,
219 struct tegra_clk_pll_params *pll_params, u8 pll_flags,
220 struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock);
221 struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
222 void __iomem *clk_base, void __iomem *pmc,
223 unsigned long flags, unsigned long fixed_rate,
224 struct tegra_clk_pll_params *pll_params, u8 pll_flags,
225 struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock);
226
227 /**
228 * struct tegra_clk_pll_out - PLL divider down clock
229 *
230 * @hw: handle between common and hardware-specific interfaces
231 * @reg: register containing the PLL divider
232 * @enb_bit_idx: bit to enable/disable PLL divider
233 * @rst_bit_idx: bit to reset PLL divider
234 * @lock: register lock
235 * @flags: hardware-specific flags
236 */
237 struct tegra_clk_pll_out {
238 struct clk_hw hw;
239 void __iomem *reg;
240 u8 enb_bit_idx;
241 u8 rst_bit_idx;
242 spinlock_t *lock;
243 u8 flags;
244 };
245
246 #define to_clk_pll_out(_hw) container_of(_hw, struct tegra_clk_pll_out, hw)
247
248 extern const struct clk_ops tegra_clk_pll_out_ops;
249 struct clk *tegra_clk_register_pll_out(const char *name,
250 const char *parent_name, void __iomem *reg, u8 enb_bit_idx,
251 u8 rst_bit_idx, unsigned long flags, u8 pll_div_flags,
252 spinlock_t *lock);
253
254 /**
255 * struct tegra_clk_periph_regs - Registers controlling peripheral clock
256 *
257 * @enb_reg: read the enable status
258 * @enb_set_reg: write 1 to enable clock
259 * @enb_clr_reg: write 1 to disable clock
260 * @rst_reg: read the reset status
261 * @rst_set_reg: write 1 to assert the reset of peripheral
262 * @rst_clr_reg: write 1 to deassert the reset of peripheral
263 */
264 struct tegra_clk_periph_regs {
265 u32 enb_reg;
266 u32 enb_set_reg;
267 u32 enb_clr_reg;
268 u32 rst_reg;
269 u32 rst_set_reg;
270 u32 rst_clr_reg;
271 };
272
273 /**
274 * struct tegra_clk_periph_gate - peripheral gate clock
275 *
276 * @magic: magic number to validate type
277 * @hw: handle between common and hardware-specific interfaces
278 * @clk_base: address of CAR controller
279 * @regs: Registers to control the peripheral
280 * @flags: hardware-specific flags
281 * @clk_num: Clock number
282 * @enable_refcnt: array to maintain reference count of the clock
283 *
284 * Flags:
285 * TEGRA_PERIPH_NO_RESET - This flag indicates that reset is not allowed
286 * for this module.
287 * TEGRA_PERIPH_MANUAL_RESET - This flag indicates not to reset module
288 * after clock enable and driver for the module is responsible for
289 * doing reset.
290 * TEGRA_PERIPH_ON_APB - If peripheral is in the APB bus then read the
291 * bus to flush the write operation in apb bus. This flag indicates
292 * that this peripheral is in apb bus.
293 */
294 struct tegra_clk_periph_gate {
295 u32 magic;
296 struct clk_hw hw;
297 void __iomem *clk_base;
298 u8 flags;
299 int clk_num;
300 int *enable_refcnt;
301 struct tegra_clk_periph_regs *regs;
302 };
303
304 #define to_clk_periph_gate(_hw) \
305 container_of(_hw, struct tegra_clk_periph_gate, hw)
306
307 #define TEGRA_CLK_PERIPH_GATE_MAGIC 0x17760309
308
309 #define TEGRA_PERIPH_NO_RESET BIT(0)
310 #define TEGRA_PERIPH_MANUAL_RESET BIT(1)
311 #define TEGRA_PERIPH_ON_APB BIT(2)
312
313 void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert);
314 extern const struct clk_ops tegra_clk_periph_gate_ops;
315 struct clk *tegra_clk_register_periph_gate(const char *name,
316 const char *parent_name, u8 gate_flags, void __iomem *clk_base,
317 unsigned long flags, int clk_num,
318 struct tegra_clk_periph_regs *pregs, int *enable_refcnt);
319
320 /**
321 * struct clk-periph - peripheral clock
322 *
323 * @magic: magic number to validate type
324 * @hw: handle between common and hardware-specific interfaces
325 * @mux: mux clock
326 * @divider: divider clock
327 * @gate: gate clock
328 * @mux_ops: mux clock ops
329 * @div_ops: divider clock ops
330 * @gate_ops: gate clock ops
331 */
332 struct tegra_clk_periph {
333 u32 magic;
334 struct clk_hw hw;
335 struct clk_mux mux;
336 struct tegra_clk_frac_div divider;
337 struct tegra_clk_periph_gate gate;
338
339 const struct clk_ops *mux_ops;
340 const struct clk_ops *div_ops;
341 const struct clk_ops *gate_ops;
342 };
343
344 #define to_clk_periph(_hw) container_of(_hw, struct tegra_clk_periph, hw)
345
346 #define TEGRA_CLK_PERIPH_MAGIC 0x18221223
347
348 extern const struct clk_ops tegra_clk_periph_ops;
349 struct clk *tegra_clk_register_periph(const char *name,
350 const char **parent_names, int num_parents,
351 struct tegra_clk_periph *periph, void __iomem *clk_base,
352 u32 offset);
353 struct clk *tegra_clk_register_periph_nodiv(const char *name,
354 const char **parent_names, int num_parents,
355 struct tegra_clk_periph *periph, void __iomem *clk_base,
356 u32 offset);
357
358 #define TEGRA_CLK_PERIPH(_mux_shift, _mux_width, _mux_flags, \
359 _div_shift, _div_width, _div_frac_width, \
360 _div_flags, _clk_num, _enb_refcnt, _regs, \
361 _gate_flags) \
362 { \
363 .mux = { \
364 .flags = _mux_flags, \
365 .shift = _mux_shift, \
366 .width = _mux_width, \
367 }, \
368 .divider = { \
369 .flags = _div_flags, \
370 .shift = _div_shift, \
371 .width = _div_width, \
372 .frac_width = _div_frac_width, \
373 }, \
374 .gate = { \
375 .flags = _gate_flags, \
376 .clk_num = _clk_num, \
377 .enable_refcnt = _enb_refcnt, \
378 .regs = _regs, \
379 }, \
380 .mux_ops = &clk_mux_ops, \
381 .div_ops = &tegra_clk_frac_div_ops, \
382 .gate_ops = &tegra_clk_periph_gate_ops, \
383 }
384
385 struct tegra_periph_init_data {
386 const char *name;
387 int clk_id;
388 const char **parent_names;
389 int num_parents;
390 struct tegra_clk_periph periph;
391 u32 offset;
392 const char *con_id;
393 const char *dev_id;
394 };
395
396 #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset, \
397 _mux_shift, _mux_width, _mux_flags, _div_shift, \
398 _div_width, _div_frac_width, _div_flags, _regs, \
399 _clk_num, _enb_refcnt, _gate_flags, _clk_id) \
400 { \
401 .name = _name, \
402 .clk_id = _clk_id, \
403 .parent_names = _parent_names, \
404 .num_parents = ARRAY_SIZE(_parent_names), \
405 .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_width, \
406 _mux_flags, _div_shift, \
407 _div_width, _div_frac_width, \
408 _div_flags, _clk_num, \
409 _enb_refcnt, _regs, \
410 _gate_flags), \
411 .offset = _offset, \
412 .con_id = _con_id, \
413 .dev_id = _dev_id, \
414 }
415
416 /**
417 * struct clk_super_mux - super clock
418 *
419 * @hw: handle between common and hardware-specific interfaces
420 * @reg: register controlling multiplexer
421 * @width: width of the multiplexer bit field
422 * @flags: hardware-specific flags
423 * @div2_index: bit controlling divide-by-2
424 * @pllx_index: PLLX index in the parent list
425 * @lock: register lock
426 *
427 * Flags:
428 * TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag indicates
429 * that this is LP cluster clock.
430 */
431 struct tegra_clk_super_mux {
432 struct clk_hw hw;
433 void __iomem *reg;
434 u8 width;
435 u8 flags;
436 u8 div2_index;
437 u8 pllx_index;
438 spinlock_t *lock;
439 };
440
441 #define to_clk_super_mux(_hw) container_of(_hw, struct tegra_clk_super_mux, hw)
442
443 #define TEGRA_DIVIDER_2 BIT(0)
444
445 extern const struct clk_ops tegra_clk_super_ops;
446 struct clk *tegra_clk_register_super_mux(const char *name,
447 const char **parent_names, u8 num_parents,
448 unsigned long flags, void __iomem *reg, u8 clk_super_flags,
449 u8 width, u8 pllx_index, u8 div2_index, spinlock_t *lock);
450
451 /**
452 * struct clk_init_tabel - clock initialization table
453 * @clk_id: clock id as mentioned in device tree bindings
454 * @parent_id: parent clock id as mentioned in device tree bindings
455 * @rate: rate to set
456 * @state: enable/disable
457 */
458 struct tegra_clk_init_table {
459 unsigned int clk_id;
460 unsigned int parent_id;
461 unsigned long rate;
462 int state;
463 };
464
465 /**
466 * struct clk_duplicate - duplicate clocks
467 * @clk_id: clock id as mentioned in device tree bindings
468 * @lookup: duplicate lookup entry for the clock
469 */
470 struct tegra_clk_duplicate {
471 int clk_id;
472 struct clk_lookup lookup;
473 };
474
475 #define TEGRA_CLK_DUPLICATE(_clk_id, _dev, _con) \
476 { \
477 .clk_id = _clk_id, \
478 .lookup = { \
479 .dev_id = _dev, \
480 .con_id = _con, \
481 }, \
482 }
483
484 void tegra_init_from_table(struct tegra_clk_init_table *tbl,
485 struct clk *clks[], int clk_max);
486
487 void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
488 struct clk *clks[], int clk_max);
489
490 #endif /* TEGRA_CLK_H */
491