|
@@ -20,6 +20,8 @@
|
|
|
#include <asm/machvec.h>
|
|
|
#include <asm/heartbeat.h>
|
|
|
#include <asm/sizes.h>
|
|
|
+#include <asm/clock.h>
|
|
|
+#include <asm/clkdev.h>
|
|
|
#include <asm/reboot.h>
|
|
|
#include <asm/smp-ops.h>
|
|
|
|
|
@@ -140,6 +142,45 @@ static int sdk7786_mode_pins(void)
|
|
|
return fpga_read_reg(MODSWR);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * FPGA-driven PCIe clocks
|
|
|
+ *
|
|
|
+ * Historically these include the oscillator, clock B (slots 2/3/4) and
|
|
|
+ * clock A (slot 1 and the CPU clock). Newer revs of the PCB shove
|
|
|
+ * everything under a single PCIe clocks enable bit that happens to map
|
|
|
+ * to the same bit position as the oscillator bit for earlier FPGA
|
|
|
+ * versions.
|
|
|
+ *
|
|
|
+ * Given that the legacy clocks have the side-effect of shutting the CPU
|
|
|
+ * off through the FPGA along with the PCI slots, we simply leave them in
|
|
|
+ * their initial state and don't bother registering them with the clock
|
|
|
+ * framework.
|
|
|
+ */
|
|
|
+static int sdk7786_pcie_clk_enable(struct clk *clk)
|
|
|
+{
|
|
|
+ fpga_write_reg(fpga_read_reg(PCIECR) | PCIECR_CLKEN, PCIECR);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void sdk7786_pcie_clk_disable(struct clk *clk)
|
|
|
+{
|
|
|
+ fpga_write_reg(fpga_read_reg(PCIECR) & ~PCIECR_CLKEN, PCIECR);
|
|
|
+}
|
|
|
+
|
|
|
+static struct clk_ops sdk7786_pcie_clk_ops = {
|
|
|
+ .enable = sdk7786_pcie_clk_enable,
|
|
|
+ .disable = sdk7786_pcie_clk_disable,
|
|
|
+};
|
|
|
+
|
|
|
+static struct clk sdk7786_pcie_clk = {
|
|
|
+ .ops = &sdk7786_pcie_clk_ops,
|
|
|
+};
|
|
|
+
|
|
|
+static struct clk_lookup sdk7786_pcie_cl = {
|
|
|
+ .con_id = "pcie_plat_clk",
|
|
|
+ .clk = &sdk7786_pcie_clk,
|
|
|
+};
|
|
|
+
|
|
|
static int sdk7786_clk_init(void)
|
|
|
{
|
|
|
struct clk *clk;
|
|
@@ -158,7 +199,18 @@ static int sdk7786_clk_init(void)
|
|
|
ret = clk_set_rate(clk, 33333333);
|
|
|
clk_put(clk);
|
|
|
|
|
|
- return ret;
|
|
|
+ /*
|
|
|
+ * Setup the FPGA clocks.
|
|
|
+ */
|
|
|
+ ret = clk_register(&sdk7786_pcie_clk);
|
|
|
+ if (unlikely(ret)) {
|
|
|
+ pr_err("FPGA clock registration failed\n");
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ clkdev_add(&sdk7786_pcie_cl);
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static void sdk7786_restart(char *cmd)
|