Commit 4d6ddb08acc48368c5b7ac431f9d00db7227d2ed

Authored by Paul Mundt
1 parent a9e1e53bcf

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 { \