summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-25 03:40:57 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-25 03:40:57 +0400
commit9161c3b796a2841a9a7be3d9c9dd121269ce90e8 (patch)
tree4920a191c4a2eecae1a4e055af7e967f1e769714 /arch/arm
parent97027da6adf2e24a4e8d3d9c0668da3006b29971 (diff)
parent137f8a7213d80c1388ca48280c1ef0856b6fec30 (diff)
downloadlinux-9161c3b796a2841a9a7be3d9c9dd121269ce90e8.tar.xz
Merge tag 'clk-for-linus' of git://git.linaro.org/people/mturquette/linux
Pull common clk framework changes from Michael Turquette: "This includes a small number of core framework improvments, platform ports and new DT bindings." Fix up trivial conflicts in drivers/clk/Makefile * tag 'clk-for-linus' of git://git.linaro.org/people/mturquette/linux: (21 commits) clk: fix compile for OF && !COMMON_CLK clk: fix clk_get on of_clk_get_by_name return check clk: mxs: clk_register_clkdev mx28 usb clocks clk: add highbank clock support dt: add clock binding doc to primecell bindings clk: add DT fixed-clock binding support clk: add DT clock binding support ARM: integrator: convert to common clock clk: add versatile ICST307 driver ARM: integrator: put symbolic bus names on devices ARM: u300: convert to common clock clk: cache parent clocks only for muxes clk: wm831x: Add initial WM831x clock driver clk: Constify struct clk_init_data clk: Add CLK_IS_BASIC flag to identify basic clocks clk: Add support for rate table based dividers clk: Add support for power of two type dividers clk: mxs: imx28: decrease the frequency of ref_io1 for SSP2 and SSP3 clk: mxs: add clkdev lookup for pwm clk: mxs: Fix the GPMI clock name ...
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig8
-rw-r--r--arch/arm/boot/dts/highbank.dts91
-rw-r--r--arch/arm/mach-highbank/Makefile2
-rw-r--r--arch/arm/mach-highbank/clock.c62
-rw-r--r--arch/arm/mach-highbank/highbank.c7
-rw-r--r--arch/arm/mach-integrator/core.c55
-rw-r--r--arch/arm/mach-integrator/include/mach/clkdev.h26
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c8
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c69
-rw-r--r--arch/arm/mach-u300/Makefile2
-rw-r--r--arch/arm/mach-u300/clock.c1504
-rw-r--r--arch/arm/mach-u300/clock.h50
-rw-r--r--arch/arm/mach-u300/core.c21
-rw-r--r--arch/arm/mach-u300/timer.c2
14 files changed, 133 insertions, 1774 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c7e6d208fa8d..b25c9d3c379a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -273,8 +273,8 @@ config ARCH_INTEGRATOR
bool "ARM Ltd. Integrator family"
select ARM_AMBA
select ARCH_HAS_CPUFREQ
- select CLKDEV_LOOKUP
- select HAVE_MACH_CLKDEV
+ select COMMON_CLK
+ select CLK_VERSATILE
select HAVE_TCM
select ICST
select GENERIC_CLOCKEVENTS
@@ -336,6 +336,7 @@ config ARCH_VEXPRESS
select ICST
select NO_IOPORT
select PLAT_VERSATILE
+ select PLAT_VERSATILE_CLOCK
select PLAT_VERSATILE_CLCD
select REGULATOR_FIXED_VOLTAGE if REGULATOR
help
@@ -372,6 +373,7 @@ config ARCH_HIGHBANK
select ARM_TIMER_SP804
select CACHE_L2X0
select CLKDEV_LOOKUP
+ select COMMON_CLK
select CPU_V7
select GENERIC_CLOCKEVENTS
select HAVE_ARM_SCU
@@ -929,7 +931,7 @@ config ARCH_U300
select ARM_VIC
select GENERIC_CLOCKEVENTS
select CLKDEV_LOOKUP
- select HAVE_MACH_CLKDEV
+ select COMMON_CLK
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
help
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
index 83e72294aefb..2e1cfa00c25b 100644
--- a/arch/arm/boot/dts/highbank.dts
+++ b/arch/arm/boot/dts/highbank.dts
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Calxeda, Inc.
+ * Copyright 2011-2012 Calxeda, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -24,6 +24,7 @@
compatible = "calxeda,highbank";
#address-cells = <1>;
#size-cells = <1>;
+ clock-ranges;
cpus {
#address-cells = <1>;
@@ -33,24 +34,32 @@
compatible = "arm,cortex-a9";
reg = <0>;
next-level-cache = <&L2>;
+ clocks = <&a9pll>;
+ clock-names = "cpu";
};
cpu@1 {
compatible = "arm,cortex-a9";
reg = <1>;
next-level-cache = <&L2>;
+ clocks = <&a9pll>;
+ clock-names = "cpu";
};
cpu@2 {
compatible = "arm,cortex-a9";
reg = <2>;
next-level-cache = <&L2>;
+ clocks = <&a9pll>;
+ clock-names = "cpu";
};
cpu@3 {
compatible = "arm,cortex-a9";
reg = <3>;
next-level-cache = <&L2>;
+ clocks = <&a9pll>;
+ clock-names = "cpu";
};
};
@@ -75,12 +84,14 @@
compatible = "arm,cortex-a9-twd-timer";
reg = <0xfff10600 0x20>;
interrupts = <1 13 0xf01>;
+ clocks = <&a9periphclk>;
};
watchdog@fff10620 {
compatible = "arm,cortex-a9-twd-wdt";
reg = <0xfff10620 0x20>;
interrupts = <1 14 0xf01>;
+ clocks = <&a9periphclk>;
};
intc: interrupt-controller@fff11000 {
@@ -116,12 +127,15 @@
compatible = "calxeda,hb-sdhci";
reg = <0xffe0e000 0x1000>;
interrupts = <0 90 4>;
+ clocks = <&eclk>;
};
ipc@fff20000 {
compatible = "arm,pl320", "arm,primecell";
reg = <0xfff20000 0x1000>;
interrupts = <0 7 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
};
gpioe: gpio@fff30000 {
@@ -130,6 +144,8 @@
gpio-controller;
reg = <0xfff30000 0x1000>;
interrupts = <0 14 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
};
gpiof: gpio@fff31000 {
@@ -138,6 +154,8 @@
gpio-controller;
reg = <0xfff31000 0x1000>;
interrupts = <0 15 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
};
gpiog: gpio@fff32000 {
@@ -146,6 +164,8 @@
gpio-controller;
reg = <0xfff32000 0x1000>;
interrupts = <0 16 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
};
gpioh: gpio@fff33000 {
@@ -154,24 +174,32 @@
gpio-controller;
reg = <0xfff33000 0x1000>;
interrupts = <0 17 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
};
timer {
compatible = "arm,sp804", "arm,primecell";
reg = <0xfff34000 0x1000>;
interrupts = <0 18 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
};
rtc@fff35000 {
compatible = "arm,pl031", "arm,primecell";
reg = <0xfff35000 0x1000>;
interrupts = <0 19 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
};
serial@fff36000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0xfff36000 0x1000>;
interrupts = <0 20 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
};
smic@fff3a000 {
@@ -186,12 +214,73 @@
sregs@fff3c000 {
compatible = "calxeda,hb-sregs";
reg = <0xfff3c000 0x1000>;
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ osc: oscillator {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <33333000>;
+ };
+
+ ddrpll: ddrpll {
+ #clock-cells = <0>;
+ compatible = "calxeda,hb-pll-clock";
+ clocks = <&osc>;
+ reg = <0x108>;
+ };
+
+ a9pll: a9pll {
+ #clock-cells = <0>;
+ compatible = "calxeda,hb-pll-clock";
+ clocks = <&osc>;
+ reg = <0x100>;
+ };
+
+ a9periphclk: a9periphclk {
+ #clock-cells = <0>;
+ compatible = "calxeda,hb-a9periph-clock";
+ clocks = <&a9pll>;
+ reg = <0x104>;
+ };
+
+ a9bclk: a9bclk {
+ #clock-cells = <0>;
+ compatible = "calxeda,hb-a9bus-clock";
+ clocks = <&a9pll>;
+ reg = <0x104>;
+ };
+
+ emmcpll: emmcpll {
+ #clock-cells = <0>;
+ compatible = "calxeda,hb-pll-clock";
+ clocks = <&osc>;
+ reg = <0x10C>;
+ };
+
+ eclk: eclk {
+ #clock-cells = <0>;
+ compatible = "calxeda,hb-emmc-clock";
+ clocks = <&emmcpll>;
+ reg = <0x114>;
+ };
+
+ pclk: pclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <150000000>;
+ };
+ };
};
dma@fff3d000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0xfff3d000 0x1000>;
interrupts = <0 92 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
};
ethernet@fff50000 {
diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile
index ded4652ada80..3ec8bdd25d09 100644
--- a/arch/arm/mach-highbank/Makefile
+++ b/arch/arm/mach-highbank/Makefile
@@ -1,4 +1,4 @@
-obj-y := clock.o highbank.o system.o smc.o
+obj-y := highbank.o system.o smc.o
plus_sec := $(call as-instr,.arch_extension sec,+sec)
AFLAGS_smc.o :=-Wa,-march=armv7-a$(plus_sec)
diff --git a/arch/arm/mach-highbank/clock.c b/arch/arm/mach-highbank/clock.c
deleted file mode 100644
index c25a2ae4fde1..000000000000
--- a/arch/arm/mach-highbank/clock.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2011 Calxeda, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/clk.h>
-#include <linux/clkdev.h>
-
-struct clk {
- unsigned long rate;
-};
-
-int clk_enable(struct clk *clk)
-{
- return 0;
-}
-
-void clk_disable(struct clk *clk)
-{}
-
-unsigned long clk_get_rate(struct clk *clk)
-{
- return clk->rate;
-}
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
- return clk->rate;
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- return 0;
-}
-
-static struct clk eclk = { .rate = 200000000 };
-static struct clk pclk = { .rate = 150000000 };
-
-static struct clk_lookup lookups[] = {
- { .clk = &pclk, .con_id = "apb_pclk", },
- { .clk = &pclk, .dev_id = "sp804", },
- { .clk = &eclk, .dev_id = "ffe0e000.sdhci", },
- { .clk = &pclk, .dev_id = "fff36000.serial", },
-};
-
-void __init highbank_clocks_init(void)
-{
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-}
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index 8777612b1a42..d75b0a78d88a 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -105,6 +105,11 @@ static void __init highbank_init_irq(void)
#endif
}
+static struct clk_lookup lookup = {
+ .dev_id = "sp804",
+ .con_id = NULL,
+};
+
static void __init highbank_timer_init(void)
{
int irq;
@@ -122,6 +127,8 @@ static void __init highbank_timer_init(void)
irq = irq_of_parse_and_map(np, 0);
highbank_clocks_init();
+ lookup.clk = of_clk_get(np, 0);
+ clkdev_add(&lookup);
sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1");
sp804_clockevents_init(timer_base, irq, "timer0");
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index eaf6c6366ffa..ebf680bebdf2 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -21,7 +21,6 @@
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>
#include <linux/io.h>
-#include <linux/clkdev.h>
#include <mach/hardware.h>
#include <mach/platform.h>
@@ -41,17 +40,17 @@ static struct amba_pl010_data integrator_uart_data;
#define KMI0_IRQ { IRQ_KMIINT0 }
#define KMI1_IRQ { IRQ_KMIINT1 }
-static AMBA_APB_DEVICE(rtc, "mb:15", 0,
+static AMBA_APB_DEVICE(rtc, "rtc", 0,
INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL);
-static AMBA_APB_DEVICE(uart0, "mb:16", 0,
+static AMBA_APB_DEVICE(uart0, "uart0", 0,
INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, &integrator_uart_data);
-static AMBA_APB_DEVICE(uart1, "mb:17", 0,
+static AMBA_APB_DEVICE(uart1, "uart1", 0,
INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, &integrator_uart_data);
-static AMBA_APB_DEVICE(kmi0, "mb:18", 0, KMI0_BASE, KMI0_IRQ, NULL);
-static AMBA_APB_DEVICE(kmi1, "mb:19", 0, KMI1_BASE, KMI1_IRQ, NULL);
+static AMBA_APB_DEVICE(kmi0, "kmi0", 0, KMI0_BASE, KMI0_IRQ, NULL);
+static AMBA_APB_DEVICE(kmi1, "kmi1", 0, KMI1_BASE, KMI1_IRQ, NULL);
static struct amba_device *amba_devs[] __initdata = {
&rtc_device,
@@ -61,50 +60,6 @@ static struct amba_device *amba_devs[] __initdata = {
&kmi1_device,
};
-/*
- * These are fixed clocks.
- */
-static struct clk clk24mhz = {
- .rate = 24000000,
-};
-
-static struct clk uartclk = {
- .rate = 14745600,
-};
-
-static struct clk dummy_apb_pclk;
-
-static struct clk_lookup lookups[] = {
- { /* Bus clock */
- .con_id = "apb_pclk",
- .clk = &dummy_apb_pclk,
- }, {
- /* Integrator/AP timer frequency */
- .dev_id = "ap_timer",
- .clk = &clk24mhz,
- }, { /* UART0 */
- .dev_id = "mb:16",
- .clk = &uartclk,
- }, { /* UART1 */
- .dev_id = "mb:17",
- .clk = &uartclk,
- }, { /* KMI0 */
- .dev_id = "mb:18",
- .clk = &clk24mhz,
- }, { /* KMI1 */
- .dev_id = "mb:19",
- .clk = &clk24mhz,
- }, { /* MMCI - IntegratorCP */
- .dev_id = "mb:1c",
- .clk = &uartclk,
- }
-};
-
-void __init integrator_init_early(void)
-{
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-}
-
static int __init integrator_init(void)
{
int i;
diff --git a/arch/arm/mach-integrator/include/mach/clkdev.h b/arch/arm/mach-integrator/include/mach/clkdev.h
deleted file mode 100644
index bfe07679faec..000000000000
--- a/arch/arm/mach-integrator/include/mach/clkdev.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef __ASM_MACH_CLKDEV_H
-#define __ASM_MACH_CLKDEV_H
-
-#include <linux/module.h>
-#include <plat/clock.h>
-
-struct clk {
- unsigned long rate;
- const struct clk_ops *ops;
- struct module *owner;
- const struct icst_params *params;
- void __iomem *vcoreg;
- void *data;
-};
-
-static inline int __clk_get(struct clk *clk)
-{
- return try_module_get(clk->owner);
-}
-
-static inline void __clk_put(struct clk *clk)
-{
- module_put(clk->owner);
-}
-
-#endif
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index c857501c5783..7b1055c8e0b9 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -33,6 +33,7 @@
#include <linux/io.h>
#include <linux/mtd/physmap.h>
#include <linux/clk.h>
+#include <linux/platform_data/clk-integrator.h>
#include <video/vga.h>
#include <mach/hardware.h>
@@ -174,6 +175,7 @@ static void __init ap_init_irq(void)
fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START,
-1, INTEGRATOR_SC_VALID_INT, NULL);
+ integrator_clk_init(false);
}
#ifdef CONFIG_PM
@@ -440,6 +442,10 @@ static void integrator_clockevent_init(unsigned long inrate)
0xffffU);
}
+void __init ap_init_early(void)
+{
+}
+
/*
* Set up timer(s).
*/
@@ -471,7 +477,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator")
.reserve = integrator_reserve,
.map_io = ap_map_io,
.nr_irqs = NR_IRQS_INTEGRATOR_AP,
- .init_early = integrator_init_early,
+ .init_early = ap_init_early,
.init_irq = ap_init_irq,
.handle_irq = fpga_handle_irq,
.timer = &ap_timer,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index a56c53608939..82d5c837cc74 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -21,8 +21,8 @@
#include <linux/amba/mmci.h>
#include <linux/io.h>
#include <linux/gfp.h>
-#include <linux/clkdev.h>
#include <linux/mtd/physmap.h>
+#include <linux/platform_data/clk-integrator.h>
#include <mach/hardware.h>
#include <mach/platform.h>
@@ -171,65 +171,10 @@ static void __init intcp_init_irq(void)
fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START,
IRQ_CP_CPPLDINT, sic_mask, NULL);
+ integrator_clk_init(true);
}
/*
- * Clock handling
- */
-#define CM_LOCK (__io_address(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
-#define CM_AUXOSC (__io_address(INTEGRATOR_HDR_BASE)+0x1c)
-
-static const struct icst_params cp_auxvco_params = {
- .ref = 24000000,
- .vco_max = ICST525_VCO_MAX_5V,
- .vco_min = ICST525_VCO_MIN,
- .vd_min = 8,
- .vd_max = 263,
- .rd_min = 3,
- .rd_max = 65,
- .s2div = icst525_s2div,
- .idx2s = icst525_idx2s,
-};
-
-static void cp_auxvco_set(struct clk *clk, struct icst_vco vco)
-{
- u32 val;
-
- val = readl(clk->vcoreg) & ~0x7ffff;
- val |= vco.v | (vco.r << 9) | (vco.s << 16);
-
- writel(0xa05f, CM_LOCK);
- writel(val, clk->vcoreg);
- writel(0, CM_LOCK);
-}
-
-static const struct clk_ops cp_auxclk_ops = {
- .round = icst_clk_round,
- .set = icst_clk_set,
- .setvco = cp_auxvco_set,
-};
-
-static struct clk cp_auxclk = {
- .ops = &cp_auxclk_ops,
- .params = &cp_auxvco_params,
- .vcoreg = CM_AUXOSC,
-};
-
-static struct clk sp804_clk = {
- .rate = 1000000,
-};
-
-static struct clk_lookup cp_lookups[] = {
- { /* CLCD */
- .dev_id = "mb:c0",
- .clk = &cp_auxclk,
- }, { /* SP804 timers */
- .dev_id = "sp804",
- .clk = &sp804_clk,
- },
-};
-
-/*
* Flash handling.
*/
static int intcp_flash_init(struct platform_device *dev)
@@ -336,10 +281,10 @@ static struct mmci_platform_data mmc_data = {
#define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 }
#define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT }
-static AMBA_APB_DEVICE(mmc, "mb:1c", 0, INTEGRATOR_CP_MMC_BASE,
+static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE,
INTEGRATOR_CP_MMC_IRQS, &mmc_data);
-static AMBA_APB_DEVICE(aaci, "mb:1d", 0, INTEGRATOR_CP_AACI_BASE,
+static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE,
INTEGRATOR_CP_AACI_IRQS, NULL);
@@ -393,7 +338,7 @@ static struct clcd_board clcd_data = {
.remove = versatile_clcd_remove_dma,
};
-static AMBA_AHB_DEVICE(clcd, "mb:c0", 0, INTCP_PA_CLCD_BASE,
+static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE,
{ IRQ_CP_CLCDCINT }, &clcd_data);
static struct amba_device *amba_devs[] __initdata = {
@@ -406,10 +351,6 @@ static struct amba_device *amba_devs[] __initdata = {
static void __init intcp_init_early(void)
{
- clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
-
- integrator_init_early();
-
#ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK
versatile_sched_clock_init(REFCOUNTER, 24000000);
#endif
diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile
index fd3a5c382f47..7e47d37aeb0e 100644
--- a/arch/arm/mach-u300/Makefile
+++ b/arch/arm/mach-u300/Makefile
@@ -2,7 +2,7 @@
# Makefile for the linux kernel, U300 machine.
#
-obj-y := core.o clock.o timer.o
+obj-y := core.o timer.o
obj-m :=
obj-n :=
obj- :=
diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c
deleted file mode 100644
index 5535dd0a78c9..000000000000
--- a/arch/arm/mach-u300/clock.c
+++ /dev/null
@@ -1,1504 +0,0 @@
-/*
- *
- * arch/arm/mach-u300/clock.c
- *
- *
- * Copyright (C) 2007-2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- * Define clocks in the app platform.
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/string.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/spinlock.h>
-#include <linux/debugfs.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/timer.h>
-#include <linux/io.h>
-#include <linux/seq_file.h>
-#include <linux/clkdev.h>
-
-#include <mach/hardware.h>
-#include <mach/syscon.h>
-
-#include "clock.h"
-
-/*
- * TODO:
- * - move all handling of the CCR register into this file and create
- * a spinlock for the CCR register
- * - switch to the clkdevice lookup mechanism that maps clocks to
- * device ID:s instead when it becomes available in kernel 2.6.29.
- * - implement rate get/set for all clocks that need it.
- */
-
-/*
- * Syscon clock I/O registers lock so clock requests don't collide
- * NOTE: this is a local lock only used to lock access to clock and
- * reset registers in syscon.
- */
-static DEFINE_SPINLOCK(syscon_clkreg_lock);
-static DEFINE_SPINLOCK(syscon_resetreg_lock);
-
-/*
- * The clocking hierarchy currently looks like this.
- * NOTE: the idea is NOT to show how the clocks are routed on the chip!
- * The ideas is to show dependencies, so a clock higher up in the
- * hierarchy has to be on in order for another clock to be on. Now,
- * both CPU and DMA can actually be on top of the hierarchy, and that
- * is not modeled currently. Instead we have the backbone AMBA bus on
- * top. This bus cannot be programmed in any way but conceptually it
- * needs to be active for the bridges and devices to transport data.
- *
- * Please be aware that a few clocks are hw controlled, which mean that
- * the hw itself can turn on/off or change the rate of the clock when
- * needed!
- *
- * AMBA bus
- * |
- * +- CPU
- * +- FSMC NANDIF NAND Flash interface
- * +- SEMI Shared Memory interface
- * +- ISP Image Signal Processor (U335 only)
- * +- CDS (U335 only)
- * +- DMA Direct Memory Access Controller
- * +- AAIF APP/ACC Inteface (Mobile Scalable Link, MSL)
- * +- APEX
- * +- VIDEO_ENC AVE2/3 Video Encoder
- * +- XGAM Graphics Accelerator Controller
- * +- AHB
- * |
- * +- ahb:0 AHB Bridge
- * | |
- * | +- ahb:1 INTCON Interrupt controller
- * | +- ahb:3 MSPRO Memory Stick Pro controller
- * | +- ahb:4 EMIF External Memory interface
- * |
- * +- fast:0 FAST bridge
- * | |
- * | +- fast:1 MMCSD MMC/SD card reader controller
- * | +- fast:2 I2S0 PCM I2S channel 0 controller
- * | +- fast:3 I2S1 PCM I2S channel 1 controller
- * | +- fast:4 I2C0 I2C channel 0 controller
- * | +- fast:5 I2C1 I2C channel 1 controller
- * | +- fast:6 SPI SPI controller
- * | +- fast:7 UART1 Secondary UART (U335 only)
- * |
- * +- slow:0 SLOW bridge
- * |
- * +- slow:1 SYSCON (not possible to control)
- * +- slow:2 WDOG Watchdog
- * +- slow:3 UART0 primary UART
- * +- slow:4 TIMER_APP Application timer - used in Linux
- * +- slow:5 KEYPAD controller
- * +- slow:6 GPIO controller
- * +- slow:7 RTC controller
- * +- slow:8 BT Bus Tracer (not used currently)
- * +- slow:9 EH Event Handler (not used currently)
- * +- slow:a TIMER_ACC Access style timer (not used currently)
- * +- slow:b PPM (U335 only, what is that?)
- */
-
-/*
- * Reset control functions. We remember if a block has been
- * taken out of reset and don't remove the reset assertion again
- * and vice versa. Currently we only remove resets so the
- * enablement function is defined out.
- */
-static void syscon_block_reset_enable(struct clk *clk)
-{
- u16 val;
- unsigned long iflags;
-
- /* Not all blocks support resetting */
- if (!clk->res_reg || !clk->res_mask)
- return;
- spin_lock_irqsave(&syscon_resetreg_lock, iflags);
- val = readw(clk->res_reg);
- val |= clk->res_mask;
- writew(val, clk->res_reg);
- spin_unlock_irqrestore(&syscon_resetreg_lock, iflags);
- clk->reset = true;
-}
-
-static void syscon_block_reset_disable(struct clk *clk)
-{
- u16 val;
- unsigned long iflags;
-
- /* Not all blocks support resetting */
- if (!clk->res_reg || !clk->res_mask)
- return;
- spin_lock_irqsave(&syscon_resetreg_lock, iflags);
- val = readw(clk->res_reg);
- val &= ~clk->res_mask;
- writew(val, clk->res_reg);
- spin_unlock_irqrestore(&syscon_resetreg_lock, iflags);
- clk->reset = false;
-}
-
-int __clk_get(struct clk *clk)
-{
- u16 val;
-
- /* The MMC and MSPRO clocks need some special set-up */
- if (!strcmp(clk->name, "MCLK")) {
- /* Set default MMC clock divisor to 18.9 MHz */
- writew(0x0054U, U300_SYSCON_VBASE + U300_SYSCON_MMF0R);
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMCR);
- /* Disable the MMC feedback clock */
- val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE;
- /* Disable MSPRO frequency */
- val &= ~U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_MMCR);
- }
- if (!strcmp(clk->name, "MSPRO")) {
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMCR);
- /* Disable the MMC feedback clock */
- val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE;
- /* Enable MSPRO frequency */
- val |= U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_MMCR);
- }
- return 1;
-}
-EXPORT_SYMBOL(__clk_get);
-
-void __clk_put(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(__clk_put);
-
-static void syscon_clk_disable(struct clk *clk)
-{
- unsigned long iflags;
-
- /* Don't touch the hardware controlled clocks */
- if (clk->hw_ctrld)
- return;
-
- spin_lock_irqsave(&syscon_clkreg_lock, iflags);
- writew(clk->clk_val, U300_SYSCON_VBASE + U300_SYSCON_SBCDR);
- spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
-}
-
-static void syscon_clk_enable(struct clk *clk)
-{
- unsigned long iflags;
-
- /* Don't touch the hardware controlled clocks */
- if (clk->hw_ctrld)
- return;
-
- spin_lock_irqsave(&syscon_clkreg_lock, iflags);
- writew(clk->clk_val, U300_SYSCON_VBASE + U300_SYSCON_SBCER);
- spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
-}
-
-static u16 syscon_clk_get_rate(void)
-{
- u16 val;
- unsigned long iflags;
-
- spin_lock_irqsave(&syscon_clkreg_lock, iflags);
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
- val &= U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
- spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
- return val;
-}
-
-#ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER
-static void enable_i2s0_vcxo(void)
-{
- u16 val;
- unsigned long iflags;
-
- spin_lock_irqsave(&syscon_clkreg_lock, iflags);
- /* Set I2S0 to use the VCXO 26 MHz clock */
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
- val |= U300_SYSCON_CCR_TURN_VCXO_ON;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
- val |= U300_SYSCON_CCR_I2S0_USE_VCXO;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR);
- val |= U300_SYSCON_CEFR_I2S0_CLK_EN;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR);
- spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
-}
-
-static void enable_i2s1_vcxo(void)
-{
- u16 val;
- unsigned long iflags;
-
- spin_lock_irqsave(&syscon_clkreg_lock, iflags);
- /* Set I2S1 to use the VCXO 26 MHz clock */
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
- val |= U300_SYSCON_CCR_TURN_VCXO_ON;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
- val |= U300_SYSCON_CCR_I2S1_USE_VCXO;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR);
- val |= U300_SYSCON_CEFR_I2S1_CLK_EN;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR);
- spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
-}
-
-static void disable_i2s0_vcxo(void)
-{
- u16 val;
- unsigned long iflags;
-
- spin_lock_irqsave(&syscon_clkreg_lock, iflags);
- /* Disable I2S0 use of the VCXO 26 MHz clock */
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
- val &= ~U300_SYSCON_CCR_I2S0_USE_VCXO;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
- /* Deactivate VCXO if no one else is using VCXO */
- if (!(val & U300_SYSCON_CCR_I2S1_USE_VCXO))
- val &= ~U300_SYSCON_CCR_TURN_VCXO_ON;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR);
- val &= ~U300_SYSCON_CEFR_I2S0_CLK_EN;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR);
- spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
-}
-
-static void disable_i2s1_vcxo(void)
-{
- u16 val;
- unsigned long iflags;
-
- spin_lock_irqsave(&syscon_clkreg_lock, iflags);
- /* Disable I2S1 use of the VCXO 26 MHz clock */
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
- val &= ~U300_SYSCON_CCR_I2S1_USE_VCXO;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
- /* Deactivate VCXO if no one else is using VCXO */
- if (!(val & U300_SYSCON_CCR_I2S0_USE_VCXO))
- val &= ~U300_SYSCON_CCR_TURN_VCXO_ON;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR);
- val &= ~U300_SYSCON_CEFR_I2S0_CLK_EN;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR);
- spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
-}
-#endif /* CONFIG_MACH_U300_USE_I2S_AS_MASTER */
-
-
-static void syscon_clk_rate_set_mclk(unsigned long rate)
-{
- u16 val;
- u32 reg;
- unsigned long iflags;
-
- switch (rate) {
- case 18900000:
- val = 0x0054;
- break;
- case 20800000:
- val = 0x0044;
- break;
- case 23100000:
- val = 0x0043;
- break;
- case 26000000:
- val = 0x0033;
- break;
- case 29700000:
- val = 0x0032;
- break;
- case 34700000:
- val = 0x0022;
- break;
- case 41600000:
- val = 0x0021;
- break;
- case 52000000:
- val = 0x0011;
- break;
- case 104000000:
- val = 0x0000;
- break;
- default:
- printk(KERN_ERR "Trying to set MCLK to unknown speed! %ld\n",
- rate);
- return;
- }
-
- spin_lock_irqsave(&syscon_clkreg_lock, iflags);
- reg = readw(U300_SYSCON_VBASE + U300_SYSCON_MMF0R) &
- ~U300_SYSCON_MMF0R_MASK;
- writew(reg | val, U300_SYSCON_VBASE + U300_SYSCON_MMF0R);
- spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
-}
-
-void syscon_clk_rate_set_cpuclk(unsigned long rate)
-{
- u16 val;
- unsigned long iflags;
-
- switch (rate) {
- case 13000000:
- val = U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER;
- break;
- case 52000000:
- val = U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE;
- break;
- case 104000000:
- val = U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH;
- break;
- case 208000000:
- val = U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST;
- break;
- default:
- return;
- }
- spin_lock_irqsave(&syscon_clkreg_lock, iflags);
- val |= readw(U300_SYSCON_VBASE + U300_SYSCON_CCR) &
- ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK ;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
- spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
-}
-EXPORT_SYMBOL(syscon_clk_rate_set_cpuclk);
-
-void clk_disable(struct clk *clk)
-{
- unsigned long iflags;
-
- spin_lock_irqsave(&clk->lock, iflags);
- if (clk->usecount > 0 && !(--clk->usecount)) {
- /* some blocks lack clocking registers and cannot be disabled */
- if (clk->disable)
- clk->disable(clk);
- if (likely((u32)clk->parent))
- clk_disable(clk->parent);
- }
-#ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER
- if (unlikely(!strcmp(clk->name, "I2S0")))
- disable_i2s0_vcxo();
- if (unlikely(!strcmp(clk->name, "I2S1")))
- disable_i2s1_vcxo();
-#endif
- spin_unlock_irqrestore(&clk->lock, iflags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-int clk_enable(struct clk *clk)
-{
- int ret = 0;
- unsigned long iflags;
-
- spin_lock_irqsave(&clk->lock, iflags);
- if (clk->usecount++ == 0) {
- if (likely((u32)clk->parent))
- ret = clk_enable(clk->parent);
-
- if (unlikely(ret != 0))
- clk->usecount--;
- else {
- /* remove reset line (we never enable reset again) */
- syscon_block_reset_disable(clk);
- /* clocks without enable function are always on */
- if (clk->enable)
- clk->enable(clk);
-#ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER
- if (unlikely(!strcmp(clk->name, "I2S0")))
- enable_i2s0_vcxo();
- if (unlikely(!strcmp(clk->name, "I2S1")))
- enable_i2s1_vcxo();
-#endif
- }
- }
- spin_unlock_irqrestore(&clk->lock, iflags);
- return ret;
-
-}
-EXPORT_SYMBOL(clk_enable);
-
-/* Returns the clock rate in Hz */
-static unsigned long clk_get_rate_cpuclk(struct clk *clk)
-{
- u16 val;
-
- val = syscon_clk_get_rate();
-
- switch (val) {
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
- return 13000000;
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
- return 52000000;
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
- return 104000000;
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
- return 208000000;
- default:
- break;
- }
- return clk->rate;
-}
-
-static unsigned long clk_get_rate_ahb_clk(struct clk *clk)
-{
- u16 val;
-
- val = syscon_clk_get_rate();
-
- switch (val) {
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
- return 6500000;
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
- return 26000000;
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
- return 52000000;
- default:
- break;
- }
- return clk->rate;
-
-}
-
-static unsigned long clk_get_rate_emif_clk(struct clk *clk)
-{
- u16 val;
-
- val = syscon_clk_get_rate();
-
- switch (val) {
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
- return 13000000;
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
- return 52000000;
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
- return 104000000;
- default:
- break;
- }
- return clk->rate;
-
-}
-
-static unsigned long clk_get_rate_xgamclk(struct clk *clk)
-{
- u16 val;
-
- val = syscon_clk_get_rate();
-
- switch (val) {
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
- return 6500000;
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
- return 26000000;
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
- return 52000000;
- default:
- break;
- }
-
- return clk->rate;
-}
-
-static unsigned long clk_get_rate_mclk(struct clk *clk)
-{
- u16 val;
-
- val = syscon_clk_get_rate();
-
- switch (val) {
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
- /*
- * Here, the 208 MHz PLL gets shut down and the always
- * on 13 MHz PLL used for RTC etc kicks into use
- * instead.
- */
- return 13000000;
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
- {
- /*
- * This clock is under program control. The register is
- * divided in two nybbles, bit 7-4 gives cycles-1 to count
- * high, bit 3-0 gives cycles-1 to count low. Distribute
- * these with no more than 1 cycle difference between
- * low and high and add low and high to get the actual
- * divisor. The base PLL is 208 MHz. Writing 0x00 will
- * divide by 1 and 1 so the highest frequency possible
- * is 104 MHz.
- *
- * e.g. 0x54 =>
- * f = 208 / ((5+1) + (4+1)) = 208 / 11 = 18.9 MHz
- */
- u16 val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMF0R) &
- U300_SYSCON_MMF0R_MASK;
- switch (val) {
- case 0x0054:
- return 18900000;
- case 0x0044:
- return 20800000;
- case 0x0043:
- return 23100000;
- case 0x0033:
- return 26000000;
- case 0x0032:
- return 29700000;
- case 0x0022:
- return 34700000;
- case 0x0021:
- return 41600000;
- case 0x0011:
- return 52000000;
- case 0x0000:
- return 104000000;
- default:
- break;
- }
- }
- default:
- break;
- }
-
- return clk->rate;
-}
-
-static unsigned long clk_get_rate_i2s_i2c_spi(struct clk *clk)
-{
- u16 val;
-
- val = syscon_clk_get_rate();
-
- switch (val) {
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
- return 13000000;
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
- case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
- return 26000000;
- default:
- break;
- }
-
- return clk->rate;
-}
-
-unsigned long clk_get_rate(struct clk *clk)
-{
- if (clk->get_rate)
- return clk->get_rate(clk);
- else
- return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-static unsigned long clk_round_rate_mclk(struct clk *clk, unsigned long rate)
-{
- if (rate <= 18900000)
- return 18900000;
- if (rate <= 20800000)
- return 20800000;
- if (rate <= 23100000)
- return 23100000;
- if (rate <= 26000000)
- return 26000000;
- if (rate <= 29700000)
- return 29700000;
- if (rate <= 34700000)
- return 34700000;
- if (rate <= 41600000)
- return 41600000;
- if (rate <= 52000000)
- return 52000000;
- return -EINVAL;
-}
-
-static unsigned long clk_round_rate_cpuclk(struct clk *clk, unsigned long rate)
-{
- if (rate <= 13000000)
- return 13000000;
- if (rate <= 52000000)
- return 52000000;
- if (rate <= 104000000)
- return 104000000;
- if (rate <= 208000000)
- return 208000000;
- return -EINVAL;
-}
-
-/*
- * This adjusts a requested rate to the closest exact rate
- * a certain clock can provide. For a fixed clock it's
- * mostly clk->rate.
- */
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
- /* TODO: get appropriate switches for EMIFCLK, AHBCLK and MCLK */
- /* Else default to fixed value */
-
- if (clk->round_rate) {
- return (long) clk->round_rate(clk, rate);
- } else {
- printk(KERN_ERR "clock: Failed to round rate of %s\n",
- clk->name);
- }
- return (long) clk->rate;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-static int clk_set_rate_mclk(struct clk *clk, unsigned long rate)
-{
- syscon_clk_rate_set_mclk(clk_round_rate(clk, rate));
- return 0;
-}
-
-static int clk_set_rate_cpuclk(struct clk *clk, unsigned long rate)
-{
- syscon_clk_rate_set_cpuclk(clk_round_rate(clk, rate));
- return 0;
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- /* TODO: set for EMIFCLK and AHBCLK */
- /* Else assume the clock is fixed and fail */
- if (clk->set_rate) {
- return clk->set_rate(clk, rate);
- } else {
- printk(KERN_ERR "clock: Failed to set %s to %ld hz\n",
- clk->name, rate);
- return -EINVAL;
- }
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-/*
- * Clock definitions. The clock parents are set to respective
- * bridge and the clock framework makes sure that the clocks have
- * parents activated and are brought out of reset when in use.
- *
- * Clocks that have hw_ctrld = true are hw controlled, and the hw
- * can by itself turn these clocks on and off.
- * So in other words, we don't really have to care about them.
- */
-
-static struct clk amba_clk = {
- .name = "AMBA",
- .rate = 52000000, /* this varies! */
- .hw_ctrld = true,
- .reset = false,
- .lock = __SPIN_LOCK_UNLOCKED(amba_clk.lock),
-};
-
-/*
- * These blocks are connected directly to the AMBA bus
- * with no bridge.
- */
-
-static struct clk cpu_clk = {
- .name = "CPU",
- .parent = &amba_clk,
- .rate = 208000000, /* this varies! */
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
- .res_mask = U300_SYSCON_RRR_CPU_RESET_EN,
- .set_rate = clk_set_rate_cpuclk,
- .get_rate = clk_get_rate_cpuclk,
- .round_rate = clk_round_rate_cpuclk,
- .lock = __SPIN_LOCK_UNLOCKED(cpu_clk.lock),
-};
-
-static struct clk nandif_clk = {
- .name = "FSMC",
- .parent = &amba_clk,
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
- .res_mask = U300_SYSCON_RRR_NANDIF_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_NANDIF_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(nandif_clk.lock),
-};
-
-static struct clk semi_clk = {
- .name = "SEMI",
- .parent = &amba_clk,
- .rate = 0, /* FIXME */
- /* It is not possible to reset SEMI */
- .hw_ctrld = false,
- .reset = false,
- .clk_val = U300_SYSCON_SBCER_SEMI_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(semi_clk.lock),
-};
-
-#ifdef CONFIG_MACH_U300_BS335
-static struct clk isp_clk = {
- .name = "ISP",
- .parent = &amba_clk,
- .rate = 0, /* FIXME */
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
- .res_mask = U300_SYSCON_RRR_ISP_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_ISP_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(isp_clk.lock),
-};
-
-static struct clk cds_clk = {
- .name = "CDS",
- .parent = &amba_clk,
- .rate = 0, /* FIXME */
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
- .res_mask = U300_SYSCON_RRR_CDS_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_CDS_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(cds_clk.lock),
-};
-#endif
-
-static struct clk dma_clk = {
- .name = "DMA",
- .parent = &amba_clk,
- .rate = 52000000, /* this varies! */
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
- .res_mask = U300_SYSCON_RRR_DMAC_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_DMAC_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(dma_clk.lock),
-};
-
-static struct clk aaif_clk = {
- .name = "AAIF",
- .parent = &amba_clk,
- .rate = 52000000, /* this varies! */
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
- .res_mask = U300_SYSCON_RRR_AAIF_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_AAIF_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(aaif_clk.lock),
-};
-
-static struct clk apex_clk = {
- .name = "APEX",
- .parent = &amba_clk,
- .rate = 0, /* FIXME */
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
- .res_mask = U300_SYSCON_RRR_APEX_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_APEX_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(apex_clk.lock),
-};
-
-static struct clk video_enc_clk = {
- .name = "VIDEO_ENC",
- .parent = &amba_clk,
- .rate = 208000000, /* this varies! */
- .hw_ctrld = false,
- .reset = false,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
- /* This has XGAM in the name but refers to the video encoder */
- .res_mask = U300_SYSCON_RRR_XGAM_VC_SYNC_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_VIDEO_ENC_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(video_enc_clk.lock),
-};
-
-static struct clk xgam_clk = {
- .name = "XGAMCLK",
- .parent = &amba_clk,
- .rate = 52000000, /* this varies! */
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
- .res_mask = U300_SYSCON_RRR_XGAM_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_XGAM_CLK_EN,
- .get_rate = clk_get_rate_xgamclk,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(xgam_clk.lock),
-};
-
-/* This clock is used to activate the video encoder */
-static struct clk ahb_clk = {
- .name = "AHB",
- .parent = &amba_clk,
- .rate = 52000000, /* this varies! */
- .hw_ctrld = false, /* This one is set to false due to HW bug */
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
- .res_mask = U300_SYSCON_RRR_AHB_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_AHB_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .get_rate = clk_get_rate_ahb_clk,
- .lock = __SPIN_LOCK_UNLOCKED(ahb_clk.lock),
-};
-
-
-/*
- * Clocks on the AHB bridge
- */
-
-static struct clk ahb_subsys_clk = {
- .name = "AHB_SUBSYS",
- .parent = &amba_clk,
- .rate = 52000000, /* this varies! */
- .hw_ctrld = true,
- .reset = false,
- .clk_val = U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .get_rate = clk_get_rate_ahb_clk,
- .lock = __SPIN_LOCK_UNLOCKED(ahb_subsys_clk.lock),
-};
-
-static struct clk intcon_clk = {
- .name = "INTCON",
- .parent = &ahb_subsys_clk,
- .rate = 52000000, /* this varies! */
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
- .res_mask = U300_SYSCON_RRR_INTCON_RESET_EN,
- /* INTCON can be reset but not clock-gated */
- .lock = __SPIN_LOCK_UNLOCKED(intcon_clk.lock),
-
-};
-
-static struct clk mspro_clk = {
- .name = "MSPRO",
- .parent = &ahb_subsys_clk,
- .rate = 0, /* FIXME */
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
- .res_mask = U300_SYSCON_RRR_MSPRO_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_MSPRO_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(mspro_clk.lock),
-};
-
-static struct clk emif_clk = {
- .name = "EMIF",
- .parent = &ahb_subsys_clk,
- .rate = 104000000, /* this varies! */
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
- .res_mask = U300_SYSCON_RRR_EMIF_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_EMIF_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .get_rate = clk_get_rate_emif_clk,
- .lock = __SPIN_LOCK_UNLOCKED(emif_clk.lock),
-};
-
-
-/*
- * Clocks on the FAST bridge
- */
-static struct clk fast_clk = {
- .name = "FAST_BRIDGE",
- .parent = &amba_clk,
- .rate = 13000000, /* this varies! */
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
- .res_mask = U300_SYSCON_RFR_FAST_BRIDGE_RESET_ENABLE,
- .clk_val = U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(fast_clk.lock),
-};
-
-/*
- * The MMCI apb_pclk is hardwired to the same terminal as the
- * external MCI clock. Thus this will be referenced twice.
- */
-static struct clk mmcsd_clk = {
- .name = "MCLK",
- .parent = &fast_clk,
- .rate = 18900000, /* this varies! */
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
- .res_mask = U300_SYSCON_RFR_MMC_RESET_ENABLE,
- .clk_val = U300_SYSCON_SBCER_MMC_CLK_EN,
- .get_rate = clk_get_rate_mclk,
- .set_rate = clk_set_rate_mclk,
- .round_rate = clk_round_rate_mclk,
- .disable = syscon_clk_disable,
- .enable = syscon_clk_enable,
- .lock = __SPIN_LOCK_UNLOCKED(mmcsd_clk.lock),
-};
-
-static struct clk i2s0_clk = {
- .name = "i2s0",
- .parent = &fast_clk,
- .rate = 26000000, /* this varies! */
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
- .res_mask = U300_SYSCON_RFR_PCM_I2S0_RESET_ENABLE,
- .clk_val = U300_SYSCON_SBCER_I2S0_CORE_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .get_rate = clk_get_rate_i2s_i2c_spi,
- .lock = __SPIN_LOCK_UNLOCKED(i2s0_clk.lock),
-};
-
-static struct clk i2s1_clk = {
- .name = "i2s1",
- .parent = &fast_clk,
- .rate = 26000000, /* this varies! */
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
- .res_mask = U300_SYSCON_RFR_PCM_I2S1_RESET_ENABLE,
- .clk_val = U300_SYSCON_SBCER_I2S1_CORE_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .get_rate = clk_get_rate_i2s_i2c_spi,
- .lock = __SPIN_LOCK_UNLOCKED(i2s1_clk.lock),
-};
-
-static struct clk i2c0_clk = {
- .name = "I2C0",
- .parent = &fast_clk,
- .rate = 26000000, /* this varies! */
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
- .res_mask = U300_SYSCON_RFR_I2C0_RESET_ENABLE,
- .clk_val = U300_SYSCON_SBCER_I2C0_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .get_rate = clk_get_rate_i2s_i2c_spi,
- .lock = __SPIN_LOCK_UNLOCKED(i2c0_clk.lock),
-};
-
-static struct clk i2c1_clk = {
- .name = "I2C1",
- .parent = &fast_clk,
- .rate = 26000000, /* this varies! */
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
- .res_mask = U300_SYSCON_RFR_I2C1_RESET_ENABLE,
- .clk_val = U300_SYSCON_SBCER_I2C1_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .get_rate = clk_get_rate_i2s_i2c_spi,
- .lock = __SPIN_LOCK_UNLOCKED(i2c1_clk.lock),
-};
-
-/*
- * The SPI apb_pclk is hardwired to the same terminal as the
- * external SPI clock. Thus this will be referenced twice.
- */
-static struct clk spi_clk = {
- .name = "SPI",
- .parent = &fast_clk,
- .rate = 26000000, /* this varies! */
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
- .res_mask = U300_SYSCON_RFR_SPI_RESET_ENABLE,
- .clk_val = U300_SYSCON_SBCER_SPI_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .get_rate = clk_get_rate_i2s_i2c_spi,
- .lock = __SPIN_LOCK_UNLOCKED(spi_clk.lock),
-};
-
-#ifdef CONFIG_MACH_U300_BS335
-static struct clk uart1_pclk = {
- .name = "UART1_PCLK",
- .parent = &fast_clk,
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
- .res_mask = U300_SYSCON_RFR_UART1_RESET_ENABLE,
- .clk_val = U300_SYSCON_SBCER_UART1_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(uart1_pclk.lock),
-};
-
-/* This one is hardwired to PLL13 */
-static struct clk uart1_clk = {
- .name = "UART1_CLK",
- .rate = 13000000,
- .hw_ctrld = true,
- .lock = __SPIN_LOCK_UNLOCKED(uart1_clk.lock),
-};
-#endif
-
-
-/*
- * Clocks on the SLOW bridge
- */
-static struct clk slow_clk = {
- .name = "SLOW_BRIDGE",
- .parent = &amba_clk,
- .rate = 13000000,
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
- .res_mask = U300_SYSCON_RSR_SLOW_BRIDGE_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(slow_clk.lock),
-};
-
-/* TODO: implement SYSCON clock? */
-
-static struct clk wdog_clk = {
- .name = "WDOG",
- .parent = &slow_clk,
- .hw_ctrld = false,
- .rate = 32768,
- .reset = false,
- /* This is always on, cannot be enabled/disabled or reset */
- .lock = __SPIN_LOCK_UNLOCKED(wdog_clk.lock),
-};
-
-static struct clk uart0_pclk = {
- .name = "UART0_PCLK",
- .parent = &slow_clk,
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
- .res_mask = U300_SYSCON_RSR_UART_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_UART_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(uart0_pclk.lock),
-};
-
-/* This one is hardwired to PLL13 */
-static struct clk uart0_clk = {
- .name = "UART0_CLK",
- .parent = &slow_clk,
- .rate = 13000000,
- .hw_ctrld = true,
- .lock = __SPIN_LOCK_UNLOCKED(uart0_clk.lock),
-};
-
-static struct clk keypad_clk = {
- .name = "KEYPAD",
- .parent = &slow_clk,
- .rate = 32768,
- .hw_ctrld = false,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
- .res_mask = U300_SYSCON_RSR_KEYPAD_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_KEYPAD_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(keypad_clk.lock),
-};
-
-static struct clk gpio_clk = {
- .name = "GPIO",
- .parent = &slow_clk,
- .rate = 13000000,
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
- .res_mask = U300_SYSCON_RSR_GPIO_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_GPIO_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(gpio_clk.lock),
-};
-
-static struct clk rtc_clk = {
- .name = "RTC",
- .parent = &slow_clk,
- .rate = 32768,
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
- .res_mask = U300_SYSCON_RSR_RTC_RESET_EN,
- /* This clock is always on, cannot be enabled/disabled */
- .lock = __SPIN_LOCK_UNLOCKED(rtc_clk.lock),
-};
-
-static struct clk bustr_clk = {
- .name = "BUSTR",
- .parent = &slow_clk,
- .rate = 13000000,
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
- .res_mask = U300_SYSCON_RSR_BTR_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_BTR_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(bustr_clk.lock),
-};
-
-static struct clk evhist_clk = {
- .name = "EVHIST",
- .parent = &slow_clk,
- .rate = 13000000,
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
- .res_mask = U300_SYSCON_RSR_EH_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_EH_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(evhist_clk.lock),
-};
-
-static struct clk timer_clk = {
- .name = "TIMER",
- .parent = &slow_clk,
- .rate = 13000000,
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
- .res_mask = U300_SYSCON_RSR_ACC_TMR_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_ACC_TMR_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(timer_clk.lock),
-};
-
-/*
- * There is a binary divider in the hardware that divides
- * the 13MHz PLL by 13 down to 1 MHz.
- */
-static struct clk app_timer_clk = {
- .name = "TIMER_APP",
- .parent = &slow_clk,
- .rate = 1000000,
- .hw_ctrld = true,
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
- .res_mask = U300_SYSCON_RSR_APP_TMR_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_APP_TMR_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(app_timer_clk.lock),
-};
-
-#ifdef CONFIG_MACH_U300_BS335
-static struct clk ppm_clk = {
- .name = "PPM",
- .parent = &slow_clk,
- .rate = 0, /* FIXME */
- .hw_ctrld = true, /* TODO: Look up if it is hw ctrld or not */
- .reset = true,
- .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
- .res_mask = U300_SYSCON_RSR_PPM_RESET_EN,
- .clk_val = U300_SYSCON_SBCER_PPM_CLK_EN,
- .enable = syscon_clk_enable,
- .disable = syscon_clk_disable,
- .lock = __SPIN_LOCK_UNLOCKED(ppm_clk.lock),
-};
-#endif
-
-#define DEF_LOOKUP(devid, clkref) \
- { \
- .dev_id = devid, \
- .clk = clkref, \
- }
-
-#define DEF_LOOKUP_CON(devid, conid, clkref) \
- { \
- .dev_id = devid, \
- .con_id = conid, \
- .clk = clkref, \
- }
-
-/*
- * Here we only define clocks that are meaningful to
- * look up through clockdevice.
- */
-static struct clk_lookup lookups[] = {
- /* Connected directly to the AMBA bus */
- DEF_LOOKUP("amba", &amba_clk),
- DEF_LOOKUP("cpu", &cpu_clk),
- DEF_LOOKUP("fsmc-nand", &nandif_clk),
- DEF_LOOKUP("semi", &semi_clk),
-#ifdef CONFIG_MACH_U300_BS335
- DEF_LOOKUP("isp", &isp_clk),
- DEF_LOOKUP("cds", &cds_clk),
-#endif
- DEF_LOOKUP("dma", &dma_clk),
- DEF_LOOKUP("msl", &aaif_clk),
- DEF_LOOKUP("apex", &apex_clk),
- DEF_LOOKUP("video_enc", &video_enc_clk),
- DEF_LOOKUP("xgam", &xgam_clk),
- DEF_LOOKUP("ahb", &ahb_clk),
- /* AHB bridge clocks */
- DEF_LOOKUP("ahb_subsys", &ahb_subsys_clk),
- DEF_LOOKUP("intcon", &intcon_clk),
- DEF_LOOKUP_CON("intcon", "apb_pclk", &intcon_clk),
- DEF_LOOKUP("mspro", &mspro_clk),
- DEF_LOOKUP("pl172", &emif_clk),
- DEF_LOOKUP_CON("pl172", "apb_pclk", &emif_clk),
- /* FAST bridge clocks */
- DEF_LOOKUP("fast", &fast_clk),
- DEF_LOOKUP("mmci", &mmcsd_clk),
- DEF_LOOKUP_CON("mmci", "apb_pclk", &mmcsd_clk),
- /*
- * The .0 and .1 identifiers on these comes from the platform device
- * .id field and are assigned when the platform devices are registered.
- */
- DEF_LOOKUP("i2s.0", &i2s0_clk),
- DEF_LOOKUP("i2s.1", &i2s1_clk),
- DEF_LOOKUP("stu300.0", &i2c0_clk),
- DEF_LOOKUP("stu300.1", &i2c1_clk),
- DEF_LOOKUP("pl022", &spi_clk),
- DEF_LOOKUP_CON("pl022", "apb_pclk", &spi_clk),
-#ifdef CONFIG_MACH_U300_BS335
- DEF_LOOKUP("uart1", &uart1_clk),
- DEF_LOOKUP_CON("uart1", "apb_pclk", &uart1_pclk),
-#endif
- /* SLOW bridge clocks */
- DEF_LOOKUP("slow", &slow_clk),
- DEF_LOOKUP("coh901327_wdog", &wdog_clk),
- DEF_LOOKUP("uart0", &uart0_clk),
- DEF_LOOKUP_CON("uart0", "apb_pclk", &uart0_pclk),
- DEF_LOOKUP("apptimer", &app_timer_clk),
- DEF_LOOKUP("coh901461-keypad", &keypad_clk),
- DEF_LOOKUP("u300-gpio", &gpio_clk),
- DEF_LOOKUP("rtc-coh901331", &rtc_clk),
- DEF_LOOKUP("bustr", &bustr_clk),
- DEF_LOOKUP("evhist", &evhist_clk),
- DEF_LOOKUP("timer", &timer_clk),
-#ifdef CONFIG_MACH_U300_BS335
- DEF_LOOKUP("ppm", &ppm_clk),
-#endif
-};
-
-static void __init clk_register(void)
-{
- /* Register the lookups */
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-}
-
-#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG))
-/*
- * The following makes it possible to view the status (especially
- * reference count and reset status) for the clocks in the platform
- * by looking into the special file <debugfs>/u300_clocks
- */
-
-/* A list of all clocks in the platform */
-static struct clk *clks[] = {
- /* Top node clock for the AMBA bus */
- &amba_clk,
- /* Connected directly to the AMBA bus */
- &cpu_clk,
- &nandif_clk,
- &semi_clk,
-#ifdef CONFIG_MACH_U300_BS335
- &isp_clk,
- &cds_clk,
-#endif
- &dma_clk,
- &aaif_clk,
- &apex_clk,
- &video_enc_clk,
- &xgam_clk,
- &ahb_clk,
-
- /* AHB bridge clocks */
- &ahb_subsys_clk,
- &intcon_clk,
- &mspro_clk,
- &emif_clk,
- /* FAST bridge clocks */
- &fast_clk,
- &mmcsd_clk,
- &i2s0_clk,
- &i2s1_clk,
- &i2c0_clk,
- &i2c1_clk,
- &spi_clk,
-#ifdef CONFIG_MACH_U300_BS335
- &uart1_clk,
- &uart1_pclk,
-#endif
- /* SLOW bridge clocks */
- &slow_clk,
- &wdog_clk,
- &uart0_clk,
- &uart0_pclk,
- &app_timer_clk,
- &keypad_clk,
- &gpio_clk,
- &rtc_clk,
- &bustr_clk,
- &evhist_clk,
- &timer_clk,
-#ifdef CONFIG_MACH_U300_BS335
- &ppm_clk,
-#endif
-};
-
-static int u300_clocks_show(struct seq_file *s, void *data)
-{
- struct clk *clk;
- int i;
-
- seq_printf(s, "CLOCK DEVICE RESET STATE\t" \
- "ACTIVE\tUSERS\tHW CTRL FREQ\n");
- seq_printf(s, "---------------------------------------------" \
- "-----------------------------------------\n");
- for (i = 0; i < ARRAY_SIZE(clks); i++) {
- clk = clks[i];
- if (clk != ERR_PTR(-ENOENT)) {
- /* Format clock and device name nicely */
- char cdp[33];
- int chars;
-
- chars = snprintf(&cdp[0], 17, "%s", clk->name);
- while (chars < 16) {
- cdp[chars] = ' ';
- chars++;
- }
- chars = snprintf(&cdp[16], 17, "%s", clk->dev ?
- dev_name(clk->dev) : "N/A");
- while (chars < 16) {
- cdp[chars+16] = ' ';
- chars++;
- }
- cdp[32] = '\0';
- if (clk->get_rate || clk->rate != 0)
- seq_printf(s,
- "%s%s\t%s\t%d\t%s\t%lu Hz\n",
- &cdp[0],
- clk->reset ?
- "ASSERTED" : "RELEASED",
- clk->usecount ? "ON" : "OFF",
- clk->usecount,
- clk->hw_ctrld ? "YES" : "NO ",
- clk_get_rate(clk));
- else
- seq_printf(s,
- "%s%s\t%s\t%d\t%s\t" \
- "(unknown rate)\n",
- &cdp[0],
- clk->reset ?
- "ASSERTED" : "RELEASED",
- clk->usecount ? "ON" : "OFF",
- clk->usecount,
- clk->hw_ctrld ? "YES" : "NO ");
- }
- }
- return 0;
-}
-
-static int u300_clocks_open(struct inode *inode, struct file *file)
-{
- return single_open(file, u300_clocks_show, NULL);
-}
-
-static const struct file_operations u300_clocks_operations = {
- .open = u300_clocks_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int __init init_clk_read_debugfs(void)
-{
- /* Expose a simple debugfs interface to view all clocks */
- (void) debugfs_create_file("u300_clocks", S_IFREG | S_IRUGO,
- NULL, NULL,
- &u300_clocks_operations);
- return 0;
-}
-/*
- * This needs to come in after the core_initcall() for the
- * overall clocks, because debugfs is not available until
- * the subsystems come up.
- */
-module_init(init_clk_read_debugfs);
-#endif
-
-int __init u300_clock_init(void)
-{
- u16 val;
-
- /*
- * FIXME: shall all this powermanagement stuff really live here???
- */
-
- /* Set system to run at PLL208, max performance, a known state. */
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
- val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
- /* Wait for the PLL208 to lock if not locked in yet */
- while (!(readw(U300_SYSCON_VBASE + U300_SYSCON_CSR) &
- U300_SYSCON_CSR_PLL208_LOCK_IND));
-
- /* Power management enable */
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMCR);
- val |= U300_SYSCON_PMCR_PWR_MGNT_ENABLE;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMCR);
-
- clk_register();
-
- /*
- * Some of these may be on when we boot the system so make sure they
- * are turned OFF.
- */
- syscon_block_reset_enable(&timer_clk);
- timer_clk.disable(&timer_clk);
-
- /*
- * These shall be turned on by default when we boot the system
- * so make sure they are ON. (Adding CPU here is a bit too much.)
- * These clocks will be claimed by drivers later.
- */
- syscon_block_reset_disable(&semi_clk);
- syscon_block_reset_disable(&emif_clk);
- clk_enable(&semi_clk);
- clk_enable(&emif_clk);
-
- return 0;
-}
diff --git a/arch/arm/mach-u300/clock.h b/arch/arm/mach-u300/clock.h
deleted file mode 100644
index 4f50ca8f901e..000000000000
--- a/arch/arm/mach-u300/clock.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * arch/arm/mach-u300/include/mach/clock.h
- *
- * Copyright (C) 2004 - 2005 Nokia corporation
- * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
- * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
- * Copyright (C) 2007-2009 ST-Ericsson AB
- * Adopted to ST-Ericsson U300 platforms by
- * Jonas Aaberg <jonas.aberg@stericsson.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#ifndef __MACH_CLOCK_H
-#define __MACH_CLOCK_H
-
-#include <linux/clk.h>
-
-struct clk {
- struct list_head node;
- struct module *owner;
- struct device *dev;
- const char *name;
- struct clk *parent;
-
- spinlock_t lock;
- unsigned long rate;
- bool reset;
- __u16 clk_val;
- __s8 usecount;
- void __iomem * res_reg;
- __u16 res_mask;
-
- bool hw_ctrld;
-
- void (*recalc) (struct clk *);
- int (*set_rate) (struct clk *, unsigned long);
- unsigned long (*get_rate) (struct clk *);
- unsigned long (*round_rate) (struct clk *, unsigned long);
- void (*init) (struct clk *);
- void (*enable) (struct clk *);
- void (*disable) (struct clk *);
-};
-
-int u300_clock_init(void);
-
-#endif
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index 33339745d432..03acf1883ec7 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -30,6 +30,7 @@
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/dma-mapping.h>
+#include <linux/platform_data/clk-u300.h>
#include <asm/types.h>
#include <asm/setup.h>
@@ -44,7 +45,6 @@
#include <mach/dma_channels.h>
#include <mach/gpio-u300.h>
-#include "clock.h"
#include "spi.h"
#include "i2c.h"
#include "u300-gpio.h"
@@ -1658,12 +1658,20 @@ void __init u300_init_irq(void)
int i;
/* initialize clocking early, we want to clock the INTCON */
- u300_clock_init();
+ u300_clk_init(U300_SYSCON_VBASE);
+
+ /* Bootstrap EMIF and SEMI clocks */
+ clk = clk_get_sys("pl172", NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_prepare_enable(clk);
+ clk = clk_get_sys("semi", NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_prepare_enable(clk);
/* Clock the interrupt controller */
clk = clk_get_sys("intcon", NULL);
BUG_ON(IS_ERR(clk));
- clk_enable(clk);
+ clk_prepare_enable(clk);
for (i = 0; i < U300_VIC_IRQS_END; i++)
set_bit(i, (unsigned long *) &mask[0]);
@@ -1811,13 +1819,6 @@ void __init u300_init_devices(void)
/* Check what platform we run and print some status information */
u300_init_check_chip();
- /* Set system to run at PLL208, max performance, a known state. */
- val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
- val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
- writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
- /* Wait for the PLL208 to lock if not locked in yet */
- while (!(readw(U300_SYSCON_VBASE + U300_SYSCON_CSR) &
- U300_SYSCON_CSR_PLL208_LOCK_IND));
/* Initialize SPI device with some board specifics */
u300_spi_init(&pl022_device);
diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c
index bc1c7897e82d..56ac06d38ec1 100644
--- a/arch/arm/mach-u300/timer.c
+++ b/arch/arm/mach-u300/timer.c
@@ -354,7 +354,7 @@ static void __init u300_timer_init(void)
/* Clock the interrupt controller */
clk = clk_get_sys("apptimer", NULL);
BUG_ON(IS_ERR(clk));
- clk_enable(clk);
+ clk_prepare_enable(clk);
rate = clk_get_rate(clk);
setup_sched_clock(u300_read_sched_clock, 32, rate);