diff options
Diffstat (limited to 'kernel/drivers/clk/mmp')
-rw-r--r-- | kernel/drivers/clk/mmp/Makefile | 2 | ||||
-rw-r--r-- | kernel/drivers/clk/mmp/clk-apbc.c | 3 | ||||
-rw-r--r-- | kernel/drivers/clk/mmp/clk-apmu.c | 3 | ||||
-rw-r--r-- | kernel/drivers/clk/mmp/clk-gate.c | 3 | ||||
-rw-r--r-- | kernel/drivers/clk/mmp/clk-mix.c | 71 | ||||
-rw-r--r-- | kernel/drivers/clk/mmp/clk-mmp2.c | 5 | ||||
-rw-r--r-- | kernel/drivers/clk/mmp/clk-of-mmp2.c | 10 | ||||
-rw-r--r-- | kernel/drivers/clk/mmp/clk-of-pxa168.c | 8 | ||||
-rw-r--r-- | kernel/drivers/clk/mmp/clk-of-pxa1928.c | 265 | ||||
-rw-r--r-- | kernel/drivers/clk/mmp/clk-of-pxa910.c | 12 | ||||
-rw-r--r-- | kernel/drivers/clk/mmp/clk-pxa168.c | 1 | ||||
-rw-r--r-- | kernel/drivers/clk/mmp/clk-pxa910.c | 1 | ||||
-rw-r--r-- | kernel/drivers/clk/mmp/clk.c | 3 |
13 files changed, 336 insertions, 51 deletions
diff --git a/kernel/drivers/clk/mmp/Makefile b/kernel/drivers/clk/mmp/Makefile index 3caaf7cc1..9d4bc41e4 100644 --- a/kernel/drivers/clk/mmp/Makefile +++ b/kernel/drivers/clk/mmp/Makefile @@ -12,3 +12,5 @@ obj-$(CONFIG_MACH_MMP2_DT) += clk-of-mmp2.o obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o + +obj-y += clk-of-pxa1928.o diff --git a/kernel/drivers/clk/mmp/clk-apbc.c b/kernel/drivers/clk/mmp/clk-apbc.c index d14120eaa..4c717db05 100644 --- a/kernel/drivers/clk/mmp/clk-apbc.c +++ b/kernel/drivers/clk/mmp/clk-apbc.c @@ -10,7 +10,6 @@ */ #include <linux/kernel.h> -#include <linux/clk.h> #include <linux/io.h> #include <linux/err.h> #include <linux/delay.h> @@ -115,7 +114,7 @@ static void clk_apbc_unprepare(struct clk_hw *hw) spin_unlock_irqrestore(apbc->lock, flags); } -struct clk_ops clk_apbc_ops = { +static struct clk_ops clk_apbc_ops = { .prepare = clk_apbc_prepare, .unprepare = clk_apbc_unprepare, }; diff --git a/kernel/drivers/clk/mmp/clk-apmu.c b/kernel/drivers/clk/mmp/clk-apmu.c index abe182b23..47b5542ce 100644 --- a/kernel/drivers/clk/mmp/clk-apmu.c +++ b/kernel/drivers/clk/mmp/clk-apmu.c @@ -10,7 +10,6 @@ */ #include <linux/kernel.h> -#include <linux/clk.h> #include <linux/io.h> #include <linux/err.h> #include <linux/delay.h> @@ -61,7 +60,7 @@ static void clk_apmu_disable(struct clk_hw *hw) spin_unlock_irqrestore(apmu->lock, flags); } -struct clk_ops clk_apmu_ops = { +static struct clk_ops clk_apmu_ops = { .enable = clk_apmu_enable, .disable = clk_apmu_disable, }; diff --git a/kernel/drivers/clk/mmp/clk-gate.c b/kernel/drivers/clk/mmp/clk-gate.c index adbd9d64d..d20cd3431 100644 --- a/kernel/drivers/clk/mmp/clk-gate.c +++ b/kernel/drivers/clk/mmp/clk-gate.c @@ -27,7 +27,6 @@ static int mmp_clk_gate_enable(struct clk_hw *hw) { struct mmp_clk_gate *gate = to_clk_mmp_gate(hw); - struct clk *clk = hw->clk; unsigned long flags = 0; unsigned long rate; u32 tmp; @@ -44,7 +43,7 @@ static int mmp_clk_gate_enable(struct clk_hw *hw) spin_unlock_irqrestore(gate->lock, flags); if (gate->flags & MMP_CLK_GATE_NEED_DELAY) { - rate = __clk_get_rate(clk); + rate = clk_hw_get_rate(hw); /* Need delay 2 cycles. */ udelay(2000000/rate); } diff --git a/kernel/drivers/clk/mmp/clk-mix.c b/kernel/drivers/clk/mmp/clk-mix.c index de6a87317..c554833cf 100644 --- a/kernel/drivers/clk/mmp/clk-mix.c +++ b/kernel/drivers/clk/mmp/clk-mix.c @@ -63,7 +63,7 @@ static unsigned int _get_div(struct mmp_clk_mix *mix, unsigned int val) static unsigned int _get_mux(struct mmp_clk_mix *mix, unsigned int val) { - int num_parents = __clk_get_num_parents(mix->hw.clk); + int num_parents = clk_hw_get_num_parents(&mix->hw); int i; if (mix->mux_flags & CLK_MUX_INDEX_BIT) @@ -113,15 +113,15 @@ static void _filter_clk_table(struct mmp_clk_mix *mix, { int i; struct mmp_clk_mix_clk_table *item; - struct clk *parent, *clk; + struct clk_hw *parent, *hw; unsigned long parent_rate; - clk = mix->hw.clk; + hw = &mix->hw; for (i = 0; i < table_size; i++) { item = &table[i]; - parent = clk_get_parent_by_index(clk, item->parent_index); - parent_rate = __clk_get_rate(parent); + parent = clk_hw_get_parent_by_index(hw, item->parent_index); + parent_rate = clk_hw_get_rate(parent); if (parent_rate % item->rate) { item->valid = 0; } else { @@ -181,7 +181,7 @@ static int _set_rate(struct mmp_clk_mix *mix, u32 mux_val, u32 div_val, if (timeout == 0) { pr_err("%s:%s cannot do frequency change\n", - __func__, __clk_get_name(mix->hw.clk)); + __func__, clk_hw_get_name(&mix->hw)); ret = -EBUSY; goto error; } @@ -201,27 +201,22 @@ error: return ret; } -static long mmp_clk_mix_determine_rate(struct clk_hw *hw, unsigned long rate, - unsigned long min_rate, - unsigned long max_rate, - unsigned long *best_parent_rate, - struct clk_hw **best_parent_clk) +static int mmp_clk_mix_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct mmp_clk_mix *mix = to_clk_mix(hw); struct mmp_clk_mix_clk_table *item; - struct clk *parent, *parent_best, *mix_clk; + struct clk_hw *parent, *parent_best; unsigned long parent_rate, mix_rate, mix_rate_best, parent_rate_best; unsigned long gap, gap_best; u32 div_val_max; unsigned int div; int i, j; - mix_clk = hw->clk; - parent = NULL; mix_rate_best = 0; parent_rate_best = 0; - gap_best = rate; + gap_best = ULONG_MAX; parent_best = NULL; if (mix->table) { @@ -229,11 +224,11 @@ static long mmp_clk_mix_determine_rate(struct clk_hw *hw, unsigned long rate, item = &mix->table[i]; if (item->valid == 0) continue; - parent = clk_get_parent_by_index(mix_clk, + parent = clk_hw_get_parent_by_index(hw, item->parent_index); - parent_rate = __clk_get_rate(parent); + parent_rate = clk_hw_get_rate(parent); mix_rate = parent_rate / item->divisor; - gap = abs(mix_rate - rate); + gap = abs(mix_rate - req->rate); if (parent_best == NULL || gap < gap_best) { parent_best = parent; parent_rate_best = parent_rate; @@ -244,14 +239,14 @@ static long mmp_clk_mix_determine_rate(struct clk_hw *hw, unsigned long rate, } } } else { - for (i = 0; i < __clk_get_num_parents(mix_clk); i++) { - parent = clk_get_parent_by_index(mix_clk, i); - parent_rate = __clk_get_rate(parent); + for (i = 0; i < clk_hw_get_num_parents(hw); i++) { + parent = clk_hw_get_parent_by_index(hw, i); + parent_rate = clk_hw_get_rate(parent); div_val_max = _get_maxdiv(mix); for (j = 0; j < div_val_max; j++) { div = _get_div(mix, j); mix_rate = parent_rate / div; - gap = abs(mix_rate - rate); + gap = abs(mix_rate - req->rate); if (parent_best == NULL || gap < gap_best) { parent_best = parent; parent_rate_best = parent_rate; @@ -265,10 +260,14 @@ static long mmp_clk_mix_determine_rate(struct clk_hw *hw, unsigned long rate, } found: - *best_parent_rate = parent_rate_best; - *best_parent_clk = __clk_get_hw(parent_best); + if (!parent_best) + return -EINVAL; + + req->best_parent_rate = parent_rate_best; + req->best_parent_hw = parent_best; + req->rate = mix_rate_best; - return mix_rate_best; + return 0; } static int mmp_clk_mix_set_rate_and_parent(struct clk_hw *hw, @@ -381,20 +380,19 @@ static int mmp_clk_set_rate(struct clk_hw *hw, unsigned long rate, struct mmp_clk_mix_clk_table *item; unsigned long parent_rate; unsigned int best_divisor; - struct clk *mix_clk, *parent; + struct clk_hw *parent; int i; best_divisor = best_parent_rate / rate; - mix_clk = hw->clk; if (mix->table) { for (i = 0; i < mix->table_size; i++) { item = &mix->table[i]; if (item->valid == 0) continue; - parent = clk_get_parent_by_index(mix_clk, + parent = clk_hw_get_parent_by_index(hw, item->parent_index); - parent_rate = __clk_get_rate(parent); + parent_rate = clk_hw_get_rate(parent); if (parent_rate == best_parent_rate && item->divisor == best_divisor) break; @@ -407,13 +405,13 @@ static int mmp_clk_set_rate(struct clk_hw *hw, unsigned long rate, else return -EINVAL; } else { - for (i = 0; i < __clk_get_num_parents(mix_clk); i++) { - parent = clk_get_parent_by_index(mix_clk, i); - parent_rate = __clk_get_rate(parent); + for (i = 0; i < clk_hw_get_num_parents(hw); i++) { + parent = clk_hw_get_parent_by_index(hw, i); + parent_rate = clk_hw_get_rate(parent); if (parent_rate == best_parent_rate) break; } - if (i < __clk_get_num_parents(mix_clk)) + if (i < clk_hw_get_num_parents(hw)) return _set_rate(mix, _get_mux_val(mix, i), _get_div_val(mix, best_divisor), 1, 1); else @@ -468,20 +466,20 @@ struct clk *mmp_clk_register_mix(struct device *dev, memcpy(&mix->reg_info, &config->reg_info, sizeof(config->reg_info)); if (config->table) { table_bytes = sizeof(*config->table) * config->table_size; - mix->table = kzalloc(table_bytes, GFP_KERNEL); + mix->table = kmemdup(config->table, table_bytes, GFP_KERNEL); if (!mix->table) { pr_err("%s:%s: could not allocate mmp mix table\n", __func__, name); kfree(mix); return ERR_PTR(-ENOMEM); } - memcpy(mix->table, config->table, table_bytes); mix->table_size = config->table_size; } if (config->mux_table) { table_bytes = sizeof(u32) * num_parents; - mix->mux_table = kzalloc(table_bytes, GFP_KERNEL); + mix->mux_table = kmemdup(config->mux_table, table_bytes, + GFP_KERNEL); if (!mix->mux_table) { pr_err("%s:%s: could not allocate mmp mix mux-table\n", __func__, name); @@ -489,7 +487,6 @@ struct clk *mmp_clk_register_mix(struct device *dev, kfree(mix); return ERR_PTR(-ENOMEM); } - memcpy(mix->mux_table, config->mux_table, table_bytes); } mix->div_flags = config->div_flags; diff --git a/kernel/drivers/clk/mmp/clk-mmp2.c b/kernel/drivers/clk/mmp/clk-mmp2.c index 5c90a4230..71fd29348 100644 --- a/kernel/drivers/clk/mmp/clk-mmp2.c +++ b/kernel/drivers/clk/mmp/clk-mmp2.c @@ -9,6 +9,7 @@ * warranty of any kind, whether express or implied. */ +#include <linux/clk.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/spinlock.h> @@ -63,10 +64,8 @@ static struct mmp_clk_factor_masks uart_factor_masks = { }; static struct mmp_clk_factor_tbl uart_factor_tbl[] = { - {.num = 14634, .den = 2165}, /*14.745MHZ */ + {.num = 8125, .den = 1536}, /*14.745MHZ */ {.num = 3521, .den = 689}, /*19.23MHZ */ - {.num = 9679, .den = 5728}, /*58.9824MHZ */ - {.num = 15850, .den = 9451}, /*59.429MHZ */ }; static const char *uart_parent[] = {"uart_pll", "vctcxo"}; diff --git a/kernel/drivers/clk/mmp/clk-of-mmp2.c b/kernel/drivers/clk/mmp/clk-of-mmp2.c index 2cbc2b43a..251533d87 100644 --- a/kernel/drivers/clk/mmp/clk-of-mmp2.c +++ b/kernel/drivers/clk/mmp/clk-of-mmp2.c @@ -30,6 +30,7 @@ #define APBC_TWSI4 0x7c #define APBC_TWSI5 0x80 #define APBC_KPC 0x18 +#define APBC_TIMER 0x24 #define APBC_UART0 0x2c #define APBC_UART1 0x30 #define APBC_UART2 0x34 @@ -98,10 +99,8 @@ static struct mmp_clk_factor_masks uart_factor_masks = { }; static struct mmp_clk_factor_tbl uart_factor_tbl[] = { - {.num = 14634, .den = 2165}, /*14.745MHZ */ + {.num = 8125, .den = 1536}, /*14.745MHZ */ {.num = 3521, .den = 689}, /*19.23MHZ */ - {.num = 9679, .den = 5728}, /*58.9824MHZ */ - {.num = 15850, .den = 9451}, /*59.429MHZ */ }; static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit) @@ -134,6 +133,9 @@ static DEFINE_SPINLOCK(ssp2_lock); static DEFINE_SPINLOCK(ssp3_lock); static const char *ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"}; +static DEFINE_SPINLOCK(timer_lock); +static const char *timer_parent_names[] = {"clk32", "vctcxo_2", "vctcxo_4", "vctcxo"}; + static DEFINE_SPINLOCK(reset_lock); static struct mmp_param_mux_clk apbc_mux_clks[] = { @@ -145,6 +147,7 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = { {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock}, {0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, &ssp2_lock}, {0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, &ssp3_lock}, + {0, "timer_mux", timer_parent_names, ARRAY_SIZE(timer_parent_names), CLK_SET_RATE_PARENT, APBC_TIMER, 4, 3, 0, &timer_lock}, }; static struct mmp_param_gate_clk apbc_gate_clks[] = { @@ -170,6 +173,7 @@ static struct mmp_param_gate_clk apbc_gate_clks[] = { {MMP2_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x7, 0x3, 0x0, 0, &ssp1_lock}, {MMP2_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x7, 0x3, 0x0, 0, &ssp2_lock}, {MMP2_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x7, 0x3, 0x0, 0, &ssp3_lock}, + {MMP2_CLK_TIMER, "timer_clk", "timer_mux", CLK_SET_RATE_PARENT, APBC_TIMER, 0x7, 0x3, 0x0, 0, &timer_lock}, }; static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit) diff --git a/kernel/drivers/clk/mmp/clk-of-pxa168.c b/kernel/drivers/clk/mmp/clk-of-pxa168.c index 5b1810dc4..64eaf4141 100644 --- a/kernel/drivers/clk/mmp/clk-of-pxa168.c +++ b/kernel/drivers/clk/mmp/clk-of-pxa168.c @@ -32,6 +32,7 @@ #define APBC_PWM1 0x10 #define APBC_PWM2 0x14 #define APBC_PWM3 0x18 +#define APBC_TIMER 0x34 #define APBC_SSP0 0x81c #define APBC_SSP1 0x820 #define APBC_SSP2 0x84c @@ -58,6 +59,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { {PXA168_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768}, {PXA168_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, {PXA168_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000}, + {PXA168_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000}, }; static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { @@ -70,6 +72,7 @@ static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { {PXA168_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0}, {PXA168_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0}, {PXA168_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0}, + {PXA168_CLK_PLL1_192, "pll1_192", "pll1_96", 1, 2, 0}, {PXA168_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0}, {PXA168_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0}, {PXA168_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0}, @@ -119,6 +122,9 @@ static DEFINE_SPINLOCK(ssp3_lock); static DEFINE_SPINLOCK(ssp4_lock); static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"}; +static DEFINE_SPINLOCK(timer_lock); +static const char *timer_parent_names[] = {"pll1_48", "clk32", "pll1_96", "pll1_192"}; + static DEFINE_SPINLOCK(reset_lock); static struct mmp_param_mux_clk apbc_mux_clks[] = { @@ -130,6 +136,7 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = { {0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, &ssp2_lock}, {0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, &ssp3_lock}, {0, "ssp4_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP4, 4, 3, 0, &ssp4_lock}, + {0, "timer_mux", timer_parent_names, ARRAY_SIZE(timer_parent_names), CLK_SET_RATE_PARENT, APBC_TIMER, 4, 3, 0, &timer_lock}, }; static struct mmp_param_gate_clk apbc_gate_clks[] = { @@ -151,6 +158,7 @@ static struct mmp_param_gate_clk apbc_gate_clks[] = { {PXA168_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x3, 0x3, 0x0, 0, &ssp2_lock}, {PXA168_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x3, 0x3, 0x0, 0, &ssp3_lock}, {PXA168_CLK_SSP4, "ssp4_clk", "ssp4_mux", CLK_SET_RATE_PARENT, APBC_SSP4, 0x3, 0x3, 0x0, 0, &ssp4_lock}, + {PXA168_CLK_TIMER, "timer_clk", "timer_mux", CLK_SET_RATE_PARENT, APBC_TIMER, 0x3, 0x3, 0x0, 0, &timer_lock}, }; static void pxa168_apb_periph_clk_init(struct pxa168_clk_unit *pxa_unit) diff --git a/kernel/drivers/clk/mmp/clk-of-pxa1928.c b/kernel/drivers/clk/mmp/clk-of-pxa1928.c new file mode 100644 index 000000000..433a5ae1e --- /dev/null +++ b/kernel/drivers/clk/mmp/clk-of-pxa1928.c @@ -0,0 +1,265 @@ +/* + * pxa1928 clock framework source file + * + * Copyright (C) 2015 Linaro, Ltd. + * Rob Herring <robh@kernel.org> + * + * Based on drivers/clk/mmp/clk-of-mmp2.c: + * Copyright (C) 2012 Marvell + * Chao Xie <xiechao.mail@gmail.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/of_address.h> +#include <linux/slab.h> +#include <linux/spinlock.h> + +#include <dt-bindings/clock/marvell,pxa1928.h> + +#include "clk.h" +#include "reset.h" + +#define MPMU_UART_PLL 0x14 + +struct pxa1928_clk_unit { + struct mmp_clk_unit unit; + void __iomem *mpmu_base; + void __iomem *apmu_base; + void __iomem *apbc_base; + void __iomem *apbcp_base; +}; + +static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { + {0, "clk32", NULL, CLK_IS_ROOT, 32768}, + {0, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, + {0, "pll1_624", NULL, CLK_IS_ROOT, 624000000}, + {0, "pll5p", NULL, CLK_IS_ROOT, 832000000}, + {0, "pll5", NULL, CLK_IS_ROOT, 1248000000}, + {0, "usb_pll", NULL, CLK_IS_ROOT, 480000000}, +}; + +static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { + {0, "pll1_d2", "pll1_624", 1, 2, 0}, + {0, "pll1_d9", "pll1_624", 1, 9, 0}, + {0, "pll1_d12", "pll1_624", 1, 12, 0}, + {0, "pll1_d16", "pll1_624", 1, 16, 0}, + {0, "pll1_d20", "pll1_624", 1, 20, 0}, + {0, "pll1_416", "pll1_624", 2, 3, 0}, + {0, "vctcxo_d2", "vctcxo", 1, 2, 0}, + {0, "vctcxo_d4", "vctcxo", 1, 4, 0}, +}; + +static struct mmp_clk_factor_masks uart_factor_masks = { + .factor = 2, + .num_mask = 0x1fff, + .den_mask = 0x1fff, + .num_shift = 16, + .den_shift = 0, +}; + +static struct mmp_clk_factor_tbl uart_factor_tbl[] = { + {.num = 832, .den = 234}, /*58.5MHZ */ + {.num = 1, .den = 1}, /*26MHZ */ +}; + +static void pxa1928_pll_init(struct pxa1928_clk_unit *pxa_unit) +{ + struct clk *clk; + struct mmp_clk_unit *unit = &pxa_unit->unit; + + mmp_register_fixed_rate_clks(unit, fixed_rate_clks, + ARRAY_SIZE(fixed_rate_clks)); + + mmp_register_fixed_factor_clks(unit, fixed_factor_clks, + ARRAY_SIZE(fixed_factor_clks)); + + clk = mmp_clk_register_factor("uart_pll", "pll1_416", + CLK_SET_RATE_PARENT, + pxa_unit->mpmu_base + MPMU_UART_PLL, + &uart_factor_masks, uart_factor_tbl, + ARRAY_SIZE(uart_factor_tbl), NULL); +} + +static DEFINE_SPINLOCK(uart0_lock); +static DEFINE_SPINLOCK(uart1_lock); +static DEFINE_SPINLOCK(uart2_lock); +static DEFINE_SPINLOCK(uart3_lock); +static const char *uart_parent_names[] = {"uart_pll", "vctcxo"}; + +static DEFINE_SPINLOCK(ssp0_lock); +static DEFINE_SPINLOCK(ssp1_lock); +static const char *ssp_parent_names[] = {"vctcxo_d4", "vctcxo_d2", "vctcxo", "pll1_d12"}; + +static DEFINE_SPINLOCK(reset_lock); + +static struct mmp_param_mux_clk apbc_mux_clks[] = { + {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_UART0 * 4, 4, 3, 0, &uart0_lock}, + {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_UART1 * 4, 4, 3, 0, &uart1_lock}, + {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_UART2 * 4, 4, 3, 0, &uart2_lock}, + {0, "uart3_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_UART3 * 4, 4, 3, 0, &uart3_lock}, + {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_SSP0 * 4, 4, 3, 0, &ssp0_lock}, + {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_SSP1 * 4, 4, 3, 0, &ssp1_lock}, +}; + +static struct mmp_param_gate_clk apbc_gate_clks[] = { + {PXA1928_CLK_TWSI0, "twsi0_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI0 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA1928_CLK_TWSI1, "twsi1_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI1 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA1928_CLK_TWSI2, "twsi2_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI2 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA1928_CLK_TWSI3, "twsi3_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI3 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA1928_CLK_TWSI4, "twsi4_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI4 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA1928_CLK_TWSI5, "twsi5_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI5 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA1928_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_GPIO * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA1928_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, PXA1928_CLK_KPC * 4, 0x3, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL}, + {PXA1928_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, PXA1928_CLK_RTC * 4, 0x83, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL}, + {PXA1928_CLK_PWM0, "pwm0_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_PWM0 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA1928_CLK_PWM1, "pwm1_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_PWM1 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA1928_CLK_PWM2, "pwm2_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_PWM2 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, + {PXA1928_CLK_PWM3, "pwm3_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_PWM3 * 4, 0x3, 0x3, 0x0, 0, &reset_lock}, + /* The gate clocks has mux parent. */ + {PXA1928_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_UART0 * 4, 0x3, 0x3, 0x0, 0, &uart0_lock}, + {PXA1928_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_UART1 * 4, 0x3, 0x3, 0x0, 0, &uart1_lock}, + {PXA1928_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_UART2 * 4, 0x3, 0x3, 0x0, 0, &uart2_lock}, + {PXA1928_CLK_UART3, "uart3_clk", "uart3_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_UART3 * 4, 0x3, 0x3, 0x0, 0, &uart3_lock}, + {PXA1928_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_SSP0 * 4, 0x3, 0x3, 0x0, 0, &ssp0_lock}, + {PXA1928_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_SSP1 * 4, 0x3, 0x3, 0x0, 0, &ssp1_lock}, +}; + +static void pxa1928_apb_periph_clk_init(struct pxa1928_clk_unit *pxa_unit) +{ + struct mmp_clk_unit *unit = &pxa_unit->unit; + + mmp_register_mux_clks(unit, apbc_mux_clks, pxa_unit->apbc_base, + ARRAY_SIZE(apbc_mux_clks)); + + mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base, + ARRAY_SIZE(apbc_gate_clks)); +} + +static DEFINE_SPINLOCK(sdh0_lock); +static DEFINE_SPINLOCK(sdh1_lock); +static DEFINE_SPINLOCK(sdh2_lock); +static DEFINE_SPINLOCK(sdh3_lock); +static DEFINE_SPINLOCK(sdh4_lock); +static const char *sdh_parent_names[] = {"pll1_624", "pll5p", "pll5", "pll1_416"}; + +static DEFINE_SPINLOCK(usb_lock); + +static struct mmp_param_mux_clk apmu_mux_clks[] = { + {0, "sdh_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_SDH0 * 4, 8, 2, 0, &sdh0_lock}, +}; + +static struct mmp_param_div_clk apmu_div_clks[] = { + {0, "sdh_div", "sdh_mux", 0, PXA1928_CLK_SDH0 * 4, 10, 4, CLK_DIVIDER_ONE_BASED, &sdh0_lock}, +}; + +static struct mmp_param_gate_clk apmu_gate_clks[] = { + {PXA1928_CLK_USB, "usb_clk", "usb_pll", 0, PXA1928_CLK_USB * 4, 0x9, 0x9, 0x0, 0, &usb_lock}, + {PXA1928_CLK_HSIC, "hsic_clk", "usb_pll", 0, PXA1928_CLK_HSIC * 4, 0x9, 0x9, 0x0, 0, &usb_lock}, + /* The gate clocks has mux parent. */ + {PXA1928_CLK_SDH0, "sdh0_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH0 * 4, 0x1b, 0x1b, 0x0, 0, &sdh0_lock}, + {PXA1928_CLK_SDH1, "sdh1_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH1 * 4, 0x1b, 0x1b, 0x0, 0, &sdh1_lock}, + {PXA1928_CLK_SDH2, "sdh2_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH2 * 4, 0x1b, 0x1b, 0x0, 0, &sdh2_lock}, + {PXA1928_CLK_SDH3, "sdh3_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH3 * 4, 0x1b, 0x1b, 0x0, 0, &sdh3_lock}, + {PXA1928_CLK_SDH4, "sdh4_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH4 * 4, 0x1b, 0x1b, 0x0, 0, &sdh4_lock}, +}; + +static void pxa1928_axi_periph_clk_init(struct pxa1928_clk_unit *pxa_unit) +{ + struct mmp_clk_unit *unit = &pxa_unit->unit; + + mmp_register_mux_clks(unit, apmu_mux_clks, pxa_unit->apmu_base, + ARRAY_SIZE(apmu_mux_clks)); + + mmp_register_div_clks(unit, apmu_div_clks, pxa_unit->apmu_base, + ARRAY_SIZE(apmu_div_clks)); + + mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base, + ARRAY_SIZE(apmu_gate_clks)); +} + +static void pxa1928_clk_reset_init(struct device_node *np, + struct pxa1928_clk_unit *pxa_unit) +{ + struct mmp_clk_reset_cell *cells; + int i, base, nr_resets; + + nr_resets = ARRAY_SIZE(apbc_gate_clks); + cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL); + if (!cells) + return; + + base = 0; + for (i = 0; i < nr_resets; i++) { + cells[base + i].clk_id = apbc_gate_clks[i].id; + cells[base + i].reg = + pxa_unit->apbc_base + apbc_gate_clks[i].offset; + cells[base + i].flags = 0; + cells[base + i].lock = apbc_gate_clks[i].lock; + cells[base + i].bits = 0x4; + } + + mmp_clk_reset_register(np, cells, nr_resets); +} + +static void __init pxa1928_mpmu_clk_init(struct device_node *np) +{ + struct pxa1928_clk_unit *pxa_unit; + + pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); + if (!pxa_unit) + return; + + pxa_unit->mpmu_base = of_iomap(np, 0); + if (!pxa_unit->mpmu_base) { + pr_err("failed to map mpmu registers\n"); + return; + } + + pxa1928_pll_init(pxa_unit); +} +CLK_OF_DECLARE(pxa1928_mpmu_clk, "marvell,pxa1928-mpmu", pxa1928_mpmu_clk_init); + +static void __init pxa1928_apmu_clk_init(struct device_node *np) +{ + struct pxa1928_clk_unit *pxa_unit; + + pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); + if (!pxa_unit) + return; + + pxa_unit->apmu_base = of_iomap(np, 0); + if (!pxa_unit->apmu_base) { + pr_err("failed to map apmu registers\n"); + return; + } + + mmp_clk_init(np, &pxa_unit->unit, PXA1928_APMU_NR_CLKS); + + pxa1928_axi_periph_clk_init(pxa_unit); +} +CLK_OF_DECLARE(pxa1928_apmu_clk, "marvell,pxa1928-apmu", pxa1928_apmu_clk_init); + +static void __init pxa1928_apbc_clk_init(struct device_node *np) +{ + struct pxa1928_clk_unit *pxa_unit; + + pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); + if (!pxa_unit) + return; + + pxa_unit->apbc_base = of_iomap(np, 0); + if (!pxa_unit->apbc_base) { + pr_err("failed to map apbc registers\n"); + return; + } + + mmp_clk_init(np, &pxa_unit->unit, PXA1928_APBC_NR_CLKS); + + pxa1928_apb_periph_clk_init(pxa_unit); + pxa1928_clk_reset_init(np, pxa_unit); +} +CLK_OF_DECLARE(pxa1928_apbc_clk, "marvell,pxa1928-apbc", pxa1928_apbc_clk_init); diff --git a/kernel/drivers/clk/mmp/clk-of-pxa910.c b/kernel/drivers/clk/mmp/clk-of-pxa910.c index 5e3c80dad..13d617332 100644 --- a/kernel/drivers/clk/mmp/clk-of-pxa910.c +++ b/kernel/drivers/clk/mmp/clk-of-pxa910.c @@ -35,6 +35,8 @@ #define APBC_SSP0 0x1c #define APBC_SSP1 0x20 #define APBC_SSP2 0x4c +#define APBC_TIMER0 0x30 +#define APBC_TIMER1 0x44 #define APBCP_TWSI1 0x28 #define APBCP_UART2 0x1c #define APMU_SDH0 0x54 @@ -57,6 +59,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { {PXA910_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768}, {PXA910_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, {PXA910_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000}, + {PXA910_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000}, }; static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { @@ -69,6 +72,7 @@ static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { {PXA910_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0}, {PXA910_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0}, {PXA910_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0}, + {PXA910_CLK_PLL1_192, "pll1_192", "pll1_96", 1, 2, 0}, {PXA910_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0}, {PXA910_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0}, {PXA910_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0}, @@ -115,6 +119,10 @@ static DEFINE_SPINLOCK(ssp0_lock); static DEFINE_SPINLOCK(ssp1_lock); static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"}; +static DEFINE_SPINLOCK(timer0_lock); +static DEFINE_SPINLOCK(timer1_lock); +static const char *timer_parent_names[] = {"pll1_48", "clk32", "pll1_96"}; + static DEFINE_SPINLOCK(reset_lock); static struct mmp_param_mux_clk apbc_mux_clks[] = { @@ -122,6 +130,8 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = { {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock}, {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP0, 4, 3, 0, &ssp0_lock}, {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock}, + {0, "timer0_mux", timer_parent_names, ARRAY_SIZE(timer_parent_names), CLK_SET_RATE_PARENT, APBC_TIMER0, 4, 3, 0, &timer0_lock}, + {0, "timer1_mux", timer_parent_names, ARRAY_SIZE(timer_parent_names), CLK_SET_RATE_PARENT, APBC_TIMER1, 4, 3, 0, &timer1_lock}, }; static struct mmp_param_mux_clk apbcp_mux_clks[] = { @@ -142,6 +152,8 @@ static struct mmp_param_gate_clk apbc_gate_clks[] = { {PXA910_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x3, 0x3, 0x0, 0, &uart1_lock}, {PXA910_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, APBC_SSP0, 0x3, 0x3, 0x0, 0, &ssp0_lock}, {PXA910_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x3, 0x3, 0x0, 0, &ssp1_lock}, + {PXA910_CLK_TIMER0, "timer0_clk", "timer0_mux", CLK_SET_RATE_PARENT, APBC_TIMER0, 0x3, 0x3, 0x0, 0, &timer0_lock}, + {PXA910_CLK_TIMER1, "timer1_clk", "timer1_mux", CLK_SET_RATE_PARENT, APBC_TIMER1, 0x3, 0x3, 0x0, 0, &timer1_lock}, }; static struct mmp_param_gate_clk apbcp_gate_clks[] = { diff --git a/kernel/drivers/clk/mmp/clk-pxa168.c b/kernel/drivers/clk/mmp/clk-pxa168.c index 93e967c0f..75244915d 100644 --- a/kernel/drivers/clk/mmp/clk-pxa168.c +++ b/kernel/drivers/clk/mmp/clk-pxa168.c @@ -9,6 +9,7 @@ * warranty of any kind, whether express or implied. */ +#include <linux/clk.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/spinlock.h> diff --git a/kernel/drivers/clk/mmp/clk-pxa910.c b/kernel/drivers/clk/mmp/clk-pxa910.c index 993abcdb3..37ba04ba1 100644 --- a/kernel/drivers/clk/mmp/clk-pxa910.c +++ b/kernel/drivers/clk/mmp/clk-pxa910.c @@ -9,6 +9,7 @@ * warranty of any kind, whether express or implied. */ +#include <linux/clk.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/spinlock.h> diff --git a/kernel/drivers/clk/mmp/clk.c b/kernel/drivers/clk/mmp/clk.c index cf038ef54..61893fe73 100644 --- a/kernel/drivers/clk/mmp/clk.c +++ b/kernel/drivers/clk/mmp/clk.c @@ -1,7 +1,6 @@ #include <linux/io.h> -#include <linux/clk.h> #include <linux/clk-provider.h> -#include <linux/clkdev.h> +#include <linux/slab.h> #include <linux/of.h> #include <linux/of_address.h> |