3a9b6dc313
SVN-Revision: 31336
309 lines
8.8 KiB
Diff
309 lines
8.8 KiB
Diff
From 580d6aef484b22b5da88588d9a2d944b4f06dc98 Mon Sep 17 00:00:00 2001
|
|
From: John Crispin <blogic@openwrt.org>
|
|
Date: Tue, 20 Mar 2012 08:26:04 +0100
|
|
Subject: [PATCH 57/70] MIPS: clean up clock code
|
|
|
|
---
|
|
arch/mips/lantiq/clk.c | 11 +++
|
|
arch/mips/lantiq/clk.h | 3 +-
|
|
arch/mips/lantiq/xway/devices.c | 2 +-
|
|
arch/mips/lantiq/xway/sysctrl.c | 166 ++++++++++++++++++++++++++++++---------
|
|
4 files changed, 143 insertions(+), 39 deletions(-)
|
|
|
|
--- a/arch/mips/lantiq/clk.c
|
|
+++ b/arch/mips/lantiq/clk.c
|
|
@@ -44,6 +44,7 @@ struct clk *clk_get_fpi(void)
|
|
{
|
|
return &cpu_clk_generic[1];
|
|
}
|
|
+EXPORT_SYMBOL_GPL(clk_get_fpi);
|
|
|
|
struct clk *clk_get_io(void)
|
|
{
|
|
@@ -70,6 +71,16 @@ unsigned long clk_get_rate(struct clk *c
|
|
}
|
|
EXPORT_SYMBOL(clk_get_rate);
|
|
|
|
+int clk_set_rate(struct clk *clk, unsigned long rate)
|
|
+{
|
|
+ if (unlikely(!clk_good(clk)))
|
|
+ return 0;
|
|
+
|
|
+ clk->rate = rate;
|
|
+ return 0;
|
|
+}
|
|
+EXPORT_SYMBOL(clk_set_rate);
|
|
+
|
|
int clk_enable(struct clk *clk)
|
|
{
|
|
if (unlikely(!clk_good(clk)))
|
|
--- a/arch/mips/lantiq/clk.h
|
|
+++ b/arch/mips/lantiq/clk.h
|
|
@@ -12,6 +12,7 @@
|
|
#include <linux/clkdev.h>
|
|
|
|
/* clock speeds */
|
|
+#define CLOCK_33M 33333333
|
|
#define CLOCK_60M 60000000
|
|
#define CLOCK_62_5M 62500000
|
|
#define CLOCK_83M 83333333
|
|
@@ -38,9 +39,9 @@
|
|
struct clk {
|
|
struct clk_lookup cl;
|
|
unsigned long rate;
|
|
- unsigned long (*get_rate) (void);
|
|
unsigned int module;
|
|
unsigned int bits;
|
|
+ unsigned long (*get_rate) (void);
|
|
int (*enable) (struct clk *clk);
|
|
void (*disable) (struct clk *clk);
|
|
int (*activate) (struct clk *clk);
|
|
--- a/arch/mips/lantiq/xway/devices.c
|
|
+++ b/arch/mips/lantiq/xway/devices.c
|
|
@@ -59,7 +59,7 @@ static struct resource ltq_stp_resource
|
|
|
|
void __init ltq_register_gpio_stp(void)
|
|
{
|
|
- platform_device_register_simple("ltq_stp", 0, <q_stp_resource, 1);
|
|
+ platform_device_register_simple("ltq_stp", -1, <q_stp_resource, 1);
|
|
}
|
|
|
|
/* asc ports - amazon se has its own serial mapping */
|
|
--- a/arch/mips/lantiq/xway/sysctrl.c
|
|
+++ b/arch/mips/lantiq/xway/sysctrl.c
|
|
@@ -16,40 +16,57 @@
|
|
#include "../devices.h"
|
|
|
|
/* clock control register */
|
|
-#define LTQ_CGU_IFCCR 0x0018
|
|
+#define CGU_IFCCR 0x0018
|
|
/* system clock register */
|
|
-#define LTQ_CGU_SYS 0x0010
|
|
-
|
|
-/* the enable / disable registers */
|
|
-#define LTQ_PMU_PWDCR 0x1C
|
|
-#define LTQ_PMU_PWDSR 0x20
|
|
-#define LTQ_PMU_PWDCR1 0x24
|
|
-#define LTQ_PMU_PWDSR1 0x28
|
|
-
|
|
-#define PWDCR(x) ((x) ? (LTQ_PMU_PWDCR1) : (LTQ_PMU_PWDCR))
|
|
-#define PWDSR(x) ((x) ? (LTQ_PMU_PWDSR1) : (LTQ_PMU_PWDSR))
|
|
-
|
|
-/* CGU - clock generation unit */
|
|
-#define CGU_EPHY 0x10
|
|
+#define CGU_SYS 0x0010
|
|
+/* pci control register */
|
|
+#define CGU_PCICR 0x0034
|
|
+/* ephy configuration register */
|
|
+#define CGU_EPHY 0x10
|
|
+/* power control register */
|
|
+#define PMU_PWDCR 0x1C
|
|
+/* power status register */
|
|
+#define PMU_PWDSR 0x20
|
|
+/* power control register */
|
|
+#define PMU_PWDCR1 0x24
|
|
+/* power status register */
|
|
+#define PMU_PWDSR1 0x28
|
|
+/* power control register */
|
|
+#define PWDCR(x) ((x) ? (PMU_PWDCR1) : (PMU_PWDCR))
|
|
+/* power status register */
|
|
+#define PWDSR(x) ((x) ? (PMU_PWDSR1) : (PMU_PWDSR))
|
|
|
|
/* PMU - power management unit */
|
|
-#define PMU_DMA 0x0020
|
|
-#define PMU_SPI 0x0100
|
|
-#define PMU_EPHY 0x0080
|
|
-#define PMU_USB 0x8041
|
|
-#define PMU_STP 0x0800
|
|
-#define PMU_GPT 0x1000
|
|
-#define PMU_PPE 0x2000
|
|
-#define PMU_FPI 0x4000
|
|
-#define PMU_SWITCH 0x10000000
|
|
-#define PMU_AHBS 0x2000
|
|
-#define PMU_AHBM 0x8000
|
|
-#define PMU_PCIE_CLK 0x80000000
|
|
-
|
|
-#define PMU1_PCIE_PHY 0x0001
|
|
-#define PMU1_PCIE_CTL 0x0002
|
|
-#define PMU1_PCIE_MSI 0x0020
|
|
-#define PMU1_PCIE_PDI 0x0010
|
|
+#define PMU_USB0_P BIT(0)
|
|
+#define PMU_PCI BIT(4)
|
|
+#define PMU_DMA BIT(5)
|
|
+#define PMU_USB0 BIT(5)
|
|
+#define PMU_SPI BIT(8)
|
|
+#define PMU_EPHY BIT(7)
|
|
+#define PMU_EBU BIT(10)
|
|
+#define PMU_STP BIT(11)
|
|
+#define PMU_GPT BIT(12)
|
|
+#define PMU_PPE BIT(13)
|
|
+#define PMU_AHBS BIT(13) /* vr9 */
|
|
+#define PMU_FPI BIT(14)
|
|
+#define PMU_AHBM BIT(15)
|
|
+#define PMU_PPE_QSB BIT(18)
|
|
+#define PMU_PPE_SLL01 BIT(19)
|
|
+#define PMU_PPE_TC BIT(21)
|
|
+#define PMU_PPE_EMA BIT(22)
|
|
+#define PMU_PPE_DPLUM BIT(23)
|
|
+#define PMU_PPE_DPLUS BIT(24)
|
|
+#define PMU_USB1_P BIT(26)
|
|
+#define PMU_USB1 BIT(27)
|
|
+#define PMU_SWITCH BIT(28)
|
|
+#define PMU_PPE_TOP BIT(29)
|
|
+#define PMU_GPHY BIT(30)
|
|
+#define PMU_PCIE_CLK BIT(31)
|
|
+
|
|
+#define PMU1_PCIE_PHY BIT(0)
|
|
+#define PMU1_PCIE_CTL BIT(1)
|
|
+#define PMU1_PCIE_PDI BIT(4)
|
|
+#define PMU1_PCIE_MSI BIT(5)
|
|
|
|
#define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y))
|
|
#define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x))
|
|
@@ -69,13 +86,13 @@ static void __iomem *ltq_pmu_membase;
|
|
|
|
static int ltq_cgu_enable(struct clk *clk)
|
|
{
|
|
- ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | clk->bits, LTQ_CGU_IFCCR);
|
|
+ ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | clk->bits, CGU_IFCCR);
|
|
return 0;
|
|
}
|
|
|
|
static void ltq_cgu_disable(struct clk *clk)
|
|
{
|
|
- ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~clk->bits, LTQ_CGU_IFCCR);
|
|
+ ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~clk->bits, CGU_IFCCR);
|
|
}
|
|
|
|
static int ltq_pmu_enable(struct clk *clk)
|
|
@@ -94,9 +111,49 @@ static int ltq_pmu_enable(struct clk *cl
|
|
|
|
static void ltq_pmu_disable(struct clk *clk)
|
|
{
|
|
- ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | clk->bits, LTQ_PMU_PWDCR);
|
|
+ ltq_pmu_w32(ltq_pmu_r32(PWDCR(clk->module)) | clk->bits,
|
|
+ PWDCR(clk->module));
|
|
}
|
|
|
|
+static int ltq_pci_enable(struct clk *clk)
|
|
+{
|
|
+ unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR);
|
|
+ /* set clock bus speed */
|
|
+ if (ltq_is_ar9()) {
|
|
+ ifccr &= ~0x1f00000;
|
|
+ if (clk->rate == CLOCK_33M)
|
|
+ ifccr |= 0xe00000;
|
|
+ else
|
|
+ ifccr |= 0x700000; /* 62.5M */
|
|
+ } else {
|
|
+ ifccr &= ~0xf00000;
|
|
+ if (clk->rate == CLOCK_33M)
|
|
+ ifccr |= 0x800000;
|
|
+ else
|
|
+ ifccr |= 0x400000; /* 62.5M */
|
|
+ }
|
|
+ ltq_cgu_w32(ifccr, CGU_IFCCR);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int ltq_pci_ext_enable(struct clk *clk)
|
|
+{
|
|
+ /* enable external pci clock */
|
|
+ ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~(1 << 16),
|
|
+ CGU_IFCCR);
|
|
+ ltq_cgu_w32((1 << 30), CGU_PCICR);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void ltq_pci_ext_disable(struct clk *clk)
|
|
+{
|
|
+ /* enable external pci clock */
|
|
+ ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | (1 << 16),
|
|
+ CGU_IFCCR);
|
|
+ ltq_cgu_w32((1 << 31) | (1 << 30), CGU_PCICR);
|
|
+}
|
|
+
|
|
+/* manage the clock gates via PMU */
|
|
static inline void clkdev_add_pmu(const char *dev, const char *con,
|
|
unsigned int module, unsigned int bits)
|
|
{
|
|
@@ -112,6 +169,7 @@ static inline void clkdev_add_pmu(const
|
|
clkdev_add(&clk->cl);
|
|
}
|
|
|
|
+/* manage the clock generator */
|
|
static inline void clkdev_add_cgu(const char *dev, const char *con,
|
|
unsigned int bits)
|
|
{
|
|
@@ -126,6 +184,33 @@ static inline void clkdev_add_cgu(const
|
|
clkdev_add(&clk->cl);
|
|
}
|
|
|
|
+/* pci needs its own enable function */
|
|
+static inline void clkdev_add_pci(void)
|
|
+{
|
|
+ struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
|
|
+ struct clk *clk_ext = kzalloc(sizeof(struct clk), GFP_KERNEL);
|
|
+
|
|
+ /* main pci clock */
|
|
+ clk->cl.dev_id = "ltq_pci";
|
|
+ clk->cl.con_id = NULL;
|
|
+ clk->cl.clk = clk;
|
|
+ clk->rate = CLOCK_33M;
|
|
+ clk->enable = ltq_pci_enable;
|
|
+ clk->disable = ltq_pmu_disable;
|
|
+ clk->module = 0;
|
|
+ clk->bits = PMU_PCI;
|
|
+ clkdev_add(&clk->cl);
|
|
+
|
|
+ /* use internal/external bus clock */
|
|
+ clk_ext->cl.dev_id = "ltq_pci";
|
|
+ clk_ext->cl.con_id = "external";
|
|
+ clk_ext->cl.clk = clk_ext;
|
|
+ clk_ext->enable = ltq_pci_ext_enable;
|
|
+ clk_ext->disable = ltq_pci_ext_disable;
|
|
+ clkdev_add(&clk_ext->cl);
|
|
+
|
|
+}
|
|
+
|
|
void __init ltq_soc_init(void)
|
|
{
|
|
ltq_pmu_membase = ltq_remap_resource(<q_pmu_resource);
|
|
@@ -144,14 +229,16 @@ void __init ltq_soc_init(void)
|
|
ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
|
|
|
|
/* add our clocks */
|
|
+ clkdev_add_pmu("ltq_fpi", NULL, 0, PMU_FPI);
|
|
clkdev_add_pmu("ltq_dma", NULL, 0, PMU_DMA);
|
|
clkdev_add_pmu("ltq_stp", NULL, 0, PMU_STP);
|
|
clkdev_add_pmu("ltq_spi", NULL, 0, PMU_SPI);
|
|
clkdev_add_pmu("ltq_gptu", NULL, 0, PMU_GPT);
|
|
+ clkdev_add_pmu("ltq_ebu", NULL, 0, PMU_EBU);
|
|
if (!ltq_is_vr9())
|
|
clkdev_add_pmu("ltq_etop", NULL, 0, PMU_PPE);
|
|
if (ltq_is_ase()) {
|
|
- if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5))
|
|
+ if (ltq_cgu_r32(CGU_SYS) & (1 << 5))
|
|
clkdev_add_static(CLOCK_266M, CLOCK_133M, CLOCK_133M);
|
|
else
|
|
clkdev_add_static(CLOCK_133M, CLOCK_133M, CLOCK_133M);
|
|
@@ -166,11 +253,16 @@ void __init ltq_soc_init(void)
|
|
clkdev_add_pmu("ltq_pcie", "pdi", 1, PMU1_PCIE_PDI);
|
|
clkdev_add_pmu("ltq_pcie", "ctl", 1, PMU1_PCIE_CTL);
|
|
clkdev_add_pmu("ltq_pcie", "ahb", 0, PMU_AHBM | PMU_AHBS);
|
|
- clkdev_add_pmu("usb0", NULL, 0, (1<<6) | 1);
|
|
- clkdev_add_pmu("usb1", NULL, 0, (1<<26) | (1<<27));
|
|
+ clkdev_add_pmu("usb0", NULL, 0, PMU_USB0 | PMU_USB0_P);
|
|
+ clkdev_add_pmu("usb1", NULL, 0, PMU_USB1 | PMU_USB1_P);
|
|
+ clkdev_add_pmu("ltq_vrx200", NULL, 0,
|
|
+ PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
|
|
+ PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
|
|
+ PMU_PPE_QSB);
|
|
} else {
|
|
clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
|
|
ltq_danube_io_region_clock());
|
|
+ clkdev_add_pci();
|
|
if (ltq_is_ar9())
|
|
clkdev_add_pmu("ltq_etop", "switch", 0, PMU_SWITCH);
|
|
}
|