diff options
Diffstat (limited to 'arch/sh/boards/mach-sdk7786/setup.c')
-rw-r--r-- | arch/sh/boards/mach-sdk7786/setup.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c index 2ec1ea5cf8ef..7e0c4e3878e0 100644 --- a/arch/sh/boards/mach-sdk7786/setup.c +++ b/arch/sh/boards/mach-sdk7786/setup.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <asm/machvec.h> | 20 | #include <asm/machvec.h> |
21 | #include <asm/heartbeat.h> | 21 | #include <asm/heartbeat.h> |
22 | #include <asm/sizes.h> | 22 | #include <asm/sizes.h> |
23 | #include <asm/clock.h> | ||
24 | #include <asm/clkdev.h> | ||
23 | #include <asm/reboot.h> | 25 | #include <asm/reboot.h> |
24 | #include <asm/smp-ops.h> | 26 | #include <asm/smp-ops.h> |
25 | 27 | ||
@@ -140,6 +142,45 @@ static int sdk7786_mode_pins(void) | |||
140 | return fpga_read_reg(MODSWR); | 142 | return fpga_read_reg(MODSWR); |
141 | } | 143 | } |
142 | 144 | ||
145 | /* | ||
146 | * FPGA-driven PCIe clocks | ||
147 | * | ||
148 | * Historically these include the oscillator, clock B (slots 2/3/4) and | ||
149 | * clock A (slot 1 and the CPU clock). Newer revs of the PCB shove | ||
150 | * everything under a single PCIe clocks enable bit that happens to map | ||
151 | * to the same bit position as the oscillator bit for earlier FPGA | ||
152 | * versions. | ||
153 | * | ||
154 | * Given that the legacy clocks have the side-effect of shutting the CPU | ||
155 | * off through the FPGA along with the PCI slots, we simply leave them in | ||
156 | * their initial state and don't bother registering them with the clock | ||
157 | * framework. | ||
158 | */ | ||
159 | static int sdk7786_pcie_clk_enable(struct clk *clk) | ||
160 | { | ||
161 | fpga_write_reg(fpga_read_reg(PCIECR) | PCIECR_CLKEN, PCIECR); | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static void sdk7786_pcie_clk_disable(struct clk *clk) | ||
166 | { | ||
167 | fpga_write_reg(fpga_read_reg(PCIECR) & ~PCIECR_CLKEN, PCIECR); | ||
168 | } | ||
169 | |||
170 | static struct clk_ops sdk7786_pcie_clk_ops = { | ||
171 | .enable = sdk7786_pcie_clk_enable, | ||
172 | .disable = sdk7786_pcie_clk_disable, | ||
173 | }; | ||
174 | |||
175 | static struct clk sdk7786_pcie_clk = { | ||
176 | .ops = &sdk7786_pcie_clk_ops, | ||
177 | }; | ||
178 | |||
179 | static struct clk_lookup sdk7786_pcie_cl = { | ||
180 | .con_id = "pcie_plat_clk", | ||
181 | .clk = &sdk7786_pcie_clk, | ||
182 | }; | ||
183 | |||
143 | static int sdk7786_clk_init(void) | 184 | static int sdk7786_clk_init(void) |
144 | { | 185 | { |
145 | struct clk *clk; | 186 | struct clk *clk; |
@@ -158,7 +199,18 @@ static int sdk7786_clk_init(void) | |||
158 | ret = clk_set_rate(clk, 33333333); | 199 | ret = clk_set_rate(clk, 33333333); |
159 | clk_put(clk); | 200 | clk_put(clk); |
160 | 201 | ||
161 | return ret; | 202 | /* |
203 | * Setup the FPGA clocks. | ||
204 | */ | ||
205 | ret = clk_register(&sdk7786_pcie_clk); | ||
206 | if (unlikely(ret)) { | ||
207 | pr_err("FPGA clock registration failed\n"); | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | clkdev_add(&sdk7786_pcie_cl); | ||
212 | |||
213 | return 0; | ||
162 | } | 214 | } |
163 | 215 | ||
164 | static void sdk7786_restart(char *cmd) | 216 | static void sdk7786_restart(char *cmd) |