aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2013-03-27 03:57:38 -0400
committerSimon Horman <horms+renesas@verge.net.au>2013-04-01 22:02:18 -0400
commitec0728d67985690f329592e68f0f1fe1f2388e70 (patch)
treeacdbca0ff30915a5349da4874466f96022d24e4e
parent10d6db2ba2a68fd7d5639ce4f422ec9dff2af0e7 (diff)
ARM: shmobile: r8a7779: remove DIV4 clocks and use fixed ratio clock
R-Car H1 has many clocks, and it is possible to read/use clock ratio of these clocks from FRQMRx as DIV4 clocks. But, these ratio are fixed value and these are decided by MD pin status. This means that we can use fixed ratio clock via MD pin status, instead of DIV4 clocks. This patch reads MD pin status, and sets PLLA clock (= root clock), and used fixed ratio clock for other clocks. It was tesed on marzen board. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Acked-by: Magnus Damm <damm@opensource.se> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7779.c196
1 files changed, 109 insertions, 87 deletions
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
index d9edeaf66007..7d86bfbb5b06 100644
--- a/arch/arm/mach-shmobile/clock-r8a7779.c
+++ b/arch/arm/mach-shmobile/clock-r8a7779.c
@@ -17,13 +17,17 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20#include <linux/bitops.h>
20#include <linux/init.h> 21#include <linux/init.h>
21#include <linux/kernel.h> 22#include <linux/kernel.h>
22#include <linux/io.h> 23#include <linux/io.h>
23#include <linux/sh_clk.h> 24#include <linux/sh_clk.h>
24#include <linux/clkdev.h> 25#include <linux/clkdev.h>
26#include <mach/clock.h>
25#include <mach/common.h> 27#include <mach/common.h>
26 28
29#define MD(nr) BIT(nr)
30
27#define FRQMR IOMEM(0xffc80014) 31#define FRQMR IOMEM(0xffc80014)
28#define MSTPCR0 IOMEM(0xffc80030) 32#define MSTPCR0 IOMEM(0xffc80030)
29#define MSTPCR1 IOMEM(0xffc80034) 33#define MSTPCR1 IOMEM(0xffc80034)
@@ -36,6 +40,9 @@
36#define MSTPCR6 IOMEM(0xffc80058) 40#define MSTPCR6 IOMEM(0xffc80058)
37#define MSTPCR7 IOMEM(0xffc80040) 41#define MSTPCR7 IOMEM(0xffc80040)
38 42
43#define MODEMR 0xffcc0020
44
45
39/* ioremap() through clock mapping mandatory to avoid 46/* ioremap() through clock mapping mandatory to avoid
40 * collision with ARM coherent DMA virtual memory range. 47 * collision with ARM coherent DMA virtual memory range.
41 */ 48 */
@@ -50,40 +57,39 @@ static struct clk_mapping cpg_mapping = {
50 * from the platform code. 57 * from the platform code.
51 */ 58 */
52static struct clk plla_clk = { 59static struct clk plla_clk = {
53 .rate = 1500000000, 60 /* .rate will be updated on r8a7779_clock_init() */
54 .mapping = &cpg_mapping, 61 .mapping = &cpg_mapping,
55}; 62};
56 63
64/*
65 * clock ratio of these clock will be updated
66 * on r8a7779_clock_init()
67 */
68SH_FIXED_RATIO_CLK_SET(clkz_clk, plla_clk, 1, 1);
69SH_FIXED_RATIO_CLK_SET(clkzs_clk, plla_clk, 1, 1);
70SH_FIXED_RATIO_CLK_SET(clki_clk, plla_clk, 1, 1);
71SH_FIXED_RATIO_CLK_SET(clks_clk, plla_clk, 1, 1);
72SH_FIXED_RATIO_CLK_SET(clks1_clk, plla_clk, 1, 1);
73SH_FIXED_RATIO_CLK_SET(clks3_clk, plla_clk, 1, 1);
74SH_FIXED_RATIO_CLK_SET(clks4_clk, plla_clk, 1, 1);
75SH_FIXED_RATIO_CLK_SET(clkb_clk, plla_clk, 1, 1);
76SH_FIXED_RATIO_CLK_SET(clkout_clk, plla_clk, 1, 1);
77SH_FIXED_RATIO_CLK_SET(clkp_clk, plla_clk, 1, 1);
78SH_FIXED_RATIO_CLK_SET(clkg_clk, plla_clk, 1, 1);
79
57static struct clk *main_clks[] = { 80static struct clk *main_clks[] = {
58 &plla_clk, 81 &plla_clk,
59}; 82 &clkz_clk,
60 83 &clkzs_clk,
61static int divisors[] = { 0, 0, 0, 6, 8, 12, 16, 0, 24, 32, 36, 0, 0, 0, 0, 0 }; 84 &clki_clk,
62 85 &clks_clk,
63static struct clk_div_mult_table div4_div_mult_table = { 86 &clks1_clk,
64 .divisors = divisors, 87 &clks3_clk,
65 .nr_divisors = ARRAY_SIZE(divisors), 88 &clks4_clk,
66}; 89 &clkb_clk,
67 90 &clkout_clk,
68static struct clk_div4_table div4_table = { 91 &clkp_clk,
69 .div_mult_table = &div4_div_mult_table, 92 &clkg_clk,
70};
71
72enum { DIV4_S, DIV4_OUT, DIV4_S4, DIV4_S3, DIV4_S1, DIV4_P, DIV4_NR };
73
74static struct clk div4_clks[DIV4_NR] = {
75 [DIV4_S] = SH_CLK_DIV4(&plla_clk, FRQMR, 20,
76 0x0018, CLK_ENABLE_ON_INIT),
77 [DIV4_OUT] = SH_CLK_DIV4(&plla_clk, FRQMR, 16,
78 0x0700, CLK_ENABLE_ON_INIT),
79 [DIV4_S4] = SH_CLK_DIV4(&plla_clk, FRQMR, 12,
80 0x0040, CLK_ENABLE_ON_INIT),
81 [DIV4_S3] = SH_CLK_DIV4(&plla_clk, FRQMR, 8,
82 0x0010, CLK_ENABLE_ON_INIT),
83 [DIV4_S1] = SH_CLK_DIV4(&plla_clk, FRQMR, 4,
84 0x0060, CLK_ENABLE_ON_INIT),
85 [DIV4_P] = SH_CLK_DIV4(&plla_clk, FRQMR, 0,
86 0x0300, CLK_ENABLE_ON_INIT),
87}; 93};
88 94
89enum { MSTP323, MSTP322, MSTP321, MSTP320, 95enum { MSTP323, MSTP322, MSTP321, MSTP320,
@@ -96,52 +102,28 @@ enum { MSTP323, MSTP322, MSTP321, MSTP320,
96 MSTP_NR }; 102 MSTP_NR };
97 103
98static struct clk mstp_clks[MSTP_NR] = { 104static struct clk mstp_clks[MSTP_NR] = {
99 [MSTP323] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 23, 0), /* SDHI0 */ 105 [MSTP323] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 23, 0), /* SDHI0 */
100 [MSTP322] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 22, 0), /* SDHI1 */ 106 [MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */
101 [MSTP321] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 21, 0), /* SDHI2 */ 107 [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
102 [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 20, 0), /* SDHI3 */ 108 [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
103 [MSTP115] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 15, 0), /* SATA */ 109 [MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */
104 [MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_S], MSTPCR1, 3, 0), /* DU */ 110 [MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 3, 0), /* DU */
105 [MSTP101] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 1, 0), /* USB2 */ 111 [MSTP101] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 1, 0), /* USB2 */
106 [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 0, 0), /* USB0/1 */ 112 [MSTP100] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 0, 0), /* USB0/1 */
107 [MSTP030] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 30, 0), /* I2C0 */ 113 [MSTP030] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 30, 0), /* I2C0 */
108 [MSTP029] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 29, 0), /* I2C1 */ 114 [MSTP029] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 29, 0), /* I2C1 */
109 [MSTP028] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 28, 0), /* I2C2 */ 115 [MSTP028] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 28, 0), /* I2C2 */
110 [MSTP027] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 27, 0), /* I2C3 */ 116 [MSTP027] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 27, 0), /* I2C3 */
111 [MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0), /* SCIF0 */ 117 [MSTP026] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 26, 0), /* SCIF0 */
112 [MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0), /* SCIF1 */ 118 [MSTP025] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 25, 0), /* SCIF1 */
113 [MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0), /* SCIF2 */ 119 [MSTP024] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 24, 0), /* SCIF2 */
114 [MSTP023] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 23, 0), /* SCIF3 */ 120 [MSTP023] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 23, 0), /* SCIF3 */
115 [MSTP022] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 22, 0), /* SCIF4 */ 121 [MSTP022] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 22, 0), /* SCIF4 */
116 [MSTP021] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 21, 0), /* SCIF5 */ 122 [MSTP021] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 21, 0), /* SCIF5 */
117 [MSTP016] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 16, 0), /* TMU0 */ 123 [MSTP016] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 16, 0), /* TMU0 */
118 [MSTP015] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0), /* TMU1 */ 124 [MSTP015] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 15, 0), /* TMU1 */
119 [MSTP014] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 14, 0), /* TMU2 */ 125 [MSTP014] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 14, 0), /* TMU2 */
120 [MSTP007] = SH_CLK_MSTP32(&div4_clks[DIV4_S], MSTPCR0, 7, 0), /* HSPI */ 126 [MSTP007] = SH_CLK_MSTP32(&clks_clk, MSTPCR0, 7, 0), /* HSPI */
121};
122
123static unsigned long mul4_recalc(struct clk *clk)
124{
125 return clk->parent->rate * 4;
126}
127
128static struct sh_clk_ops mul4_clk_ops = {
129 .recalc = mul4_recalc,
130};
131
132struct clk clkz_clk = {
133 .ops = &mul4_clk_ops,
134 .parent = &div4_clks[DIV4_S],
135};
136
137struct clk clkzs_clk = {
138 /* clks x 4 / 4 = clks */
139 .parent = &div4_clks[DIV4_S],
140};
141
142static struct clk *late_main_clks[] = {
143 &clkz_clk,
144 &clkzs_clk,
145}; 127};
146 128
147static struct clk_lookup lookups[] = { 129static struct clk_lookup lookups[] = {
@@ -151,12 +133,12 @@ static struct clk_lookup lookups[] = {
151 CLKDEV_CON_ID("clkzs_clk", &clkzs_clk), 133 CLKDEV_CON_ID("clkzs_clk", &clkzs_clk),
152 134
153 /* DIV4 clocks */ 135 /* DIV4 clocks */
154 CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_S]), 136 CLKDEV_CON_ID("shyway_clk", &clks_clk),
155 CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_OUT]), 137 CLKDEV_CON_ID("bus_clk", &clkout_clk),
156 CLKDEV_CON_ID("shyway4_clk", &div4_clks[DIV4_S4]), 138 CLKDEV_CON_ID("shyway4_clk", &clks4_clk),
157 CLKDEV_CON_ID("shyway3_clk", &div4_clks[DIV4_S3]), 139 CLKDEV_CON_ID("shyway3_clk", &clks3_clk),
158 CLKDEV_CON_ID("shyway1_clk", &div4_clks[DIV4_S1]), 140 CLKDEV_CON_ID("shyway1_clk", &clks1_clk),
159 CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), 141 CLKDEV_CON_ID("peripheral_clk", &clkp_clk),
160 142
161 /* MSTP32 clocks */ 143 /* MSTP32 clocks */
162 CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */ 144 CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
@@ -190,20 +172,60 @@ static struct clk_lookup lookups[] = {
190 172
191void __init r8a7779_clock_init(void) 173void __init r8a7779_clock_init(void)
192{ 174{
175 void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
176 u32 mode;
193 int k, ret = 0; 177 int k, ret = 0;
194 178
179 BUG_ON(!modemr);
180 mode = ioread32(modemr);
181 iounmap(modemr);
182
183 if (mode & MD(1)) {
184 plla_clk.rate = 1500000000;
185
186 SH_CLK_SET_RATIO(&clkz_clk_ratio, 2, 3);
187 SH_CLK_SET_RATIO(&clkzs_clk_ratio, 1, 6);
188 SH_CLK_SET_RATIO(&clki_clk_ratio, 1, 2);
189 SH_CLK_SET_RATIO(&clks_clk_ratio, 1, 6);
190 SH_CLK_SET_RATIO(&clks1_clk_ratio, 1, 12);
191 SH_CLK_SET_RATIO(&clks3_clk_ratio, 1, 8);
192 SH_CLK_SET_RATIO(&clks4_clk_ratio, 1, 16);
193 SH_CLK_SET_RATIO(&clkp_clk_ratio, 1, 24);
194 SH_CLK_SET_RATIO(&clkg_clk_ratio, 1, 24);
195 if (mode & MD(2)) {
196 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 36);
197 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 36);
198 } else {
199 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 24);
200 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 24);
201 }
202 } else {
203 plla_clk.rate = 1600000000;
204
205 SH_CLK_SET_RATIO(&clkz_clk_ratio, 1, 2);
206 SH_CLK_SET_RATIO(&clkzs_clk_ratio, 1, 8);
207 SH_CLK_SET_RATIO(&clki_clk_ratio, 1, 2);
208 SH_CLK_SET_RATIO(&clks_clk_ratio, 1, 8);
209 SH_CLK_SET_RATIO(&clks1_clk_ratio, 1, 16);
210 SH_CLK_SET_RATIO(&clks3_clk_ratio, 1, 8);
211 SH_CLK_SET_RATIO(&clks4_clk_ratio, 1, 16);
212 SH_CLK_SET_RATIO(&clkp_clk_ratio, 1, 32);
213 SH_CLK_SET_RATIO(&clkg_clk_ratio, 1, 24);
214 if (mode & MD(2)) {
215 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 32);
216 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 32);
217 } else {
218 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 24);
219 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 24);
220 }
221 }
222
195 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) 223 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
196 ret = clk_register(main_clks[k]); 224 ret = clk_register(main_clks[k]);
197 225
198 if (!ret) 226 if (!ret)
199 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
200
201 if (!ret)
202 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); 227 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
203 228
204 for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
205 ret = clk_register(late_main_clks[k]);
206
207 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 229 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
208 230
209 if (!ret) 231 if (!ret)