diff options
author | Hisashi Nakamura <hisashi.nakamura.ak@renesas.com> | 2013-09-03 23:45:57 -0400 |
---|---|---|
committer | Simon Horman <horms+renesas@verge.net.au> | 2013-09-30 03:11:12 -0400 |
commit | 0d0771ab2bd5f57a62db91f26bba1e9f522d16cb (patch) | |
tree | a8cee5b33c65e136837a3e28ba6c4d005b2700d1 /arch/arm/mach-shmobile/clock-r8a7791.c | |
parent | a93c2aaf18e0e10084c099a0ba2460ab8e3c0e05 (diff) |
ARM: shmobile: Initial r8a7791 SoC support
Add initial support for the r8a7791 SoC including:
- Single Cortex-A15 CPU Core
- GIC
No static virtual mappings are used, all the components
make use of ioremap(). DT_MACHINE_START is still wrapped
in CONFIG_USE_OF to match other mach-shmobile code.
Signed-off-by: Hisashi Nakamura <hisashi.nakamura.ak@renesas.com>
Signed-off-by: Ryo Kataoka <ryo.kataoka.wt@renesas.com>
[damm@opensource.se: Forward ported to upstream, dropped not-yet-ready code]
Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Diffstat (limited to 'arch/arm/mach-shmobile/clock-r8a7791.c')
-rw-r--r-- | arch/arm/mach-shmobile/clock-r8a7791.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c new file mode 100644 index 000000000000..9929feb1b810 --- /dev/null +++ b/arch/arm/mach-shmobile/clock-r8a7791.c | |||
@@ -0,0 +1,198 @@ | |||
1 | /* | ||
2 | * r8a7791 clock framework support | ||
3 | * | ||
4 | * Copyright (C) 2013 Renesas Electronics Corporation | ||
5 | * Copyright (C) 2013 Renesas Solutions Corp. | ||
6 | * Copyright (C) 2013 Magnus Damm | ||
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 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | */ | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/sh_clk.h> | ||
25 | #include <linux/clkdev.h> | ||
26 | #include <mach/clock.h> | ||
27 | #include <mach/common.h> | ||
28 | |||
29 | /* | ||
30 | * MD EXTAL PLL0 PLL1 PLL3 | ||
31 | * 14 13 19 (MHz) *1 *1 | ||
32 | *--------------------------------------------------- | ||
33 | * 0 0 0 15 x 1 x172/2 x208/2 x106 | ||
34 | * 0 0 1 15 x 1 x172/2 x208/2 x88 | ||
35 | * 0 1 0 20 x 1 x130/2 x156/2 x80 | ||
36 | * 0 1 1 20 x 1 x130/2 x156/2 x66 | ||
37 | * 1 0 0 26 / 2 x200/2 x240/2 x122 | ||
38 | * 1 0 1 26 / 2 x200/2 x240/2 x102 | ||
39 | * 1 1 0 30 / 2 x172/2 x208/2 x106 | ||
40 | * 1 1 1 30 / 2 x172/2 x208/2 x88 | ||
41 | * | ||
42 | * *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2) | ||
43 | * see "p1 / 2" on R8A7791_CLOCK_ROOT() below | ||
44 | */ | ||
45 | |||
46 | #define MD(nr) (1 << nr) | ||
47 | |||
48 | #define CPG_BASE 0xe6150000 | ||
49 | #define CPG_LEN 0x1000 | ||
50 | |||
51 | #define SMSTPCR1 0xE6150134 | ||
52 | #define SMSTPCR2 0xe6150138 | ||
53 | #define SMSTPCR3 0xE615013C | ||
54 | #define SMSTPCR5 0xE6150144 | ||
55 | #define SMSTPCR7 0xe615014c | ||
56 | #define SMSTPCR8 0xE6150990 | ||
57 | #define SMSTPCR9 0xE6150994 | ||
58 | #define SMSTPCR10 0xE6150998 | ||
59 | |||
60 | #define MODEMR 0xE6160060 | ||
61 | #define SDCKCR 0xE6150074 | ||
62 | #define SD2CKCR 0xE6150078 | ||
63 | #define SD3CKCR 0xE615007C | ||
64 | #define MMC0CKCR 0xE6150240 | ||
65 | #define MMC1CKCR 0xE6150244 | ||
66 | #define SSPCKCR 0xE6150248 | ||
67 | #define SSPRSCKCR 0xE615024C | ||
68 | |||
69 | static struct clk_mapping cpg_mapping = { | ||
70 | .phys = CPG_BASE, | ||
71 | .len = CPG_LEN, | ||
72 | }; | ||
73 | |||
74 | static struct clk extal_clk = { | ||
75 | /* .rate will be updated on r8a7791_clock_init() */ | ||
76 | .mapping = &cpg_mapping, | ||
77 | }; | ||
78 | |||
79 | static struct sh_clk_ops followparent_clk_ops = { | ||
80 | .recalc = followparent_recalc, | ||
81 | }; | ||
82 | |||
83 | static struct clk main_clk = { | ||
84 | /* .parent will be set r8a73a4_clock_init */ | ||
85 | .ops = &followparent_clk_ops, | ||
86 | }; | ||
87 | |||
88 | /* | ||
89 | * clock ratio of these clock will be updated | ||
90 | * on r8a7791_clock_init() | ||
91 | */ | ||
92 | SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1); | ||
93 | SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1); | ||
94 | |||
95 | /* fixed ratio clock */ | ||
96 | SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2); | ||
97 | SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2); | ||
98 | |||
99 | SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2); | ||
100 | SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12); | ||
101 | SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24); | ||
102 | |||
103 | SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15); | ||
104 | |||
105 | static struct clk *main_clks[] = { | ||
106 | &extal_clk, | ||
107 | &extal_div2_clk, | ||
108 | &main_clk, | ||
109 | &pll1_clk, | ||
110 | &pll1_div2_clk, | ||
111 | &pll3_clk, | ||
112 | &hp_clk, | ||
113 | &p_clk, | ||
114 | &mp_clk, | ||
115 | &cp_clk, | ||
116 | }; | ||
117 | |||
118 | /* MSTP */ | ||
119 | enum { | ||
120 | MSTP721, MSTP720, | ||
121 | /* MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,*/ | ||
122 | MSTP_NR | ||
123 | }; | ||
124 | |||
125 | static struct clk mstp_clks[MSTP_NR] = { | ||
126 | [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ | ||
127 | [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ | ||
128 | }; | ||
129 | |||
130 | static struct clk_lookup lookups[] = { | ||
131 | |||
132 | /* main clocks */ | ||
133 | CLKDEV_CON_ID("extal", &extal_clk), | ||
134 | CLKDEV_CON_ID("extal_div2", &extal_div2_clk), | ||
135 | CLKDEV_CON_ID("main", &main_clk), | ||
136 | CLKDEV_CON_ID("pll1", &pll1_clk), | ||
137 | CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk), | ||
138 | CLKDEV_CON_ID("pll3", &pll3_clk), | ||
139 | CLKDEV_CON_ID("hp", &hp_clk), | ||
140 | CLKDEV_CON_ID("p", &p_clk), | ||
141 | CLKDEV_CON_ID("mp", &mp_clk), | ||
142 | CLKDEV_CON_ID("cp", &cp_clk), | ||
143 | CLKDEV_CON_ID("peripheral_clk", &hp_clk), | ||
144 | }; | ||
145 | |||
146 | #define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ | ||
147 | extal_clk.rate = e * 1000 * 1000; \ | ||
148 | main_clk.parent = m; \ | ||
149 | SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \ | ||
150 | if (mode & MD(19)) \ | ||
151 | SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \ | ||
152 | else \ | ||
153 | SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1) | ||
154 | |||
155 | |||
156 | void __init r8a7791_clock_init(void) | ||
157 | { | ||
158 | void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); | ||
159 | u32 mode; | ||
160 | int k, ret = 0; | ||
161 | |||
162 | BUG_ON(!modemr); | ||
163 | mode = ioread32(modemr); | ||
164 | iounmap(modemr); | ||
165 | |||
166 | switch (mode & (MD(14) | MD(13))) { | ||
167 | case 0: | ||
168 | R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88); | ||
169 | break; | ||
170 | case MD(13): | ||
171 | R8A7791_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66); | ||
172 | break; | ||
173 | case MD(14): | ||
174 | R8A7791_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102); | ||
175 | break; | ||
176 | case MD(13) | MD(14): | ||
177 | R8A7791_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88); | ||
178 | break; | ||
179 | } | ||
180 | |||
181 | for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) | ||
182 | ret = clk_register(main_clks[k]); | ||
183 | |||
184 | if (!ret) | ||
185 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); | ||
186 | |||
187 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
188 | |||
189 | if (!ret) | ||
190 | shmobile_clk_init(); | ||
191 | else | ||
192 | goto epanic; | ||
193 | |||
194 | return; | ||
195 | |||
196 | epanic: | ||
197 | panic("failed to setup r8a7791 clocks\n"); | ||
198 | } | ||