Commit 4d6ddb08acc48368c5b7ac431f9d00db7227d2ed
1 parent
a9e1e53bcf
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
sh: clkfwk: Support variable size accesses for MSTP clocks.
The bulk of the MSTP users require 32-bit access, but this isn't the case for some of the SH-2A parts, so add in some basic infrastructure to let the CPU define its required access size in preparation. Requested-by: Phil Edworthy <phil.edworthy@renesas.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Showing 2 changed files with 58 additions and 14 deletions Side-by-side Diff
drivers/sh/clk/cpg.c
... | ... | @@ -2,6 +2,7 @@ |
2 | 2 | * Helper routines for SuperH Clock Pulse Generator blocks (CPG). |
3 | 3 | * |
4 | 4 | * Copyright (C) 2010 Magnus Damm |
5 | + * Copyright (C) 2010 - 2012 Paul Mundt | |
5 | 6 | * |
6 | 7 | * This file is subject to the terms and conditions of the GNU General Public |
7 | 8 | * License. See the file "COPYING" in the main directory of this archive |
8 | 9 | |
9 | 10 | |
10 | 11 | |
11 | 12 | |
12 | 13 | |
... | ... | @@ -13,26 +14,41 @@ |
13 | 14 | #include <linux/io.h> |
14 | 15 | #include <linux/sh_clk.h> |
15 | 16 | |
16 | -static int sh_clk_mstp32_enable(struct clk *clk) | |
17 | +static int sh_clk_mstp_enable(struct clk *clk) | |
17 | 18 | { |
18 | - iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit), | |
19 | - clk->mapped_reg); | |
19 | + if (clk->flags & CLK_ENABLE_REG_8BIT) | |
20 | + iowrite8(ioread8(clk->mapped_reg) & ~(1 << clk->enable_bit), | |
21 | + clk->mapped_reg); | |
22 | + else if (clk->flags & CLK_ENABLE_REG_16BIT) | |
23 | + iowrite16(ioread16(clk->mapped_reg) & ~(1 << clk->enable_bit), | |
24 | + clk->mapped_reg); | |
25 | + else | |
26 | + iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit), | |
27 | + clk->mapped_reg); | |
28 | + | |
20 | 29 | return 0; |
21 | 30 | } |
22 | 31 | |
23 | -static void sh_clk_mstp32_disable(struct clk *clk) | |
32 | +static void sh_clk_mstp_disable(struct clk *clk) | |
24 | 33 | { |
25 | - iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit), | |
26 | - clk->mapped_reg); | |
34 | + if (clk->flags & CLK_ENABLE_REG_8BIT) | |
35 | + iowrite8(ioread8(clk->mapped_reg) | (1 << clk->enable_bit), | |
36 | + clk->mapped_reg); | |
37 | + else if (clk->flags & CLK_ENABLE_REG_16BIT) | |
38 | + iowrite16(ioread16(clk->mapped_reg) | (1 << clk->enable_bit), | |
39 | + clk->mapped_reg); | |
40 | + else | |
41 | + iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit), | |
42 | + clk->mapped_reg); | |
27 | 43 | } |
28 | 44 | |
29 | -static struct sh_clk_ops sh_clk_mstp32_clk_ops = { | |
30 | - .enable = sh_clk_mstp32_enable, | |
31 | - .disable = sh_clk_mstp32_disable, | |
45 | +static struct sh_clk_ops sh_clk_mstp_clk_ops = { | |
46 | + .enable = sh_clk_mstp_enable, | |
47 | + .disable = sh_clk_mstp_disable, | |
32 | 48 | .recalc = followparent_recalc, |
33 | 49 | }; |
34 | 50 | |
35 | -int __init sh_clk_mstp32_register(struct clk *clks, int nr) | |
51 | +int __init sh_clk_mstp_register(struct clk *clks, int nr) | |
36 | 52 | { |
37 | 53 | struct clk *clkp; |
38 | 54 | int ret = 0; |
... | ... | @@ -40,7 +56,7 @@ |
40 | 56 | |
41 | 57 | for (k = 0; !ret && (k < nr); k++) { |
42 | 58 | clkp = clks + k; |
43 | - clkp->ops = &sh_clk_mstp32_clk_ops; | |
59 | + clkp->ops = &sh_clk_mstp_clk_ops; | |
44 | 60 | ret |= clk_register(clkp); |
45 | 61 | } |
46 | 62 |
include/linux/sh_clk.h
... | ... | @@ -59,8 +59,16 @@ |
59 | 59 | unsigned int nr_freqs; |
60 | 60 | }; |
61 | 61 | |
62 | -#define CLK_ENABLE_ON_INIT (1 << 0) | |
62 | +#define CLK_ENABLE_ON_INIT BIT(0) | |
63 | 63 | |
64 | +#define CLK_ENABLE_REG_32BIT BIT(1) /* default access size */ | |
65 | +#define CLK_ENABLE_REG_16BIT BIT(2) | |
66 | +#define CLK_ENABLE_REG_8BIT BIT(3) | |
67 | + | |
68 | +#define CLK_ENABLE_REG_MASK (CLK_ENABLE_REG_32BIT | \ | |
69 | + CLK_ENABLE_REG_16BIT | \ | |
70 | + CLK_ENABLE_REG_8BIT) | |
71 | + | |
64 | 72 | /* drivers/sh/clk.c */ |
65 | 73 | unsigned long followparent_recalc(struct clk *); |
66 | 74 | void recalculate_root_clocks(void); |
... | ... | @@ -102,7 +110,7 @@ |
102 | 110 | unsigned long *best_freq, unsigned long *parent_freq, |
103 | 111 | unsigned int div_min, unsigned int div_max); |
104 | 112 | |
105 | -#define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags) \ | |
113 | +#define SH_CLK_MSTP(_parent, _enable_reg, _enable_bit, _flags) \ | |
106 | 114 | { \ |
107 | 115 | .parent = _parent, \ |
108 | 116 | .enable_reg = (void __iomem *)_enable_reg, \ |
... | ... | @@ -110,7 +118,27 @@ |
110 | 118 | .flags = _flags, \ |
111 | 119 | } |
112 | 120 | |
113 | -int sh_clk_mstp32_register(struct clk *clks, int nr); | |
121 | +#define SH_CLK_MSTP32(_p, _r, _b, _f) \ | |
122 | + SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_32BIT) | |
123 | + | |
124 | +#define SH_CLK_MSTP16(_p, _r, _b, _f) \ | |
125 | + SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_16BIT) | |
126 | + | |
127 | +#define SH_CLK_MSTP8(_p, _r, _b, _f) \ | |
128 | + SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_8BIT) | |
129 | + | |
130 | +int sh_clk_mstp_register(struct clk *clks, int nr); | |
131 | + | |
132 | +/* | |
133 | + * MSTP registration never really cared about access size, despite the | |
134 | + * original enable/disable pairs assuming a 32-bit access. Clocks are | |
135 | + * responsible for defining their access sizes either directly or via the | |
136 | + * clock definition wrappers. | |
137 | + */ | |
138 | +static inline int __deprecated sh_clk_mstp32_register(struct clk *clks, int nr) | |
139 | +{ | |
140 | + return sh_clk_mstp_register(clks, nr); | |
141 | +} | |
114 | 142 | |
115 | 143 | #define SH_CLK_DIV4(_parent, _reg, _shift, _div_bitmap, _flags) \ |
116 | 144 | { \ |