diff options
-rw-r--r-- | drivers/clk/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/pxa/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/pxa/clk-pxa.c | 97 | ||||
-rw-r--r-- | drivers/clk/pxa/clk-pxa.h | 107 | ||||
-rw-r--r-- | include/dt-bindings/clock/pxa-clock.h | 77 |
5 files changed, 283 insertions, 0 deletions
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index f537a0b1f798..7891e4edaa07 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -48,6 +48,7 @@ obj-$(CONFIG_ARCH_MMP) += mmp/ | |||
48 | endif | 48 | endif |
49 | obj-$(CONFIG_PLAT_ORION) += mvebu/ | 49 | obj-$(CONFIG_PLAT_ORION) += mvebu/ |
50 | obj-$(CONFIG_ARCH_MXS) += mxs/ | 50 | obj-$(CONFIG_ARCH_MXS) += mxs/ |
51 | obj-$(CONFIG_ARCH_PXA) += pxa/ | ||
51 | obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ | 52 | obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ |
52 | obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ | 53 | obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ |
53 | obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ | 54 | obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ |
diff --git a/drivers/clk/pxa/Makefile b/drivers/clk/pxa/Makefile new file mode 100644 index 000000000000..cb2bd8ff53da --- /dev/null +++ b/drivers/clk/pxa/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-y += clk-pxa.o | |||
diff --git a/drivers/clk/pxa/clk-pxa.c b/drivers/clk/pxa/clk-pxa.c new file mode 100644 index 000000000000..ef3c05389c0a --- /dev/null +++ b/drivers/clk/pxa/clk-pxa.c | |||
@@ -0,0 +1,97 @@ | |||
1 | /* | ||
2 | * Marvell PXA family clocks | ||
3 | * | ||
4 | * Copyright (C) 2014 Robert Jarzmik | ||
5 | * | ||
6 | * Common clock code for PXA clocks ("CKEN" type clocks + DT) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | */ | ||
13 | #include <linux/clk.h> | ||
14 | #include <linux/clk-provider.h> | ||
15 | #include <linux/clkdev.h> | ||
16 | #include <linux/of.h> | ||
17 | |||
18 | #include <dt-bindings/clock/pxa-clock.h> | ||
19 | #include "clk-pxa.h" | ||
20 | |||
21 | DEFINE_SPINLOCK(lock); | ||
22 | |||
23 | static struct clk *pxa_clocks[CLK_MAX]; | ||
24 | static struct clk_onecell_data onecell_data = { | ||
25 | .clks = pxa_clocks, | ||
26 | .clk_num = CLK_MAX, | ||
27 | }; | ||
28 | |||
29 | #define to_pxa_clk(_hw) container_of(_hw, struct pxa_clk_cken, hw) | ||
30 | |||
31 | static unsigned long cken_recalc_rate(struct clk_hw *hw, | ||
32 | unsigned long parent_rate) | ||
33 | { | ||
34 | struct pxa_clk_cken *pclk = to_pxa_clk(hw); | ||
35 | struct clk_fixed_factor *fix; | ||
36 | |||
37 | if (!pclk->is_in_low_power || pclk->is_in_low_power()) | ||
38 | fix = &pclk->lp; | ||
39 | else | ||
40 | fix = &pclk->hp; | ||
41 | fix->hw.clk = hw->clk; | ||
42 | return clk_fixed_factor_ops.recalc_rate(&fix->hw, parent_rate); | ||
43 | } | ||
44 | |||
45 | static struct clk_ops cken_rate_ops = { | ||
46 | .recalc_rate = cken_recalc_rate, | ||
47 | }; | ||
48 | |||
49 | static u8 cken_get_parent(struct clk_hw *hw) | ||
50 | { | ||
51 | struct pxa_clk_cken *pclk = to_pxa_clk(hw); | ||
52 | |||
53 | if (!pclk->is_in_low_power) | ||
54 | return 0; | ||
55 | return pclk->is_in_low_power() ? 0 : 1; | ||
56 | } | ||
57 | |||
58 | static struct clk_ops cken_mux_ops = { | ||
59 | .get_parent = cken_get_parent, | ||
60 | .set_parent = dummy_clk_set_parent, | ||
61 | }; | ||
62 | |||
63 | void __init clkdev_pxa_register(int ckid, const char *con_id, | ||
64 | const char *dev_id, struct clk *clk) | ||
65 | { | ||
66 | if (!IS_ERR(clk) && (ckid != CLK_NONE)) | ||
67 | pxa_clocks[ckid] = clk; | ||
68 | if (!IS_ERR(clk)) | ||
69 | clk_register_clkdev(clk, con_id, dev_id); | ||
70 | } | ||
71 | |||
72 | int __init clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks) | ||
73 | { | ||
74 | int i; | ||
75 | struct pxa_clk_cken *pclk; | ||
76 | struct clk *clk; | ||
77 | |||
78 | for (i = 0; i < nb_clks; i++) { | ||
79 | pclk = clks + i; | ||
80 | pclk->gate.lock = &lock; | ||
81 | clk = clk_register_composite(NULL, pclk->name, | ||
82 | pclk->parent_names, 2, | ||
83 | &pclk->hw, &cken_mux_ops, | ||
84 | &pclk->hw, &cken_rate_ops, | ||
85 | &pclk->gate.hw, &clk_gate_ops, | ||
86 | pclk->flags); | ||
87 | clkdev_pxa_register(pclk->ckid, pclk->con_id, pclk->dev_id, | ||
88 | clk); | ||
89 | } | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static void __init pxa_dt_clocks_init(struct device_node *np) | ||
94 | { | ||
95 | of_clk_add_provider(np, of_clk_src_onecell_get, &onecell_data); | ||
96 | } | ||
97 | CLK_OF_DECLARE(pxa_clks, "marvell,pxa-clocks", pxa_dt_clocks_init); | ||
diff --git a/drivers/clk/pxa/clk-pxa.h b/drivers/clk/pxa/clk-pxa.h new file mode 100644 index 000000000000..5fe219d06b49 --- /dev/null +++ b/drivers/clk/pxa/clk-pxa.h | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * Marvell PXA family clocks | ||
3 | * | ||
4 | * Copyright (C) 2014 Robert Jarzmik | ||
5 | * | ||
6 | * Common clock code for PXA clocks ("CKEN" type clocks + DT) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | */ | ||
13 | #ifndef _CLK_PXA_ | ||
14 | #define _CLK_PXA_ | ||
15 | |||
16 | #define PARENTS(name) \ | ||
17 | static const char *name ## _parents[] __initconst | ||
18 | #define MUX_RO_RATE_RO_OPS(name, clk_name) \ | ||
19 | static struct clk_hw name ## _mux_hw; \ | ||
20 | static struct clk_hw name ## _rate_hw; \ | ||
21 | static struct clk_ops name ## _mux_ops = { \ | ||
22 | .get_parent = name ## _get_parent, \ | ||
23 | .set_parent = dummy_clk_set_parent, \ | ||
24 | }; \ | ||
25 | static struct clk_ops name ## _rate_ops = { \ | ||
26 | .recalc_rate = name ## _get_rate, \ | ||
27 | }; \ | ||
28 | static struct clk *clk_register_ ## name(void) \ | ||
29 | { \ | ||
30 | return clk_register_composite(NULL, clk_name, \ | ||
31 | name ## _parents, \ | ||
32 | ARRAY_SIZE(name ## _parents), \ | ||
33 | &name ## _mux_hw, &name ## _mux_ops, \ | ||
34 | &name ## _rate_hw, &name ## _rate_ops, \ | ||
35 | NULL, NULL, CLK_GET_RATE_NOCACHE); \ | ||
36 | } | ||
37 | |||
38 | #define RATE_RO_OPS(name, clk_name) \ | ||
39 | static struct clk_hw name ## _rate_hw; \ | ||
40 | static struct clk_ops name ## _rate_ops = { \ | ||
41 | .recalc_rate = name ## _get_rate, \ | ||
42 | }; \ | ||
43 | static struct clk *clk_register_ ## name(void) \ | ||
44 | { \ | ||
45 | return clk_register_composite(NULL, clk_name, \ | ||
46 | name ## _parents, \ | ||
47 | ARRAY_SIZE(name ## _parents), \ | ||
48 | NULL, NULL, \ | ||
49 | &name ## _rate_hw, &name ## _rate_ops, \ | ||
50 | NULL, NULL, CLK_GET_RATE_NOCACHE); \ | ||
51 | } | ||
52 | |||
53 | /* | ||
54 | * CKEN clock type | ||
55 | * This clock takes it source from 2 possible parents : | ||
56 | * - a low power parent | ||
57 | * - a normal parent | ||
58 | * | ||
59 | * +------------+ +-----------+ | ||
60 | * | Low Power | --- | x mult_lp | | ||
61 | * | Clock | | / div_lp |\ | ||
62 | * +------------+ +-----------+ \+-----+ +-----------+ | ||
63 | * | Mux |---| CKEN gate | | ||
64 | * +------------+ +-----------+ /+-----+ +-----------+ | ||
65 | * | High Power | | x mult_hp |/ | ||
66 | * | Clock | --- | / div_hp | | ||
67 | * +------------+ +-----------+ | ||
68 | */ | ||
69 | struct pxa_clk_cken { | ||
70 | struct clk_hw hw; | ||
71 | int ckid; | ||
72 | const char *name; | ||
73 | const char *dev_id; | ||
74 | const char *con_id; | ||
75 | const char **parent_names; | ||
76 | struct clk_fixed_factor lp; | ||
77 | struct clk_fixed_factor hp; | ||
78 | struct clk_gate gate; | ||
79 | bool (*is_in_low_power)(void); | ||
80 | const unsigned long flags; | ||
81 | }; | ||
82 | |||
83 | #define PXA_CKEN(_dev_id, _con_id, _name, parents, _mult_lp, _div_lp, \ | ||
84 | _mult_hp, _div_hp, is_lp, _cken_reg, _cken_bit, flag) \ | ||
85 | { .ckid = CLK_ ## _name, .name = #_name, \ | ||
86 | .dev_id = _dev_id, .con_id = _con_id, .parent_names = parents,\ | ||
87 | .lp = { .mult = _mult_lp, .div = _div_lp }, \ | ||
88 | .hp = { .mult = _mult_hp, .div = _div_hp }, \ | ||
89 | .is_in_low_power = is_lp, \ | ||
90 | .gate = { .reg = (void __iomem *)_cken_reg, .bit_idx = _cken_bit }, \ | ||
91 | .flags = flag, \ | ||
92 | } | ||
93 | #define PXA_CKEN_1RATE(dev_id, con_id, name, parents, cken_reg, \ | ||
94 | cken_bit, flag) \ | ||
95 | PXA_CKEN(dev_id, con_id, name, parents, 1, 1, 1, 1, \ | ||
96 | NULL, cken_reg, cken_bit, flag) | ||
97 | |||
98 | static int dummy_clk_set_parent(struct clk_hw *hw, u8 index) | ||
99 | { | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | extern void clkdev_pxa_register(int ckid, const char *con_id, | ||
104 | const char *dev_id, struct clk *clk); | ||
105 | extern int clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks); | ||
106 | |||
107 | #endif | ||
diff --git a/include/dt-bindings/clock/pxa-clock.h b/include/dt-bindings/clock/pxa-clock.h new file mode 100644 index 000000000000..e65803b1dc7e --- /dev/null +++ b/include/dt-bindings/clock/pxa-clock.h | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * Inspired by original work from pxa2xx-regs.h by Nicolas Pitre | ||
3 | * Copyright (C) 2014 Robert Jarzmik | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #ifndef __DT_BINDINGS_CLOCK_PXA2XX_H__ | ||
12 | #define __DT_BINDINGS_CLOCK_PXA2XX_H__ | ||
13 | |||
14 | #define CLK_NONE 0 | ||
15 | #define CLK_1WIRE 1 | ||
16 | #define CLK_AC97 2 | ||
17 | #define CLK_AC97CONF 3 | ||
18 | #define CLK_ASSP 4 | ||
19 | #define CLK_BOOT 5 | ||
20 | #define CLK_BTUART 6 | ||
21 | #define CLK_CAMERA 7 | ||
22 | #define CLK_CIR 8 | ||
23 | #define CLK_CORE 9 | ||
24 | #define CLK_DMC 10 | ||
25 | #define CLK_FFUART 11 | ||
26 | #define CLK_FICP 12 | ||
27 | #define CLK_GPIO 13 | ||
28 | #define CLK_HSIO2 14 | ||
29 | #define CLK_HWUART 15 | ||
30 | #define CLK_I2C 16 | ||
31 | #define CLK_I2S 17 | ||
32 | #define CLK_IM 18 | ||
33 | #define CLK_INC 19 | ||
34 | #define CLK_ISC 20 | ||
35 | #define CLK_KEYPAD 21 | ||
36 | #define CLK_LCD 22 | ||
37 | #define CLK_MEMC 23 | ||
38 | #define CLK_MEMSTK 24 | ||
39 | #define CLK_MINI_IM 25 | ||
40 | #define CLK_MINI_LCD 26 | ||
41 | #define CLK_MMC 27 | ||
42 | #define CLK_MMC1 28 | ||
43 | #define CLK_MMC2 29 | ||
44 | #define CLK_MMC3 30 | ||
45 | #define CLK_MSL 31 | ||
46 | #define CLK_MSL0 32 | ||
47 | #define CLK_MVED 33 | ||
48 | #define CLK_NAND 34 | ||
49 | #define CLK_NSSP 35 | ||
50 | #define CLK_OSTIMER 36 | ||
51 | #define CLK_PWM0 37 | ||
52 | #define CLK_PWM1 38 | ||
53 | #define CLK_PWM2 39 | ||
54 | #define CLK_PWM3 40 | ||
55 | #define CLK_PWRI2C 41 | ||
56 | #define CLK_PXA300_GCU 42 | ||
57 | #define CLK_PXA320_GCU 43 | ||
58 | #define CLK_SMC 44 | ||
59 | #define CLK_SSP 45 | ||
60 | #define CLK_SSP1 46 | ||
61 | #define CLK_SSP2 47 | ||
62 | #define CLK_SSP3 48 | ||
63 | #define CLK_SSP4 49 | ||
64 | #define CLK_STUART 50 | ||
65 | #define CLK_TOUCH 51 | ||
66 | #define CLK_TPM 52 | ||
67 | #define CLK_UDC 53 | ||
68 | #define CLK_USB 54 | ||
69 | #define CLK_USB2 55 | ||
70 | #define CLK_USBH 56 | ||
71 | #define CLK_USBHOST 57 | ||
72 | #define CLK_USIM 58 | ||
73 | #define CLK_USIM1 59 | ||
74 | #define CLK_USMI0 60 | ||
75 | #define CLK_MAX 61 | ||
76 | |||
77 | #endif | ||