aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/sh/boards/mach-sdk7786/setup.c54
-rw-r--r--arch/sh/drivers/pci/fixups-sdk7786.c1
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.c23
-rw-r--r--arch/sh/include/mach-sdk7786/mach/fpga.h2
4 files changed, 75 insertions, 5 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 */
159static 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
165static void sdk7786_pcie_clk_disable(struct clk *clk)
166{
167 fpga_write_reg(fpga_read_reg(PCIECR) & ~PCIECR_CLKEN, PCIECR);
168}
169
170static struct clk_ops sdk7786_pcie_clk_ops = {
171 .enable = sdk7786_pcie_clk_enable,
172 .disable = sdk7786_pcie_clk_disable,
173};
174
175static struct clk sdk7786_pcie_clk = {
176 .ops = &sdk7786_pcie_clk_ops,
177};
178
179static struct clk_lookup sdk7786_pcie_cl = {
180 .con_id = "pcie_plat_clk",
181 .clk = &sdk7786_pcie_clk,
182};
183
143static int sdk7786_clk_init(void) 184static 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
164static void sdk7786_restart(char *cmd) 216static void sdk7786_restart(char *cmd)
diff --git a/arch/sh/drivers/pci/fixups-sdk7786.c b/arch/sh/drivers/pci/fixups-sdk7786.c
index 058a65a1aa20..0e18ee332553 100644
--- a/arch/sh/drivers/pci/fixups-sdk7786.c
+++ b/arch/sh/drivers/pci/fixups-sdk7786.c
@@ -10,7 +10,6 @@
10#define pr_fmt(fmt) "PCI: " fmt 10#define pr_fmt(fmt) "PCI: " fmt
11 11
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/clk.h>
14#include <linux/kernel.h> 13#include <linux/kernel.h>
15#include <linux/pci.h> 14#include <linux/pci.h>
16#include <mach/fpga.h> 15#include <mach/fpga.h>
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index 8ec4af197388..ae0b2c9b70a0 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -17,7 +17,6 @@
17#include <linux/sh_clk.h> 17#include <linux/sh_clk.h>
18#include "pcie-sh7786.h" 18#include "pcie-sh7786.h"
19#include <asm/sizes.h> 19#include <asm/sizes.h>
20#include <asm/clock.h>
21 20
22struct sh7786_pcie_port { 21struct sh7786_pcie_port {
23 struct pci_channel *hose; 22 struct pci_channel *hose;
@@ -510,6 +509,7 @@ static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = {
510 509
511static int __init sh7786_pcie_init(void) 510static int __init sh7786_pcie_init(void)
512{ 511{
512 struct clk *platclk;
513 int ret = 0, i; 513 int ret = 0, i;
514 514
515 printk(KERN_NOTICE "PCI: Starting initialization.\n"); 515 printk(KERN_NOTICE "PCI: Starting initialization.\n");
@@ -527,6 +527,22 @@ static int __init sh7786_pcie_init(void)
527 if (unlikely(!sh7786_pcie_ports)) 527 if (unlikely(!sh7786_pcie_ports))
528 return -ENOMEM; 528 return -ENOMEM;
529 529
530 /*
531 * Fetch any optional platform clock associated with this block.
532 *
533 * This is a rather nasty hack for boards with spec-mocking FPGAs
534 * that have a secondary set of clocks outside of the on-chip
535 * ones that need to be accounted for before there is any chance
536 * of touching the existing MSTP bits or CPG clocks.
537 */
538 platclk = clk_get(NULL, "pcie_plat_clk");
539 if (IS_ERR(platclk)) {
540 /* Sane hardware should probably get a WARN_ON.. */
541 platclk = NULL;
542 }
543
544 clk_enable(platclk);
545
530 printk(KERN_NOTICE "PCI: probing %d ports.\n", nr_ports); 546 printk(KERN_NOTICE "PCI: probing %d ports.\n", nr_ports);
531 547
532 for (i = 0; i < nr_ports; i++) { 548 for (i = 0; i < nr_ports; i++) {
@@ -539,8 +555,11 @@ static int __init sh7786_pcie_init(void)
539 ret |= sh7786_pcie_hwops->port_init_hw(port); 555 ret |= sh7786_pcie_hwops->port_init_hw(port);
540 } 556 }
541 557
542 if (unlikely(ret)) 558 if (unlikely(ret)) {
559 clk_disable(platclk);
560 clk_put(platclk);
543 return ret; 561 return ret;
562 }
544 563
545 return 0; 564 return 0;
546} 565}
diff --git a/arch/sh/include/mach-sdk7786/mach/fpga.h b/arch/sh/include/mach-sdk7786/mach/fpga.h
index 8cc784147b96..b7d93699b679 100644
--- a/arch/sh/include/mach-sdk7786/mach/fpga.h
+++ b/arch/sh/include/mach-sdk7786/mach/fpga.h
@@ -39,7 +39,7 @@
39#define PCIECR_PRST3 BIT(11) /* slot 3 card present */ 39#define PCIECR_PRST3 BIT(11) /* slot 3 card present */
40#define PCIECR_PRST2 BIT(10) /* slot 2 card present */ 40#define PCIECR_PRST2 BIT(10) /* slot 2 card present */
41#define PCIECR_PRST1 BIT(9) /* slot 1 card present */ 41#define PCIECR_PRST1 BIT(9) /* slot 1 card present */
42#define PCIECR_CLKEN BIT(4) 42#define PCIECR_CLKEN BIT(4) /* oscillator enable */
43 43
44#define FAER 0x150 44#define FAER 0x150
45#define USRGPIR 0x160 45#define USRGPIR 0x160