aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2012-09-12 23:03:37 -0700
committerOlof Johansson <olof@lixom.net>2012-09-12 23:03:37 -0700
commit77ea4a300dc585e84062f45157d43897c9132c22 (patch)
tree3a6e19250b837be65477060870c33443a861dc1e /arch/arm
parentMerge tag 'mxs-dt-3.7' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/dt (diff)
parentclk: add of_clk_src_onecell_get() support (diff)
downloadlinux-dev-77ea4a300dc585e84062f45157d43897c9132c22.tar.xz
linux-dev-77ea4a300dc585e84062f45157d43897c9132c22.zip
Merge branch 'clk-3.7' of git://git.linaro.org/people/mturquette/linux into next/dt
* 'clk-3.7' of git://git.linaro.org/people/mturquette/linux: clk: add of_clk_src_onecell_get() support clk: ux500: Define smp_twd clock for u8500 mfd: dbx500: Provide a more accurate smp_twd clock clk: ux500: Support for prmcu_rate clock clk: Provide option for clk_get_rate to issue hw for new rate clock: max77686: Add driver for Maxim 77686 32Khz crystal oscillator. ARM: ux500: Switch to use common clock framework clk: ux500: Clock definitions for u8500 clk: ux500: First version of clock definitions for ux500 clk: ux500: Adapt PRCMU and PRCC clocks for common clk clk: versatile: make config option boolean clk: add Loongson1B clock support arm: mmp: make all SOCs use common clock by default clk: mmp: add clock definition for mmp2 clk: mmp: add clock definition for pxa910 clk: mmp: add clock definition for pxa168 clk: mmp: add mmp specific clocks clk: convert ARM RealView to common clk clk: prima2: move from arch/arm/mach to drivers/clk ARM: PRIMA2: convert to common clk and finish full clk tree
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig9
-rw-r--r--arch/arm/mach-mmp/Kconfig3
-rw-r--r--arch/arm/mach-prima2/Makefile1
-rw-r--r--arch/arm/mach-prima2/clock.c510
-rw-r--r--arch/arm/mach-prima2/prima2.c1
-rw-r--r--arch/arm/mach-prima2/timer.c8
-rw-r--r--arch/arm/mach-realview/core.c106
-rw-r--r--arch/arm/mach-realview/include/mach/clkdev.h16
-rw-r--r--arch/arm/mach-realview/realview_eb.c2
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c2
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c2
-rw-r--r--arch/arm/mach-realview/realview_pba8.c2
-rw-r--r--arch/arm/mach-realview/realview_pbx.c2
-rw-r--r--arch/arm/mach-ux500/Kconfig1
-rw-r--r--arch/arm/mach-ux500/Makefile2
-rw-r--r--arch/arm/mach-ux500/clock.c715
-rw-r--r--arch/arm/mach-ux500/clock.h164
-rw-r--r--arch/arm/mach-ux500/cpu.c14
18 files changed, 34 insertions, 1526 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c5f9ae5dbd1a..93d2fab25b30 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -273,7 +273,7 @@ config ARCH_INTEGRATOR
select ARM_AMBA
select ARCH_HAS_CPUFREQ
select COMMON_CLK
- select CLK_VERSATILE
+ select COMMON_CLK_VERSATILE
select HAVE_TCM
select ICST
select GENERIC_CLOCKEVENTS
@@ -289,13 +289,12 @@ config ARCH_INTEGRATOR
config ARCH_REALVIEW
bool "ARM Ltd. RealView family"
select ARM_AMBA
- select CLKDEV_LOOKUP
- select HAVE_MACH_CLKDEV
+ select COMMON_CLK
+ select COMMON_CLK_VERSATILE
select ICST
select GENERIC_CLOCKEVENTS
select ARCH_WANT_OPTIONAL_GPIOLIB
select PLAT_VERSATILE
- select PLAT_VERSATILE_CLOCK
select PLAT_VERSATILE_CLCD
select ARM_TIMER_SP804
select GPIO_PL061 if GPIOLIB
@@ -413,7 +412,7 @@ config ARCH_PRIMA2
select NO_IOPORT
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
- select CLKDEV_LOOKUP
+ select COMMON_CLK
select GENERIC_IRQ_CHIP
select MIGHT_HAVE_CACHE_L2X0
select PINCTRL
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index 7fddd01b85b9..d697d07a1bf0 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -108,18 +108,21 @@ endmenu
config CPU_PXA168
bool
select CPU_MOHAWK
+ select COMMON_CLK
help
Select code specific to PXA168
config CPU_PXA910
bool
select CPU_MOHAWK
+ select COMMON_CLK
help
Select code specific to PXA910
config CPU_MMP2
bool
select CPU_PJ4
+ select COMMON_CLK
help
Select code specific to MMP2. MMP2 is ARMv7 compatible.
diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
index 13dd1604d951..841847d56032 100644
--- a/arch/arm/mach-prima2/Makefile
+++ b/arch/arm/mach-prima2/Makefile
@@ -1,6 +1,5 @@
obj-y := timer.o
obj-y += irq.o
-obj-y += clock.o
obj-y += rstc.o
obj-y += prima2.o
obj-y += rtciobrg.o
diff --git a/arch/arm/mach-prima2/clock.c b/arch/arm/mach-prima2/clock.c
deleted file mode 100644
index aebad7e565cf..000000000000
--- a/arch/arm/mach-prima2/clock.c
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Clock tree for CSR SiRFprimaII
- *
- * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/bitops.h>
-#include <linux/err.h>
-#include <linux/errno.h>
-#include <linux/io.h>
-#include <linux/clkdev.h>
-#include <linux/clk.h>
-#include <linux/spinlock.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <asm/mach/map.h>
-#include <mach/map.h>
-
-#define SIRFSOC_CLKC_CLK_EN0 0x0000
-#define SIRFSOC_CLKC_CLK_EN1 0x0004
-#define SIRFSOC_CLKC_REF_CFG 0x0014
-#define SIRFSOC_CLKC_CPU_CFG 0x0018
-#define SIRFSOC_CLKC_MEM_CFG 0x001c
-#define SIRFSOC_CLKC_SYS_CFG 0x0020
-#define SIRFSOC_CLKC_IO_CFG 0x0024
-#define SIRFSOC_CLKC_DSP_CFG 0x0028
-#define SIRFSOC_CLKC_GFX_CFG 0x002c
-#define SIRFSOC_CLKC_MM_CFG 0x0030
-#define SIRFSOC_LKC_LCD_CFG 0x0034
-#define SIRFSOC_CLKC_MMC_CFG 0x0038
-#define SIRFSOC_CLKC_PLL1_CFG0 0x0040
-#define SIRFSOC_CLKC_PLL2_CFG0 0x0044
-#define SIRFSOC_CLKC_PLL3_CFG0 0x0048
-#define SIRFSOC_CLKC_PLL1_CFG1 0x004c
-#define SIRFSOC_CLKC_PLL2_CFG1 0x0050
-#define SIRFSOC_CLKC_PLL3_CFG1 0x0054
-#define SIRFSOC_CLKC_PLL1_CFG2 0x0058
-#define SIRFSOC_CLKC_PLL2_CFG2 0x005c
-#define SIRFSOC_CLKC_PLL3_CFG2 0x0060
-
-#define SIRFSOC_CLOCK_VA_BASE SIRFSOC_VA(0x005000)
-
-#define KHZ 1000
-#define MHZ (KHZ * KHZ)
-
-struct clk_ops {
- unsigned long (*get_rate)(struct clk *clk);
- long (*round_rate)(struct clk *clk, unsigned long rate);
- int (*set_rate)(struct clk *clk, unsigned long rate);
- int (*enable)(struct clk *clk);
- int (*disable)(struct clk *clk);
- struct clk *(*get_parent)(struct clk *clk);
- int (*set_parent)(struct clk *clk, struct clk *parent);
-};
-
-struct clk {
- struct clk *parent; /* parent clk */
- unsigned long rate; /* clock rate in Hz */
- signed char usage; /* clock enable count */
- signed char enable_bit; /* enable bit: 0 ~ 63 */
- unsigned short regofs; /* register offset */
- struct clk_ops *ops; /* clock operation */
-};
-
-static DEFINE_SPINLOCK(clocks_lock);
-
-static inline unsigned long clkc_readl(unsigned reg)
-{
- return readl(SIRFSOC_CLOCK_VA_BASE + reg);
-}
-
-static inline void clkc_writel(u32 val, unsigned reg)
-{
- writel(val, SIRFSOC_CLOCK_VA_BASE + reg);
-}
-
-/*
- * osc_rtc - real time oscillator - 32.768KHz
- * osc_sys - high speed oscillator - 26MHz
- */
-
-static struct clk clk_rtc = {
- .rate = 32768,
-};
-
-static struct clk clk_osc = {
- .rate = 26 * MHZ,
-};
-
-/*
- * std pll
- */
-static unsigned long std_pll_get_rate(struct clk *clk)
-{
- unsigned long fin = clk_get_rate(clk->parent);
- u32 regcfg2 = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 -
- SIRFSOC_CLKC_PLL1_CFG0;
-
- if (clkc_readl(regcfg2) & BIT(2)) {
- /* pll bypass mode */
- clk->rate = fin;
- } else {
- /* fout = fin * nf / nr / od */
- u32 cfg0 = clkc_readl(clk->regofs);
- u32 nf = (cfg0 & (BIT(13) - 1)) + 1;
- u32 nr = ((cfg0 >> 13) & (BIT(6) - 1)) + 1;
- u32 od = ((cfg0 >> 19) & (BIT(4) - 1)) + 1;
- WARN_ON(fin % MHZ);
- clk->rate = fin / MHZ * nf / nr / od * MHZ;
- }
-
- return clk->rate;
-}
-
-static int std_pll_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long fin, nf, nr, od, reg;
-
- /*
- * fout = fin * nf / (nr * od);
- * set od = 1, nr = fin/MHz, so fout = nf * MHz
- */
-
- nf = rate / MHZ;
- if (unlikely((rate % MHZ) || nf > BIT(13) || nf < 1))
- return -EINVAL;
-
- fin = clk_get_rate(clk->parent);
- BUG_ON(fin < MHZ);
-
- nr = fin / MHZ;
- BUG_ON((fin % MHZ) || nr > BIT(6));
-
- od = 1;
-
- reg = (nf - 1) | ((nr - 1) << 13) | ((od - 1) << 19);
- clkc_writel(reg, clk->regofs);
-
- reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG1 - SIRFSOC_CLKC_PLL1_CFG0;
- clkc_writel((nf >> 1) - 1, reg);
-
- reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - SIRFSOC_CLKC_PLL1_CFG0;
- while (!(clkc_readl(reg) & BIT(6)))
- cpu_relax();
-
- clk->rate = 0; /* set to zero will force recalculation */
- return 0;
-}
-
-static struct clk_ops std_pll_ops = {
- .get_rate = std_pll_get_rate,
- .set_rate = std_pll_set_rate,
-};
-
-static struct clk clk_pll1 = {
- .parent = &clk_osc,
- .regofs = SIRFSOC_CLKC_PLL1_CFG0,
- .ops = &std_pll_ops,
-};
-
-static struct clk clk_pll2 = {
- .parent = &clk_osc,
- .regofs = SIRFSOC_CLKC_PLL2_CFG0,
- .ops = &std_pll_ops,
-};
-
-static struct clk clk_pll3 = {
- .parent = &clk_osc,
- .regofs = SIRFSOC_CLKC_PLL3_CFG0,
- .ops = &std_pll_ops,
-};
-
-/*
- * clock domains - cpu, mem, sys/io
- */
-
-static struct clk clk_mem;
-
-static struct clk *dmn_get_parent(struct clk *clk)
-{
- struct clk *clks[] = {
- &clk_osc, &clk_rtc, &clk_pll1, &clk_pll2, &clk_pll3
- };
- u32 cfg = clkc_readl(clk->regofs);
- WARN_ON((cfg & (BIT(3) - 1)) > 4);
- return clks[cfg & (BIT(3) - 1)];
-}
-
-static int dmn_set_parent(struct clk *clk, struct clk *parent)
-{
- const struct clk *clks[] = {
- &clk_osc, &clk_rtc, &clk_pll1, &clk_pll2, &clk_pll3
- };
- u32 cfg = clkc_readl(clk->regofs);
- int i;
- for (i = 0; i < ARRAY_SIZE(clks); i++) {
- if (clks[i] == parent) {
- cfg &= ~(BIT(3) - 1);
- clkc_writel(cfg | i, clk->regofs);
- /* BIT(3) - switching status: 1 - busy, 0 - done */
- while (clkc_readl(clk->regofs) & BIT(3))
- cpu_relax();
- return 0;
- }
- }
- return -EINVAL;
-}
-
-static unsigned long dmn_get_rate(struct clk *clk)
-{
- unsigned long fin = clk_get_rate(clk->parent);
- u32 cfg = clkc_readl(clk->regofs);
- if (cfg & BIT(24)) {
- /* fcd bypass mode */
- clk->rate = fin;
- } else {
- /*
- * wait count: bit[19:16], hold count: bit[23:20]
- */
- u32 wait = (cfg >> 16) & (BIT(4) - 1);
- u32 hold = (cfg >> 20) & (BIT(4) - 1);
-
- clk->rate = fin / (wait + hold + 2);
- }
-
- return clk->rate;
-}
-
-static int dmn_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long fin;
- unsigned ratio, wait, hold, reg;
- unsigned bits = (clk == &clk_mem) ? 3 : 4;
-
- fin = clk_get_rate(clk->parent);
- ratio = fin / rate;
-
- if (unlikely(ratio < 2 || ratio > BIT(bits + 1)))
- return -EINVAL;
-
- WARN_ON(fin % rate);
-
- wait = (ratio >> 1) - 1;
- hold = ratio - wait - 2;
-
- reg = clkc_readl(clk->regofs);
- reg &= ~(((BIT(bits) - 1) << 16) | ((BIT(bits) - 1) << 20));
- reg |= (wait << 16) | (hold << 20) | BIT(25);
- clkc_writel(reg, clk->regofs);
-
- /* waiting FCD been effective */
- while (clkc_readl(clk->regofs) & BIT(25))
- cpu_relax();
-
- clk->rate = 0; /* set to zero will force recalculation */
-
- return 0;
-}
-
-/*
- * cpu clock has no FCD register in Prima2, can only change pll
- */
-static int cpu_set_rate(struct clk *clk, unsigned long rate)
-{
- int ret1, ret2;
- struct clk *cur_parent, *tmp_parent;
-
- cur_parent = dmn_get_parent(clk);
- BUG_ON(cur_parent == NULL || cur_parent->usage > 1);
-
- /* switch to tmp pll before setting parent clock's rate */
- tmp_parent = cur_parent == &clk_pll1 ? &clk_pll2 : &clk_pll1;
- ret1 = dmn_set_parent(clk, tmp_parent);
- BUG_ON(ret1);
-
- ret2 = clk_set_rate(cur_parent, rate);
-
- ret1 = dmn_set_parent(clk, cur_parent);
-
- clk->rate = 0; /* set to zero will force recalculation */
-
- return ret2 ? ret2 : ret1;
-}
-
-static struct clk_ops cpu_ops = {
- .get_parent = dmn_get_parent,
- .set_parent = dmn_set_parent,
- .set_rate = cpu_set_rate,
-};
-
-static struct clk clk_cpu = {
- .parent = &clk_pll1,
- .regofs = SIRFSOC_CLKC_CPU_CFG,
- .ops = &cpu_ops,
-};
-
-
-static struct clk_ops msi_ops = {
- .set_rate = dmn_set_rate,
- .get_rate = dmn_get_rate,
- .set_parent = dmn_set_parent,
- .get_parent = dmn_get_parent,
-};
-
-static struct clk clk_mem = {
- .parent = &clk_pll2,
- .regofs = SIRFSOC_CLKC_MEM_CFG,
- .ops = &msi_ops,
-};
-
-static struct clk clk_sys = {
- .parent = &clk_pll3,
- .regofs = SIRFSOC_CLKC_SYS_CFG,
- .ops = &msi_ops,
-};
-
-static struct clk clk_io = {
- .parent = &clk_pll3,
- .regofs = SIRFSOC_CLKC_IO_CFG,
- .ops = &msi_ops,
-};
-
-/*
- * on-chip clock sets
- */
-static struct clk_lookup onchip_clks[] = {
- {
- .dev_id = "rtc",
- .clk = &clk_rtc,
- }, {
- .dev_id = "osc",
- .clk = &clk_osc,
- }, {
- .dev_id = "pll1",
- .clk = &clk_pll1,
- }, {
- .dev_id = "pll2",
- .clk = &clk_pll2,
- }, {
- .dev_id = "pll3",
- .clk = &clk_pll3,
- }, {
- .dev_id = "cpu",
- .clk = &clk_cpu,
- }, {
- .dev_id = "mem",
- .clk = &clk_mem,
- }, {
- .dev_id = "sys",
- .clk = &clk_sys,
- }, {
- .dev_id = "io",
- .clk = &clk_io,
- },
-};
-
-int clk_enable(struct clk *clk)
-{
- unsigned long flags;
-
- if (unlikely(IS_ERR_OR_NULL(clk)))
- return -EINVAL;
-
- if (clk->parent)
- clk_enable(clk->parent);
-
- spin_lock_irqsave(&clocks_lock, flags);
- if (!clk->usage++ && clk->ops && clk->ops->enable)
- clk->ops->enable(clk);
- spin_unlock_irqrestore(&clocks_lock, flags);
- return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
- unsigned long flags;
-
- if (unlikely(IS_ERR_OR_NULL(clk)))
- return;
-
- WARN_ON(!clk->usage);
-
- spin_lock_irqsave(&clocks_lock, flags);
- if (--clk->usage == 0 && clk->ops && clk->ops->disable)
- clk->ops->disable(clk);
- spin_unlock_irqrestore(&clocks_lock, flags);
-
- if (clk->parent)
- clk_disable(clk->parent);
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
- if (unlikely(IS_ERR_OR_NULL(clk)))
- return 0;
-
- if (clk->rate)
- return clk->rate;
-
- if (clk->ops && clk->ops->get_rate)
- return clk->ops->get_rate(clk);
-
- return clk_get_rate(clk->parent);
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
- if (unlikely(IS_ERR_OR_NULL(clk)))
- return 0;
-
- if (clk->ops && clk->ops->round_rate)
- return clk->ops->round_rate(clk, rate);
-
- return 0;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- if (unlikely(IS_ERR_OR_NULL(clk)))
- return -EINVAL;
-
- if (!clk->ops || !clk->ops->set_rate)
- return -EINVAL;
-
- return clk->ops->set_rate(clk, rate);
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
- int ret;
- unsigned long flags;
-
- if (unlikely(IS_ERR_OR_NULL(clk)))
- return -EINVAL;
-
- if (!clk->ops || !clk->ops->set_parent)
- return -EINVAL;
-
- spin_lock_irqsave(&clocks_lock, flags);
- ret = clk->ops->set_parent(clk, parent);
- if (!ret) {
- parent->usage += clk->usage;
- clk->parent->usage -= clk->usage;
- BUG_ON(clk->parent->usage < 0);
- clk->parent = parent;
- }
- spin_unlock_irqrestore(&clocks_lock, flags);
- return ret;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-struct clk *clk_get_parent(struct clk *clk)
-{
- unsigned long flags;
-
- if (unlikely(IS_ERR_OR_NULL(clk)))
- return NULL;
-
- if (!clk->ops || !clk->ops->get_parent)
- return clk->parent;
-
- spin_lock_irqsave(&clocks_lock, flags);
- clk->parent = clk->ops->get_parent(clk);
- spin_unlock_irqrestore(&clocks_lock, flags);
- return clk->parent;
-}
-EXPORT_SYMBOL(clk_get_parent);
-
-static void __init sirfsoc_clk_init(void)
-{
- clkdev_add_table(onchip_clks, ARRAY_SIZE(onchip_clks));
-}
-
-static struct of_device_id clkc_ids[] = {
- { .compatible = "sirf,prima2-clkc" },
- {},
-};
-
-void __init sirfsoc_of_clk_init(void)
-{
- struct device_node *np;
- struct resource res;
- struct map_desc sirfsoc_clkc_iodesc = {
- .virtual = SIRFSOC_CLOCK_VA_BASE,
- .type = MT_DEVICE,
- };
-
- np = of_find_matching_node(NULL, clkc_ids);
- if (!np)
- panic("unable to find compatible clkc node in dtb\n");
-
- if (of_address_to_resource(np, 0, &res))
- panic("unable to find clkc range in dtb");
- of_node_put(np);
-
- sirfsoc_clkc_iodesc.pfn = __phys_to_pfn(res.start);
- sirfsoc_clkc_iodesc.length = 1 + res.end - res.start;
-
- iotable_init(&sirfsoc_clkc_iodesc, 1);
-
- sirfsoc_clk_init();
-}
diff --git a/arch/arm/mach-prima2/prima2.c b/arch/arm/mach-prima2/prima2.c
index 8f0429d4b79f..e9a17aebe0d6 100644
--- a/arch/arm/mach-prima2/prima2.c
+++ b/arch/arm/mach-prima2/prima2.c
@@ -38,7 +38,6 @@ static const char *prima2cb_dt_match[] __initdata = {
MACHINE_START(PRIMA2_EVB, "prima2cb")
/* Maintainer: Barry Song <baohua.song@csr.com> */
.atag_offset = 0x100,
- .init_early = sirfsoc_of_clk_init,
.map_io = sirfsoc_map_lluart,
.init_irq = sirfsoc_of_irq_init,
.timer = &sirfsoc_timer,
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c
index f224107de7bc..d95bf252f694 100644
--- a/arch/arm/mach-prima2/timer.c
+++ b/arch/arm/mach-prima2/timer.c
@@ -21,6 +21,8 @@
#include <asm/sched_clock.h>
#include <asm/mach/time.h>
+#include "common.h"
+
#define SIRFSOC_TIMER_COUNTER_LO 0x0000
#define SIRFSOC_TIMER_COUNTER_HI 0x0004
#define SIRFSOC_TIMER_MATCH_0 0x0008
@@ -188,9 +190,13 @@ static void __init sirfsoc_clockevent_init(void)
static void __init sirfsoc_timer_init(void)
{
unsigned long rate;
+ struct clk *clk;
+
+ /* initialize clocking early, we want to set the OS timer */
+ sirfsoc_of_clk_init();
/* timer's input clock is io clock */
- struct clk *clk = clk_get_sys("io", NULL);
+ clk = clk_get_sys("io", NULL);
BUG_ON(IS_ERR(clk));
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 45868bb43cbd..ff007d15e0ec 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -30,7 +30,6 @@
#include <linux/ata_platform.h>
#include <linux/amba/mmci.h>
#include <linux/gfp.h>
-#include <linux/clkdev.h>
#include <linux/mtd/physmap.h>
#include <mach/hardware.h>
@@ -226,115 +225,10 @@ struct mmci_platform_data realview_mmc1_plat_data = {
.cd_invert = true,
};
-/*
- * Clock handling
- */
-static const struct icst_params realview_oscvco_params = {
- .ref = 24000000,
- .vco_max = ICST307_VCO_MAX,
- .vco_min = ICST307_VCO_MIN,
- .vd_min = 4 + 8,
- .vd_max = 511 + 8,
- .rd_min = 1 + 2,
- .rd_max = 127 + 2,
- .s2div = icst307_s2div,
- .idx2s = icst307_idx2s,
-};
-
-static void realview_oscvco_set(struct clk *clk, struct icst_vco vco)
-{
- void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
- u32 val;
-
- val = readl(clk->vcoreg) & ~0x7ffff;
- val |= vco.v | (vco.r << 9) | (vco.s << 16);
-
- writel(0xa05f, sys_lock);
- writel(val, clk->vcoreg);
- writel(0, sys_lock);
-}
-
-static const struct clk_ops oscvco_clk_ops = {
- .round = icst_clk_round,
- .set = icst_clk_set,
- .setvco = realview_oscvco_set,
-};
-
-static struct clk oscvco_clk = {
- .ops = &oscvco_clk_ops,
- .params = &realview_oscvco_params,
-};
-
-/*
- * These are fixed clocks.
- */
-static struct clk ref24_clk = {
- .rate = 24000000,
-};
-
-static struct clk sp804_clk = {
- .rate = 1000000,
-};
-
-static struct clk dummy_apb_pclk;
-
-static struct clk_lookup lookups[] = {
- { /* Bus clock */
- .con_id = "apb_pclk",
- .clk = &dummy_apb_pclk,
- }, { /* UART0 */
- .dev_id = "dev:uart0",
- .clk = &ref24_clk,
- }, { /* UART1 */
- .dev_id = "dev:uart1",
- .clk = &ref24_clk,
- }, { /* UART2 */
- .dev_id = "dev:uart2",
- .clk = &ref24_clk,
- }, { /* UART3 */
- .dev_id = "fpga:uart3",
- .clk = &ref24_clk,
- }, { /* UART3 is on the dev chip in PB1176 */
- .dev_id = "dev:uart3",
- .clk = &ref24_clk,
- }, { /* UART4 only exists in PB1176 */
- .dev_id = "fpga:uart4",
- .clk = &ref24_clk,
- }, { /* KMI0 */
- .dev_id = "fpga:kmi0",
- .clk = &ref24_clk,
- }, { /* KMI1 */
- .dev_id = "fpga:kmi1",
- .clk = &ref24_clk,
- }, { /* MMC0 */
- .dev_id = "fpga:mmc0",
- .clk = &ref24_clk,
- }, { /* CLCD is in the PB1176 and EB DevChip */
- .dev_id = "dev:clcd",
- .clk = &oscvco_clk,
- }, { /* PB:CLCD */
- .dev_id = "issp:clcd",
- .clk = &oscvco_clk,
- }, { /* SSP */
- .dev_id = "dev:ssp0",
- .clk = &ref24_clk,
- }, { /* SP804 timers */
- .dev_id = "sp804",
- .clk = &sp804_clk,
- },
-};
-
void __init realview_init_early(void)
{
void __iomem *sys = __io_address(REALVIEW_SYS_BASE);
- if (machine_is_realview_pb1176())
- oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC0_OFFSET;
- else
- oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC4_OFFSET;
-
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
versatile_sched_clock_init(sys + REALVIEW_SYS_24MHz_OFFSET, 24000000);
}
diff --git a/arch/arm/mach-realview/include/mach/clkdev.h b/arch/arm/mach-realview/include/mach/clkdev.h
deleted file mode 100644
index e58d0771b64e..000000000000
--- a/arch/arm/mach-realview/include/mach/clkdev.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __ASM_MACH_CLKDEV_H
-#define __ASM_MACH_CLKDEV_H
-
-#include <plat/clock.h>
-
-struct clk {
- unsigned long rate;
- const struct clk_ops *ops;
- const struct icst_params *params;
- void __iomem *vcoreg;
-};
-
-#define __clk_get(clk) ({ 1; })
-#define __clk_put(clk) do { } while (0)
-
-#endif
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index baf382c5e776..a33e33b76733 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -27,6 +27,7 @@
#include <linux/amba/mmci.h>
#include <linux/amba/pl022.h>
#include <linux/io.h>
+#include <linux/platform_data/clk-realview.h>
#include <mach/hardware.h>
#include <asm/irq.h>
@@ -414,6 +415,7 @@ static void __init realview_eb_timer_init(void)
else
timer_irq = IRQ_EB_TIMER0_1;
+ realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
realview_timer_init(timer_irq);
realview_eb_twd_init();
}
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index b1d7cafa1a6d..f0298cbc203e 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -29,6 +29,7 @@
#include <linux/mtd/physmap.h>
#include <linux/mtd/partitions.h>
#include <linux/io.h>
+#include <linux/platform_data/clk-realview.h>
#include <mach/hardware.h>
#include <asm/irq.h>
@@ -326,6 +327,7 @@ static void __init realview_pb1176_timer_init(void)
timer2_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE);
timer3_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE) + 0x20;
+ realview_clk_init(__io_address(REALVIEW_SYS_BASE), true);
realview_timer_init(IRQ_DC1176_TIMER0);
}
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index a98c536e3327..1f019f76f7b5 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -27,6 +27,7 @@
#include <linux/amba/mmci.h>
#include <linux/amba/pl022.h>
#include <linux/io.h>
+#include <linux/platform_data/clk-realview.h>
#include <mach/hardware.h>
#include <asm/irq.h>
@@ -312,6 +313,7 @@ static void __init realview_pb11mp_timer_init(void)
timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE);
timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20;
+ realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
realview_timer_init(IRQ_TC11MP_TIMER0_1);
realview_pb11mp_twd_init();
}
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 59650174e6ed..5032775dbfee 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -27,6 +27,7 @@
#include <linux/amba/mmci.h>
#include <linux/amba/pl022.h>
#include <linux/io.h>
+#include <linux/platform_data/clk-realview.h>
#include <asm/irq.h>
#include <asm/leds.h>
@@ -261,6 +262,7 @@ static void __init realview_pba8_timer_init(void)
timer2_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE);
timer3_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE) + 0x20;
+ realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
realview_timer_init(IRQ_PBA8_TIMER0_1);
}
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index 3f2f605624e9..de64ba0ddb95 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -26,6 +26,7 @@
#include <linux/amba/mmci.h>
#include <linux/amba/pl022.h>
#include <linux/io.h>
+#include <linux/platform_data/clk-realview.h>
#include <asm/irq.h>
#include <asm/leds.h>
@@ -320,6 +321,7 @@ static void __init realview_pbx_timer_init(void)
timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE);
timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20;
+ realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
realview_timer_init(IRQ_PBX_TIMER0_1);
realview_pbx_twd_init();
}
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 53d3d46dec12..a258996d954b 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -11,6 +11,7 @@ config UX500_SOC_COMMON
select CACHE_L2X0
select PINCTRL
select PINCTRL_NOMADIK
+ select COMMON_CLK
config UX500_SOC_DB8500
bool
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index 026086ff9e6c..5691ef679d01 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -2,7 +2,7 @@
# Makefile for the linux kernel, U8500 machine.
#
-obj-y := clock.o cpu.o devices.o devices-common.o \
+obj-y := cpu.o devices.o devices-common.o \
id.o usb.o timer.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
deleted file mode 100644
index 8d73b066a18d..000000000000
--- a/arch/arm/mach-ux500/clock.c
+++ /dev/null
@@ -1,715 +0,0 @@
-/*
- * Copyright (C) 2009 ST-Ericsson
- * Copyright (C) 2009 STMicroelectronics
- *
- * 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.
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/clkdev.h>
-#include <linux/cpufreq.h>
-
-#include <plat/mtu.h>
-#include <mach/hardware.h>
-#include "clock.h"
-
-#ifdef CONFIG_DEBUG_FS
-#include <linux/debugfs.h>
-#include <linux/uaccess.h> /* for copy_from_user */
-static LIST_HEAD(clk_list);
-#endif
-
-#define PRCC_PCKEN 0x00
-#define PRCC_PCKDIS 0x04
-#define PRCC_KCKEN 0x08
-#define PRCC_KCKDIS 0x0C
-
-#define PRCM_YYCLKEN0_MGT_SET 0x510
-#define PRCM_YYCLKEN1_MGT_SET 0x514
-#define PRCM_YYCLKEN0_MGT_CLR 0x518
-#define PRCM_YYCLKEN1_MGT_CLR 0x51C
-#define PRCM_YYCLKEN0_MGT_VAL 0x520
-#define PRCM_YYCLKEN1_MGT_VAL 0x524
-
-#define PRCM_SVAMMDSPCLK_MGT 0x008
-#define PRCM_SIAMMDSPCLK_MGT 0x00C
-#define PRCM_SGACLK_MGT 0x014
-#define PRCM_UARTCLK_MGT 0x018
-#define PRCM_MSP02CLK_MGT 0x01C
-#define PRCM_MSP1CLK_MGT 0x288
-#define PRCM_I2CCLK_MGT 0x020
-#define PRCM_SDMMCCLK_MGT 0x024
-#define PRCM_SLIMCLK_MGT 0x028
-#define PRCM_PER1CLK_MGT 0x02C
-#define PRCM_PER2CLK_MGT 0x030
-#define PRCM_PER3CLK_MGT 0x034
-#define PRCM_PER5CLK_MGT 0x038
-#define PRCM_PER6CLK_MGT 0x03C
-#define PRCM_PER7CLK_MGT 0x040
-#define PRCM_LCDCLK_MGT 0x044
-#define PRCM_BMLCLK_MGT 0x04C
-#define PRCM_HSITXCLK_MGT 0x050
-#define PRCM_HSIRXCLK_MGT 0x054
-#define PRCM_HDMICLK_MGT 0x058
-#define PRCM_APEATCLK_MGT 0x05C
-#define PRCM_APETRACECLK_MGT 0x060
-#define PRCM_MCDECLK_MGT 0x064
-#define PRCM_IPI2CCLK_MGT 0x068
-#define PRCM_DSIALTCLK_MGT 0x06C
-#define PRCM_DMACLK_MGT 0x074
-#define PRCM_B2R2CLK_MGT 0x078
-#define PRCM_TVCLK_MGT 0x07C
-#define PRCM_TCR 0x1C8
-#define PRCM_TCR_STOPPED (1 << 16)
-#define PRCM_TCR_DOZE_MODE (1 << 17)
-#define PRCM_UNIPROCLK_MGT 0x278
-#define PRCM_SSPCLK_MGT 0x280
-#define PRCM_RNGCLK_MGT 0x284
-#define PRCM_UICCCLK_MGT 0x27C
-
-#define PRCM_MGT_ENABLE (1 << 8)
-
-static DEFINE_SPINLOCK(clocks_lock);
-
-static void __clk_enable(struct clk *clk)
-{
- if (clk->enabled++ == 0) {
- if (clk->parent_cluster)
- __clk_enable(clk->parent_cluster);
-
- if (clk->parent_periph)
- __clk_enable(clk->parent_periph);
-
- if (clk->ops && clk->ops->enable)
- clk->ops->enable(clk);
- }
-}
-
-int clk_enable(struct clk *clk)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&clocks_lock, flags);
- __clk_enable(clk);
- spin_unlock_irqrestore(&clocks_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-static void __clk_disable(struct clk *clk)
-{
- if (--clk->enabled == 0) {
- if (clk->ops && clk->ops->disable)
- clk->ops->disable(clk);
-
- if (clk->parent_periph)
- __clk_disable(clk->parent_periph);
-
- if (clk->parent_cluster)
- __clk_disable(clk->parent_cluster);
- }
-}
-
-void clk_disable(struct clk *clk)
-{
- unsigned long flags;
-
- WARN_ON(!clk->enabled);
-
- spin_lock_irqsave(&clocks_lock, flags);
- __clk_disable(clk);
- spin_unlock_irqrestore(&clocks_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-/*
- * The MTU has a separate, rather complex muxing setup
- * with alternative parents (peripheral cluster or
- * ULP or fixed 32768 Hz) depending on settings
- */
-static unsigned long clk_mtu_get_rate(struct clk *clk)
-{
- void __iomem *addr;
- u32 tcr;
- int mtu = (int) clk->data;
- /*
- * One of these is selected eventually
- * TODO: Replace the constant with a reference
- * to the ULP source once this is modeled.
- */
- unsigned long clk32k = 32768;
- unsigned long mturate;
- unsigned long retclk;
-
- if (cpu_is_u8500_family())
- addr = __io_address(U8500_PRCMU_BASE);
- else
- ux500_unknown_soc();
-
- /*
- * On a startup, always conifgure the TCR to the doze mode;
- * bootloaders do it for us. Do this in the kernel too.
- */
- writel(PRCM_TCR_DOZE_MODE, addr + PRCM_TCR);
-
- tcr = readl(addr + PRCM_TCR);
-
- /* Get the rate from the parent as a default */
- if (clk->parent_periph)
- mturate = clk_get_rate(clk->parent_periph);
- else if (clk->parent_cluster)
- mturate = clk_get_rate(clk->parent_cluster);
- else
- /* We need to be connected SOMEWHERE */
- BUG();
-
- /* Return the clock selected for this MTU */
- if (tcr & (1 << mtu))
- retclk = clk32k;
- else
- retclk = mturate;
-
- pr_info("MTU%d clock rate: %lu Hz\n", mtu, retclk);
- return retclk;
-}
-
-unsigned long clk_get_rate(struct clk *clk)
-{
- unsigned long rate;
-
- /*
- * If there is a custom getrate callback for this clock,
- * it will take precedence.
- */
- if (clk->get_rate)
- return clk->get_rate(clk);
-
- if (clk->ops && clk->ops->get_rate)
- return clk->ops->get_rate(clk);
-
- rate = clk->rate;
- if (!rate) {
- if (clk->parent_periph)
- rate = clk_get_rate(clk->parent_periph);
- else if (clk->parent_cluster)
- rate = clk_get_rate(clk->parent_cluster);
- }
-
- return rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
- /*TODO*/
- return rate;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- clk->rate = rate;
- return 0;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
- /*TODO*/
- return -ENOSYS;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-static void clk_prcmu_enable(struct clk *clk)
-{
- void __iomem *cg_set_reg = __io_address(U8500_PRCMU_BASE)
- + PRCM_YYCLKEN0_MGT_SET + clk->prcmu_cg_off;
-
- writel(1 << clk->prcmu_cg_bit, cg_set_reg);
-}
-
-static void clk_prcmu_disable(struct clk *clk)
-{
- void __iomem *cg_clr_reg = __io_address(U8500_PRCMU_BASE)
- + PRCM_YYCLKEN0_MGT_CLR + clk->prcmu_cg_off;
-
- writel(1 << clk->prcmu_cg_bit, cg_clr_reg);
-}
-
-static struct clkops clk_prcmu_ops = {
- .enable = clk_prcmu_enable,
- .disable = clk_prcmu_disable,
-};
-
-static unsigned int clkrst_base[] = {
- [1] = U8500_CLKRST1_BASE,
- [2] = U8500_CLKRST2_BASE,
- [3] = U8500_CLKRST3_BASE,
- [5] = U8500_CLKRST5_BASE,
- [6] = U8500_CLKRST6_BASE,
-};
-
-static void clk_prcc_enable(struct clk *clk)
-{
- void __iomem *addr = __io_address(clkrst_base[clk->cluster]);
-
- if (clk->prcc_kernel != -1)
- writel(1 << clk->prcc_kernel, addr + PRCC_KCKEN);
-
- if (clk->prcc_bus != -1)
- writel(1 << clk->prcc_bus, addr + PRCC_PCKEN);
-}
-
-static void clk_prcc_disable(struct clk *clk)
-{
- void __iomem *addr = __io_address(clkrst_base[clk->cluster]);
-
- if (clk->prcc_bus != -1)
- writel(1 << clk->prcc_bus, addr + PRCC_PCKDIS);
-
- if (clk->prcc_kernel != -1)
- writel(1 << clk->prcc_kernel, addr + PRCC_KCKDIS);
-}
-
-static struct clkops clk_prcc_ops = {
- .enable = clk_prcc_enable,
- .disable = clk_prcc_disable,
-};
-
-static struct clk clk_32khz = {
- .name = "clk_32khz",
- .rate = 32000,
-};
-
-/*
- * PRCMU level clock gating
- */
-
-/* Bank 0 */
-static DEFINE_PRCMU_CLK(svaclk, 0x0, 2, SVAMMDSPCLK);
-static DEFINE_PRCMU_CLK(siaclk, 0x0, 3, SIAMMDSPCLK);
-static DEFINE_PRCMU_CLK(sgaclk, 0x0, 4, SGACLK);
-static DEFINE_PRCMU_CLK_RATE(uartclk, 0x0, 5, UARTCLK, 38400000);
-static DEFINE_PRCMU_CLK(msp02clk, 0x0, 6, MSP02CLK);
-static DEFINE_PRCMU_CLK(msp1clk, 0x0, 7, MSP1CLK); /* v1 */
-static DEFINE_PRCMU_CLK_RATE(i2cclk, 0x0, 8, I2CCLK, 48000000);
-static DEFINE_PRCMU_CLK_RATE(sdmmcclk, 0x0, 9, SDMMCCLK, 100000000);
-static DEFINE_PRCMU_CLK(slimclk, 0x0, 10, SLIMCLK);
-static DEFINE_PRCMU_CLK(per1clk, 0x0, 11, PER1CLK);
-static DEFINE_PRCMU_CLK(per2clk, 0x0, 12, PER2CLK);
-static DEFINE_PRCMU_CLK(per3clk, 0x0, 13, PER3CLK);
-static DEFINE_PRCMU_CLK(per5clk, 0x0, 14, PER5CLK);
-static DEFINE_PRCMU_CLK_RATE(per6clk, 0x0, 15, PER6CLK, 133330000);
-static DEFINE_PRCMU_CLK(lcdclk, 0x0, 17, LCDCLK);
-static DEFINE_PRCMU_CLK(bmlclk, 0x0, 18, BMLCLK);
-static DEFINE_PRCMU_CLK(hsitxclk, 0x0, 19, HSITXCLK);
-static DEFINE_PRCMU_CLK(hsirxclk, 0x0, 20, HSIRXCLK);
-static DEFINE_PRCMU_CLK(hdmiclk, 0x0, 21, HDMICLK);
-static DEFINE_PRCMU_CLK(apeatclk, 0x0, 22, APEATCLK);
-static DEFINE_PRCMU_CLK(apetraceclk, 0x0, 23, APETRACECLK);
-static DEFINE_PRCMU_CLK(mcdeclk, 0x0, 24, MCDECLK);
-static DEFINE_PRCMU_CLK(ipi2clk, 0x0, 25, IPI2CCLK);
-static DEFINE_PRCMU_CLK(dsialtclk, 0x0, 26, DSIALTCLK); /* v1 */
-static DEFINE_PRCMU_CLK(dmaclk, 0x0, 27, DMACLK);
-static DEFINE_PRCMU_CLK(b2r2clk, 0x0, 28, B2R2CLK);
-static DEFINE_PRCMU_CLK(tvclk, 0x0, 29, TVCLK);
-static DEFINE_PRCMU_CLK(uniproclk, 0x0, 30, UNIPROCLK); /* v1 */
-static DEFINE_PRCMU_CLK_RATE(sspclk, 0x0, 31, SSPCLK, 48000000); /* v1 */
-
-/* Bank 1 */
-static DEFINE_PRCMU_CLK(rngclk, 0x4, 0, RNGCLK); /* v1 */
-static DEFINE_PRCMU_CLK(uiccclk, 0x4, 1, UICCCLK); /* v1 */
-
-/*
- * PRCC level clock gating
- * Format: per#, clk, PCKEN bit, KCKEN bit, parent
- */
-
-/* Peripheral Cluster #1 */
-static DEFINE_PRCC_CLK(1, msp3, 11, 10, &clk_msp1clk);
-static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk);
-static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL);
-static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk);
-static DEFINE_PRCC_CLK(1, spi3, 7, -1, NULL);
-static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk);
-static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk);
-static DEFINE_PRCC_CLK(1, msp1, 4, 4, &clk_msp1clk);
-static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk);
-static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk);
-static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk);
-static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk);
-
-/* Peripheral Cluster #2 */
-static DEFINE_PRCC_CLK(2, gpio1, 11, -1, NULL);
-static DEFINE_PRCC_CLK(2, ssitx, 10, 7, NULL);
-static DEFINE_PRCC_CLK(2, ssirx, 9, 6, NULL);
-static DEFINE_PRCC_CLK(2, spi0, 8, -1, NULL);
-static DEFINE_PRCC_CLK(2, sdi3, 7, 5, &clk_sdmmcclk);
-static DEFINE_PRCC_CLK(2, sdi1, 6, 4, &clk_sdmmcclk);
-static DEFINE_PRCC_CLK(2, msp2, 5, 3, &clk_msp02clk);
-static DEFINE_PRCC_CLK(2, sdi4, 4, 2, &clk_sdmmcclk);
-static DEFINE_PRCC_CLK(2, pwl, 3, 1, NULL);
-static DEFINE_PRCC_CLK(2, spi1, 2, -1, NULL);
-static DEFINE_PRCC_CLK(2, spi2, 1, -1, NULL);
-static DEFINE_PRCC_CLK(2, i2c3, 0, 0, &clk_i2cclk);
-
-/* Peripheral Cluster #3 */
-static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL);
-static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk);
-static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk);
-static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz);
-static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk);
-static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk);
-static DEFINE_PRCC_CLK(3, ssp1, 2, 2, &clk_sspclk);
-static DEFINE_PRCC_CLK(3, ssp0, 1, 1, &clk_sspclk);
-static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL);
-
-/* Peripheral Cluster #4 is in the always on domain */
-
-/* Peripheral Cluster #5 */
-static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL);
-static DEFINE_PRCC_CLK(5, usb, 0, 0, NULL);
-
-/* Peripheral Cluster #6 */
-
-/* MTU ID in data */
-static DEFINE_PRCC_CLK_CUSTOM(6, mtu1, 9, -1, NULL, clk_mtu_get_rate, 1);
-static DEFINE_PRCC_CLK_CUSTOM(6, mtu0, 8, -1, NULL, clk_mtu_get_rate, 0);
-static DEFINE_PRCC_CLK(6, cfgreg, 7, 7, NULL);
-static DEFINE_PRCC_CLK(6, hash1, 6, -1, NULL);
-static DEFINE_PRCC_CLK(6, unipro, 5, 1, &clk_uniproclk);
-static DEFINE_PRCC_CLK(6, pka, 4, -1, NULL);
-static DEFINE_PRCC_CLK(6, hash0, 3, -1, NULL);
-static DEFINE_PRCC_CLK(6, cryp0, 2, -1, NULL);
-static DEFINE_PRCC_CLK(6, cryp1, 1, -1, NULL);
-static DEFINE_PRCC_CLK(6, rng, 0, 0, &clk_rngclk);
-
-static struct clk clk_dummy_apb_pclk = {
- .name = "apb_pclk",
-};
-
-static struct clk_lookup u8500_clks[] = {
- CLK(dummy_apb_pclk, NULL, "apb_pclk"),
-
- /* Peripheral Cluster #1 */
- CLK(gpio0, "gpio.0", NULL),
- CLK(gpio0, "gpio.1", NULL),
- CLK(slimbus0, "slimbus0", NULL),
- CLK(i2c2, "nmk-i2c.2", NULL),
- CLK(sdi0, "sdi0", NULL),
- CLK(msp0, "ux500-msp-i2s.0", NULL),
- CLK(i2c1, "nmk-i2c.1", NULL),
- CLK(uart1, "uart1", NULL),
- CLK(uart0, "uart0", NULL),
-
- /* Peripheral Cluster #3 */
- CLK(gpio2, "gpio.2", NULL),
- CLK(gpio2, "gpio.3", NULL),
- CLK(gpio2, "gpio.4", NULL),
- CLK(gpio2, "gpio.5", NULL),
- CLK(sdi5, "sdi5", NULL),
- CLK(uart2, "uart2", NULL),
- CLK(ske, "ske", NULL),
- CLK(ske, "nmk-ske-keypad", NULL),
- CLK(sdi2, "sdi2", NULL),
- CLK(i2c0, "nmk-i2c.0", NULL),
- CLK(fsmc, "fsmc", NULL),
-
- /* Peripheral Cluster #5 */
- CLK(gpio3, "gpio.8", NULL),
-
- /* Peripheral Cluster #6 */
- CLK(hash1, "hash1", NULL),
- CLK(pka, "pka", NULL),
- CLK(hash0, "hash0", NULL),
- CLK(cryp0, "cryp0", NULL),
- CLK(cryp1, "cryp1", NULL),
-
- /* PRCMU level clock gating */
-
- /* Bank 0 */
- CLK(svaclk, "sva", NULL),
- CLK(siaclk, "sia", NULL),
- CLK(sgaclk, "sga", NULL),
- CLK(slimclk, "slim", NULL),
- CLK(lcdclk, "lcd", NULL),
- CLK(bmlclk, "bml", NULL),
- CLK(hsitxclk, "stm-hsi.0", NULL),
- CLK(hsirxclk, "stm-hsi.1", NULL),
- CLK(hdmiclk, "hdmi", NULL),
- CLK(apeatclk, "apeat", NULL),
- CLK(apetraceclk, "apetrace", NULL),
- CLK(mcdeclk, "mcde", NULL),
- CLK(ipi2clk, "ipi2", NULL),
- CLK(dmaclk, "dma40.0", NULL),
- CLK(b2r2clk, "b2r2", NULL),
- CLK(tvclk, "tv", NULL),
-
- /* Peripheral Cluster #1 */
- CLK(i2c4, "nmk-i2c.4", NULL),
- CLK(spi3, "spi3", NULL),
- CLK(msp1, "ux500-msp-i2s.1", NULL),
- CLK(msp3, "ux500-msp-i2s.3", NULL),
-
- /* Peripheral Cluster #2 */
- CLK(gpio1, "gpio.6", NULL),
- CLK(gpio1, "gpio.7", NULL),
- CLK(ssitx, "ssitx", NULL),
- CLK(ssirx, "ssirx", NULL),
- CLK(spi0, "spi0", NULL),
- CLK(sdi3, "sdi3", NULL),
- CLK(sdi1, "sdi1", NULL),
- CLK(msp2, "ux500-msp-i2s.2", NULL),
- CLK(sdi4, "sdi4", NULL),
- CLK(pwl, "pwl", NULL),
- CLK(spi1, "spi1", NULL),
- CLK(spi2, "spi2", NULL),
- CLK(i2c3, "nmk-i2c.3", NULL),
-
- /* Peripheral Cluster #3 */
- CLK(ssp1, "ssp1", NULL),
- CLK(ssp0, "ssp0", NULL),
-
- /* Peripheral Cluster #5 */
- CLK(usb, "musb-ux500.0", "usb"),
-
- /* Peripheral Cluster #6 */
- CLK(mtu1, "mtu1", NULL),
- CLK(mtu0, "mtu0", NULL),
- CLK(cfgreg, "cfgreg", NULL),
- CLK(hash1, "hash1", NULL),
- CLK(unipro, "unipro", NULL),
- CLK(rng, "rng", NULL),
-
- /* PRCMU level clock gating */
-
- /* Bank 0 */
- CLK(uniproclk, "uniproclk", NULL),
- CLK(dsialtclk, "dsialt", NULL),
-
- /* Bank 1 */
- CLK(rngclk, "rng", NULL),
- CLK(uiccclk, "uicc", NULL),
-};
-
-#ifdef CONFIG_DEBUG_FS
-/*
- * debugfs support to trace clock tree hierarchy and attributes with
- * powerdebug
- */
-static struct dentry *clk_debugfs_root;
-
-void __init clk_debugfs_add_table(struct clk_lookup *cl, size_t num)
-{
- while (num--) {
- /* Check that the clock has not been already registered */
- if (!(cl->clk->list.prev != cl->clk->list.next))
- list_add_tail(&cl->clk->list, &clk_list);
-
- cl++;
- }
-}
-
-static ssize_t usecount_dbg_read(struct file *file, char __user *buf,
- size_t size, loff_t *off)
-{
- struct clk *clk = file->f_dentry->d_inode->i_private;
- char cusecount[128];
- unsigned int len;
-
- len = sprintf(cusecount, "%u\n", clk->enabled);
- return simple_read_from_buffer(buf, size, off, cusecount, len);
-}
-
-static ssize_t rate_dbg_read(struct file *file, char __user *buf,
- size_t size, loff_t *off)
-{
- struct clk *clk = file->f_dentry->d_inode->i_private;
- char crate[128];
- unsigned int rate;
- unsigned int len;
-
- rate = clk_get_rate(clk);
- len = sprintf(crate, "%u\n", rate);
- return simple_read_from_buffer(buf, size, off, crate, len);
-}
-
-static const struct file_operations usecount_fops = {
- .read = usecount_dbg_read,
-};
-
-static const struct file_operations set_rate_fops = {
- .read = rate_dbg_read,
-};
-
-static struct dentry *clk_debugfs_register_dir(struct clk *c,
- struct dentry *p_dentry)
-{
- struct dentry *d, *clk_d;
- const char *p = c->name;
-
- if (!p)
- p = "BUG";
-
- clk_d = debugfs_create_dir(p, p_dentry);
- if (!clk_d)
- return NULL;
-
- d = debugfs_create_file("usecount", S_IRUGO,
- clk_d, c, &usecount_fops);
- if (!d)
- goto err_out;
- d = debugfs_create_file("rate", S_IRUGO,
- clk_d, c, &set_rate_fops);
- if (!d)
- goto err_out;
- /*
- * TODO : not currently available in ux500
- * d = debugfs_create_x32("flags", S_IRUGO, clk_d, (u32 *)&c->flags);
- * if (!d)
- * goto err_out;
- */
-
- return clk_d;
-
-err_out:
- debugfs_remove_recursive(clk_d);
- return NULL;
-}
-
-static int clk_debugfs_register_one(struct clk *c)
-{
- struct clk *pa = c->parent_periph;
- struct clk *bpa = c->parent_cluster;
-
- if (!(bpa && !pa)) {
- c->dent = clk_debugfs_register_dir(c,
- pa ? pa->dent : clk_debugfs_root);
- if (!c->dent)
- return -ENOMEM;
- }
-
- if (bpa) {
- c->dent_bus = clk_debugfs_register_dir(c,
- bpa->dent_bus ? bpa->dent_bus : bpa->dent);
- if ((!c->dent_bus) && (c->dent)) {
- debugfs_remove_recursive(c->dent);
- c->dent = NULL;
- return -ENOMEM;
- }
- }
- return 0;
-}
-
-static int clk_debugfs_register(struct clk *c)
-{
- int err;
- struct clk *pa = c->parent_periph;
- struct clk *bpa = c->parent_cluster;
-
- if (pa && (!pa->dent && !pa->dent_bus)) {
- err = clk_debugfs_register(pa);
- if (err)
- return err;
- }
-
- if (bpa && (!bpa->dent && !bpa->dent_bus)) {
- err = clk_debugfs_register(bpa);
- if (err)
- return err;
- }
-
- if ((!c->dent) && (!c->dent_bus)) {
- err = clk_debugfs_register_one(c);
- if (err)
- return err;
- }
- return 0;
-}
-
-int __init clk_debugfs_init(void)
-{
- struct clk *c;
- struct dentry *d;
- int err;
-
- d = debugfs_create_dir("clock", NULL);
- if (!d)
- return -ENOMEM;
- clk_debugfs_root = d;
-
- list_for_each_entry(c, &clk_list, list) {
- err = clk_debugfs_register(c);
- if (err)
- goto err_out;
- }
- return 0;
-err_out:
- debugfs_remove_recursive(clk_debugfs_root);
- return err;
-}
-
-#endif /* defined(CONFIG_DEBUG_FS) */
-
-unsigned long clk_smp_twd_rate = 500000000;
-
-unsigned long clk_smp_twd_get_rate(struct clk *clk)
-{
- return clk_smp_twd_rate;
-}
-
-static struct clk clk_smp_twd = {
- .get_rate = clk_smp_twd_get_rate,
- .name = "smp_twd",
-};
-
-static struct clk_lookup clk_smp_twd_lookup = {
- .dev_id = "smp_twd",
- .clk = &clk_smp_twd,
-};
-
-#ifdef CONFIG_CPU_FREQ
-
-static int clk_twd_cpufreq_transition(struct notifier_block *nb,
- unsigned long state, void *data)
-{
- struct cpufreq_freqs *f = data;
-
- if (state == CPUFREQ_PRECHANGE) {
- /* Save frequency in simple Hz */
- clk_smp_twd_rate = (f->new * 1000) / 2;
- }
-
- return NOTIFY_OK;
-}
-
-static struct notifier_block clk_twd_cpufreq_nb = {
- .notifier_call = clk_twd_cpufreq_transition,
-};
-
-int clk_init_smp_twd_cpufreq(void)
-{
- return cpufreq_register_notifier(&clk_twd_cpufreq_nb,
- CPUFREQ_TRANSITION_NOTIFIER);
-}
-
-#endif
-
-int __init clk_init(void)
-{
- clkdev_add_table(u8500_clks, ARRAY_SIZE(u8500_clks));
- clkdev_add(&clk_smp_twd_lookup);
-
-#ifdef CONFIG_DEBUG_FS
- clk_debugfs_add_table(u8500_clks, ARRAY_SIZE(u8500_clks));
-#endif
- return 0;
-}
diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h
deleted file mode 100644
index 65d27a13f46d..000000000000
--- a/arch/arm/mach-ux500/clock.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2010 ST-Ericsson
- * Copyright (C) 2009 STMicroelectronics
- *
- * 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.
- */
-
-/**
- * struct clkops - ux500 clock operations
- * @enable: function to enable the clock
- * @disable: function to disable the clock
- * @get_rate: function to get the current clock rate
- *
- * This structure contains function pointers to functions that will be used to
- * control the clock. All of these functions are optional. If get_rate is
- * NULL, the rate in the struct clk will be used.
- */
-struct clkops {
- void (*enable) (struct clk *);
- void (*disable) (struct clk *);
- unsigned long (*get_rate) (struct clk *);
- int (*set_parent)(struct clk *, struct clk *);
-};
-
-/**
- * struct clk - ux500 clock structure
- * @ops: pointer to clkops struct used to control this clock
- * @name: name, for debugging
- * @enabled: refcount. positive if enabled, zero if disabled
- * @get_rate: custom callback for getting the clock rate
- * @data: custom per-clock data for example for the get_rate
- * callback
- * @rate: fixed rate for clocks which don't implement
- * ops->getrate
- * @prcmu_cg_off: address offset of the combined enable/disable register
- * (used on u8500v1)
- * @prcmu_cg_bit: bit in the combined enable/disable register (used on
- * u8500v1)
- * @prcmu_cg_mgt: address of the enable/disable register (used on
- * u8500ed)
- * @cluster: peripheral cluster number
- * @prcc_bus: bit for the bus clock in the peripheral's CLKRST
- * @prcc_kernel: bit for the kernel clock in the peripheral's CLKRST.
- * -1 if no kernel clock exists.
- * @parent_cluster: pointer to parent's cluster clk struct
- * @parent_periph: pointer to parent's peripheral clk struct
- *
- * Peripherals are organised into clusters, and each cluster has an associated
- * bus clock. Some peripherals also have a parent peripheral clock.
- *
- * In order to enable a clock for a peripheral, we need to enable:
- * (1) the parent cluster (bus) clock at the PRCMU level
- * (2) the parent peripheral clock (if any) at the PRCMU level
- * (3) the peripheral's bus & kernel clock at the PRCC level
- *
- * (1) and (2) are handled by defining clk structs (DEFINE_PRCMU_CLK) for each
- * of the cluster and peripheral clocks, and hooking these as the parents of
- * the individual peripheral clocks.
- *
- * (3) is handled by specifying the bits in the PRCC control registers required
- * to enable these clocks and modifying them in the ->enable and
- * ->disable callbacks of the peripheral clocks (DEFINE_PRCC_CLK).
- *
- * This structure describes both the PRCMU-level clocks and PRCC-level clocks.
- * The prcmu_* fields are only used for the PRCMU clocks, and the cluster,
- * prcc, and parent pointers are only used for the PRCC-level clocks.
- */
-struct clk {
- const struct clkops *ops;
- const char *name;
- unsigned int enabled;
- unsigned long (*get_rate)(struct clk *);
- void *data;
-
- unsigned long rate;
- struct list_head list;
-
- /* These three are only for PRCMU clks */
-
- unsigned int prcmu_cg_off;
- unsigned int prcmu_cg_bit;
- unsigned int prcmu_cg_mgt;
-
- /* The rest are only for PRCC clks */
-
- int cluster;
- unsigned int prcc_bus;
- unsigned int prcc_kernel;
-
- struct clk *parent_cluster;
- struct clk *parent_periph;
-#if defined(CONFIG_DEBUG_FS)
- struct dentry *dent; /* For visible tree hierarchy */
- struct dentry *dent_bus; /* For visible tree hierarchy */
-#endif
-};
-
-#define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg) \
-struct clk clk_##_name = { \
- .name = #_name, \
- .ops = &clk_prcmu_ops, \
- .prcmu_cg_off = _cg_off, \
- .prcmu_cg_bit = _cg_bit, \
- .prcmu_cg_mgt = PRCM_##_reg##_MGT \
- }
-
-#define DEFINE_PRCMU_CLK_RATE(_name, _cg_off, _cg_bit, _reg, _rate) \
-struct clk clk_##_name = { \
- .name = #_name, \
- .ops = &clk_prcmu_ops, \
- .prcmu_cg_off = _cg_off, \
- .prcmu_cg_bit = _cg_bit, \
- .rate = _rate, \
- .prcmu_cg_mgt = PRCM_##_reg##_MGT \
- }
-
-#define DEFINE_PRCC_CLK(_pclust, _name, _bus_en, _kernel_en, _kernclk) \
-struct clk clk_##_name = { \
- .name = #_name, \
- .ops = &clk_prcc_ops, \
- .cluster = _pclust, \
- .prcc_bus = _bus_en, \
- .prcc_kernel = _kernel_en, \
- .parent_cluster = &clk_per##_pclust##clk, \
- .parent_periph = _kernclk \
- }
-
-#define DEFINE_PRCC_CLK_CUSTOM(_pclust, _name, _bus_en, _kernel_en, _kernclk, _callback, _data) \
-struct clk clk_##_name = { \
- .name = #_name, \
- .ops = &clk_prcc_ops, \
- .cluster = _pclust, \
- .prcc_bus = _bus_en, \
- .prcc_kernel = _kernel_en, \
- .parent_cluster = &clk_per##_pclust##clk, \
- .parent_periph = _kernclk, \
- .get_rate = _callback, \
- .data = (void *) _data \
- }
-
-
-#define CLK(_clk, _devname, _conname) \
- { \
- .clk = &clk_##_clk, \
- .dev_id = _devname, \
- .con_id = _conname, \
- }
-
-int __init clk_db8500_ed_fixup(void);
-int __init clk_init(void);
-
-#ifdef CONFIG_DEBUG_FS
-int clk_debugfs_init(void);
-#else
-static inline int clk_debugfs_init(void) { return 0; }
-#endif
-
-#ifdef CONFIG_CPU_FREQ
-int clk_init_smp_twd_cpufreq(void);
-#else
-static inline int clk_init_smp_twd_cpufreq(void) { return 0; }
-#endif
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index e2360e7c770d..17a78ec516ff 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -8,7 +8,6 @@
#include <linux/platform_device.h>
#include <linux/io.h>
-#include <linux/clk.h>
#include <linux/mfd/db8500-prcmu.h>
#include <linux/clksrc-dbx500-prcmu.h>
#include <linux/sys_soc.h>
@@ -17,6 +16,7 @@
#include <linux/stat.h>
#include <linux/of.h>
#include <linux/of_irq.h>
+#include <linux/platform_data/clk-ux500.h>
#include <asm/hardware/gic.h>
#include <asm/mach/map.h>
@@ -25,8 +25,6 @@
#include <mach/setup.h>
#include <mach/devices.h>
-#include "clock.h"
-
void __iomem *_PRCMU_BASE;
/*
@@ -70,13 +68,17 @@ void __init ux500_init_irq(void)
*/
if (cpu_is_u8500_family())
db8500_prcmu_early_init();
- clk_init();
+
+ if (cpu_is_u8500_family())
+ u8500_clk_init();
+ else if (cpu_is_u9540())
+ u9540_clk_init();
+ else if (cpu_is_u8540())
+ u8540_clk_init();
}
void __init ux500_init_late(void)
{
- clk_debugfs_init();
- clk_init_smp_twd_cpufreq();
}
static const char * __init ux500_get_machine(void)