* [PATCH 1/2] ARM: vexpress: Check master site in daughterboard's sysctl operations
@ 2012-06-08 12:50 Pawel Moll
2012-06-08 12:50 ` [PATCH 2/2] ARM: vexpress: Initial common clock support Pawel Moll
2012-06-12 8:58 ` [PATCH 1/2] ARM: vexpress: Check master site in daughterboard's sysctl operations Jon Medhurst (Tixy)
0 siblings, 2 replies; 6+ messages in thread
From: Pawel Moll @ 2012-06-08 12:50 UTC (permalink / raw)
To: linux-arm-kernel
With recent enough motherboard firmware, core tile can be fitted
in either of the two daughterboard sites. The non-DT tile code for
V2P-CA9 did not check that when configuring DVI output nor setting
CLCD pixel clock.
Fixed now, providing "get master site" API in motherboard's code.
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
arch/arm/mach-vexpress/ct-ca9x4.c | 15 ++++++++++++---
arch/arm/mach-vexpress/include/mach/motherboard.h | 9 ++++++---
arch/arm/mach-vexpress/v2m.c | 12 +++++++++---
3 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index c65cc3b..11cb248 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -66,8 +66,15 @@ static void __init ct_ca9x4_init_irq(void)
static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
{
- v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
- v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE_DB1, 2);
+ u32 site = v2m_get_master_site();
+
+ /*
+ * Old firmware was using the "site" component of the command
+ * to control the DVI muxer (while it should be always 0 ie. MB).
+ * Newer firmware uses the data register. Keep both for compatibility.
+ */
+ v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE(site), site);
+ v2m_cfg_write(SYS_CFG_DVIMODE, 2);
}
static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
@@ -112,7 +119,9 @@ static long ct_round(struct clk *clk, unsigned long rate)
static int ct_set(struct clk *clk, unsigned long rate)
{
- return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_DB1 | 1, rate);
+ u32 site = v2m_get_master_site();
+
+ return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE(site) | 1, rate);
}
static const struct clk_ops osc1_clk_ops = {
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
index 31a9289..f004ec9 100644
--- a/arch/arm/mach-vexpress/include/mach/motherboard.h
+++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
@@ -104,9 +104,10 @@
#define SYS_CFG_REBOOT (9 << 20)
#define SYS_CFG_DVIMODE (11 << 20)
#define SYS_CFG_POWER (12 << 20)
-#define SYS_CFG_SITE_MB (0 << 16)
-#define SYS_CFG_SITE_DB1 (1 << 16)
-#define SYS_CFG_SITE_DB2 (2 << 16)
+#define SYS_CFG_SITE(n) ((n) << 16)
+#define SYS_CFG_SITE_MB 0
+#define SYS_CFG_SITE_DB1 1
+#define SYS_CFG_SITE_DB2 2
#define SYS_CFG_STACK(n) ((n) << 12)
#define SYS_CFG_ERR (1 << 1)
@@ -122,6 +123,8 @@ void v2m_flags_set(u32 data);
#define SYS_MISC_MASTERSITE (1 << 14)
#define SYS_PROCIDx_HBI_MASK 0xfff
+int v2m_get_master_site(void);
+
/*
* Core tile IDs
*/
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index fde26ad..aa6f9a6 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -147,6 +147,13 @@ void __init v2m_flags_set(u32 data)
writel(data, v2m_sysreg_base + V2M_SYS_FLAGSSET);
}
+int __init v2m_get_master_site(void)
+{
+ u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC);
+
+ return misc & SYS_MISC_MASTERSITE ? SYS_CFG_SITE_DB2 : SYS_CFG_SITE_DB1;
+}
+
static struct resource v2m_pcie_i2c_resource = {
.start = V2M_SERIAL_BUS_PCI,
@@ -413,7 +420,6 @@ static void v2m_restart(char str, const char *cmd)
if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0))
printk(KERN_EMERG "Unable to reboot\n");
}
-
struct ct_desc *ct_desc;
static struct ct_desc *ct_descs[] __initdata = {
@@ -605,8 +611,8 @@ void __init v2m_dt_init_early(void)
/* Confirm board type against DT property, if available */
if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) {
- u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC);
- u32 id = readl(v2m_sysreg_base + (misc & SYS_MISC_MASTERSITE ?
+ int site = v2m_get_master_site();
+ u32 id = readl(v2m_sysreg_base + (site == SYS_CFG_SITE_DB2 ?
V2M_SYS_PROCID1 : V2M_SYS_PROCID0));
u32 hbi = id & SYS_PROCIDx_HBI_MASK;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] ARM: vexpress: Initial common clock support
2012-06-08 12:50 [PATCH 1/2] ARM: vexpress: Check master site in daughterboard's sysctl operations Pawel Moll
@ 2012-06-08 12:50 ` Pawel Moll
2012-06-13 10:07 ` Jon Medhurst (Tixy)
2012-06-12 8:58 ` [PATCH 1/2] ARM: vexpress: Check master site in daughterboard's sysctl operations Jon Medhurst (Tixy)
1 sibling, 1 reply; 6+ messages in thread
From: Pawel Moll @ 2012-06-08 12:50 UTC (permalink / raw)
To: linux-arm-kernel
This patch makes Versatile Express use the common clock framework
instead of the plat-versatile implementation (which remains intact
for mach-versatile and mach-realview sake).
It defines clock provider for VE's OSCs (clock generators) and
registers all required fixed and variable clock sources (for both
motherboard and core tile).
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
arch/arm/Kconfig | 2 +-
arch/arm/mach-vexpress/ct-ca9x4.c | 55 +----
arch/arm/mach-vexpress/include/mach/clkdev.h | 15 --
arch/arm/mach-vexpress/include/mach/motherboard.h | 20 ++
arch/arm/mach-vexpress/v2m.c | 253 +++++++++------------
arch/arm/plat-versatile/Kconfig | 5 +
arch/arm/plat-versatile/Makefile | 2 +-
7 files changed, 150 insertions(+), 202 deletions(-)
delete mode 100644 arch/arm/mach-vexpress/include/mach/clkdev.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 84449dd..6f3370e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -306,7 +306,7 @@ config ARCH_VEXPRESS
select ARM_AMBA
select ARM_TIMER_SP804
select CLKDEV_LOOKUP
- select HAVE_MACH_CLKDEV
+ select COMMON_CLK
select GENERIC_CLOCKEVENTS
select HAVE_CLK
select HAVE_PATA_PLATFORM
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 11cb248..3ef3fda 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -111,48 +111,22 @@ static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
&gpio_device,
};
+static struct v2m_osc ct_osc1 = {
+ .osc = 1,
+ .rate_min = 10000000,
+ .rate_max = 80000000,
+ .rate_default = 23750000,
+};
-static long ct_round(struct clk *clk, unsigned long rate)
-{
- return rate;
-}
-
-static int ct_set(struct clk *clk, unsigned long rate)
+static void __init ct_ca9x4_init_clk(void)
{
- u32 site = v2m_get_master_site();
+ struct clk *clk;
- return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE(site) | 1, rate);
+ ct_osc1.site = v2m_get_master_site();
+ clk = v2m_osc_register("ct:osc1", &ct_osc1);
+ clk_register_clkdev(clk, NULL, "ct:clcd");
}
-static const struct clk_ops osc1_clk_ops = {
- .round = ct_round,
- .set = ct_set,
-};
-
-static struct clk osc1_clk = {
- .ops = &osc1_clk_ops,
- .rate = 24000000,
-};
-
-static struct clk ct_sp804_clk = {
- .rate = 1000000,
-};
-
-static struct clk_lookup lookups[] = {
- { /* CLCD */
- .dev_id = "ct:clcd",
- .clk = &osc1_clk,
- }, { /* SP804 timers */
- .dev_id = "sp804",
- .con_id = "ct-timer0",
- .clk = &ct_sp804_clk,
- }, { /* SP804 timers */
- .dev_id = "sp804",
- .con_id = "ct-timer1",
- .clk = &ct_sp804_clk,
- },
-};
-
static struct resource pmu_resources[] = {
[0] = {
.start = IRQ_CT_CA9X4_PMU_CPU0,
@@ -183,11 +157,6 @@ static struct platform_device pmu_device = {
.resource = pmu_resources,
};
-static void __init ct_ca9x4_init_early(void)
-{
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-}
-
static void __init ct_ca9x4_init(void)
{
int i;
@@ -243,8 +212,8 @@ struct ct_desc ct_ca9x4_desc __initdata = {
.id = V2M_CT_ID_CA9,
.name = "CA9x4",
.map_io = ct_ca9x4_map_io,
- .init_early = ct_ca9x4_init_early,
.init_irq = ct_ca9x4_init_irq,
+ .init_clk = ct_ca9x4_init_clk,
.init_tile = ct_ca9x4_init,
#ifdef CONFIG_SMP
.init_cpu_map = ct_ca9x4_init_cpu_map,
diff --git a/arch/arm/mach-vexpress/include/mach/clkdev.h b/arch/arm/mach-vexpress/include/mach/clkdev.h
deleted file mode 100644
index 3f8307d..0000000
--- a/arch/arm/mach-vexpress/include/mach/clkdev.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef __ASM_MACH_CLKDEV_H
-#define __ASM_MACH_CLKDEV_H
-
-#include <plat/clock.h>
-
-struct clk {
- const struct clk_ops *ops;
- unsigned long rate;
- const struct icst_params *params;
-};
-
-#define __clk_get(clk) ({ 1; })
-#define __clk_put(clk) do { } while (0)
-
-#endif
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
index f004ec9..2762263 100644
--- a/arch/arm/mach-vexpress/include/mach/motherboard.h
+++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
@@ -1,6 +1,8 @@
#ifndef __MACH_MOTHERBOARD_H
#define __MACH_MOTHERBOARD_H
+#include <linux/clk-provider.h>
+
/*
* Physical addresses, offset from V2M_PA_CS0-3
*/
@@ -138,6 +140,7 @@ struct ct_desc {
void (*map_io)(void);
void (*init_early)(void);
void (*init_irq)(void);
+ void (*init_clk)(void);
void (*init_tile)(void);
#ifdef CONFIG_SMP
void (*init_cpu_map)(void);
@@ -147,4 +150,21 @@ struct ct_desc {
extern struct ct_desc *ct_desc;
+/*
+ * OSC clock provider
+ */
+struct v2m_osc {
+ struct clk_hw hw;
+ u8 site; /* 0 = motherboard, 1 = site 1, 2 = site 2 */
+ u8 stack; /* board stack position */
+ u16 osc;
+ unsigned long rate_min;
+ unsigned long rate_max;
+ unsigned long rate_default;
+};
+
+#define to_v2m_osc(osc) container_of(osc, struct v2m_osc, hw)
+
+struct clk *v2m_osc_register(const char *name, struct v2m_osc *osc);
+
#endif
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index aa6f9a6..e1e2415 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -16,6 +16,7 @@
#include <linux/spinlock.h>
#include <linux/usb/isp1760.h>
#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
#include <linux/mtd/physmap.h>
#include <asm/arch_timer.h>
@@ -81,16 +82,6 @@ static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0");
}
-static void __init v2m_timer_init(void)
-{
- v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K));
- v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
-}
-
-static struct sys_timer v2m_timer = {
- .init = v2m_timer_init,
-};
-
static DEFINE_SPINLOCK(v2m_cfg_lock);
@@ -326,86 +317,135 @@ static struct amba_device *v2m_amba_devs[] __initdata = {
};
-static long v2m_osc_round(struct clk *clk, unsigned long rate)
+static unsigned long v2m_osc_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct v2m_osc *osc = to_v2m_osc(hw);
+
+ return !parent_rate ? osc->rate_default : parent_rate;
+}
+
+static long v2m_osc_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
{
+ struct v2m_osc *osc = to_v2m_osc(hw);
+
+ if (WARN_ON(rate < osc->rate_min))
+ rate = osc->rate_min;
+
+ if (WARN_ON(rate > osc->rate_max))
+ rate = osc->rate_max;
+
return rate;
}
-static int v2m_osc1_set(struct clk *clk, unsigned long rate)
+static int v2m_osc_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
{
- return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_MB | 1, rate);
+ struct v2m_osc *osc = to_v2m_osc(hw);
+
+ v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE(osc->site) |
+ SYS_CFG_STACK(osc->stack) | osc->osc, rate);
+
+ return 0;
}
-static const struct clk_ops osc1_clk_ops = {
- .round = v2m_osc_round,
- .set = v2m_osc1_set,
+static struct clk_ops v2m_osc_ops = {
+ .recalc_rate = v2m_osc_recalc_rate,
+ .round_rate = v2m_osc_round_rate,
+ .set_rate = v2m_osc_set_rate,
};
-static struct clk osc1_clk = {
- .ops = &osc1_clk_ops,
- .rate = 24000000,
+struct clk * __init v2m_osc_register(const char *name, struct v2m_osc *osc)
+{
+ struct clk_init_data init;
+
+ WARN_ON(osc->site > 2);
+ WARN_ON(osc->stack > 15);
+ WARN_ON(osc->osc > 4095);
+
+ init.name = name;
+ init.ops = &v2m_osc_ops;
+ init.flags = CLK_IS_ROOT;
+ init.num_parents = 0;
+
+ osc->hw.init = &init;
+
+ return clk_register(NULL, &osc->hw);
+}
+
+static struct v2m_osc v2m_mb_osc1 = {
+ .site = SYS_CFG_SITE_MB,
+ .osc = 1,
+ .rate_min = 23750000,
+ .rate_max = 63500000,
+ .rate_default = 23750000,
};
-static struct clk osc2_clk = {
- .rate = 24000000,
+static const char *v2m_ref_clk_periphs[] __initconst = {
+ "mb:wdt", "1000f000.wdt", "1c0f0000.wdt", /* SP805 WDT */
};
-static struct clk v2m_sp804_clk = {
- .rate = 1000000,
+static const char *v2m_osc1_periphs[] __initconst = {
+ "mb:clcd", "1001f000.clcd", "1c1f0000.clcd", /* PL111 CLCD */
};
-static struct clk v2m_ref_clk = {
- .rate = 32768,
+static const char *v2m_osc2_periphs[] __initconst = {
+ "mb:mmci", "10005000.mmci", "1c050000.mmci", /* PL180 MMCI */
+ "mb:kmi0", "10006000.kmi", "1c060000.kmi", /* PL050 KMI0 */
+ "mb:kmi1", "10007000.kmi", "1c070000.kmi", /* PL050 KMI1 */
+ "mb:uart0", "10009000.uart", "1c090000.uart", /* PL011 UART0 */
+ "mb:uart1", "1000a000.uart", "1c0a0000.uart", /* PL011 UART1 */
+ "mb:uart2", "1000b000.uart", "1c0b0000.uart", /* PL011 UART2 */
+ "mb:uart3", "1000c000.uart", "1c0c0000.uart", /* PL011 UART3 */
};
-static struct clk dummy_apb_pclk;
-
-static struct clk_lookup v2m_lookups[] = {
- { /* AMBA bus clock */
- .con_id = "apb_pclk",
- .clk = &dummy_apb_pclk,
- }, { /* UART0 */
- .dev_id = "mb:uart0",
- .clk = &osc2_clk,
- }, { /* UART1 */
- .dev_id = "mb:uart1",
- .clk = &osc2_clk,
- }, { /* UART2 */
- .dev_id = "mb:uart2",
- .clk = &osc2_clk,
- }, { /* UART3 */
- .dev_id = "mb:uart3",
- .clk = &osc2_clk,
- }, { /* KMI0 */
- .dev_id = "mb:kmi0",
- .clk = &osc2_clk,
- }, { /* KMI1 */
- .dev_id = "mb:kmi1",
- .clk = &osc2_clk,
- }, { /* MMC0 */
- .dev_id = "mb:mmci",
- .clk = &osc2_clk,
- }, { /* CLCD */
- .dev_id = "mb:clcd",
- .clk = &osc1_clk,
- }, { /* SP805 WDT */
- .dev_id = "mb:wdt",
- .clk = &v2m_ref_clk,
- }, { /* SP804 timers */
- .dev_id = "sp804",
- .con_id = "v2m-timer0",
- .clk = &v2m_sp804_clk,
- }, { /* SP804 timers */
- .dev_id = "sp804",
- .con_id = "v2m-timer1",
- .clk = &v2m_sp804_clk,
- },
+static void __init v2m_clk_init(void)
+{
+ struct clk *clk;
+ int i;
+
+ clk = clk_register_fixed_rate(NULL, "dummy_apb_pclk", NULL,
+ CLK_IS_ROOT, 0);
+ WARN_ON(clk_register_clkdev(clk, "abp_pclk", NULL));
+
+ clk = clk_register_fixed_rate(NULL, "mb:ref_clk", NULL,
+ CLK_IS_ROOT, 32768);
+ for (i = 0; i < ARRAY_SIZE(v2m_ref_clk_periphs); i++)
+ WARN_ON(clk_register_clkdev(clk, NULL, v2m_ref_clk_periphs[i]));
+
+ clk = clk_register_fixed_rate(NULL, "mb:sp804_clk", NULL,
+ CLK_IS_ROOT, 1000000);
+ WARN_ON(clk_register_clkdev(clk, "v2m-timer0", "sp804"));
+ WARN_ON(clk_register_clkdev(clk, "v2m-timer1", "sp804"));
+
+ clk = v2m_osc_register("mb:osc1", &v2m_mb_osc1);
+ for (i = 0; i < ARRAY_SIZE(v2m_osc1_periphs); i++)
+ WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc1_periphs[i]));
+
+ clk = clk_register_fixed_rate(NULL, "mb:osc2", NULL,
+ CLK_IS_ROOT, 24000000);
+ for (i = 0; i < ARRAY_SIZE(v2m_osc2_periphs); i++)
+ WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc2_periphs[i]));
+}
+
+static void __init v2m_timer_init(void)
+{
+ v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K));
+ v2m_clk_init();
+ if (ct_desc->init_clk)
+ ct_desc->init_clk();
+ v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
+}
+
+static struct sys_timer v2m_timer = {
+ .init = v2m_timer_init,
};
static void __init v2m_init_early(void)
{
- ct_desc->init_early();
- clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
+ if (ct_desc->init_early)
+ ct_desc->init_early();
versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000);
}
@@ -528,77 +568,6 @@ void __init v2m_dt_map_io(void)
#endif
}
-static struct clk_lookup v2m_dt_lookups[] = {
- { /* AMBA bus clock */
- .con_id = "apb_pclk",
- .clk = &dummy_apb_pclk,
- }, { /* SP804 timers */
- .dev_id = "sp804",
- .con_id = "v2m-timer0",
- .clk = &v2m_sp804_clk,
- }, { /* SP804 timers */
- .dev_id = "sp804",
- .con_id = "v2m-timer1",
- .clk = &v2m_sp804_clk,
- }, { /* PL180 MMCI */
- .dev_id = "mb:mmci", /* 10005000.mmci */
- .clk = &osc2_clk,
- }, { /* PL050 KMI0 */
- .dev_id = "10006000.kmi",
- .clk = &osc2_clk,
- }, { /* PL050 KMI1 */
- .dev_id = "10007000.kmi",
- .clk = &osc2_clk,
- }, { /* PL011 UART0 */
- .dev_id = "10009000.uart",
- .clk = &osc2_clk,
- }, { /* PL011 UART1 */
- .dev_id = "1000a000.uart",
- .clk = &osc2_clk,
- }, { /* PL011 UART2 */
- .dev_id = "1000b000.uart",
- .clk = &osc2_clk,
- }, { /* PL011 UART3 */
- .dev_id = "1000c000.uart",
- .clk = &osc2_clk,
- }, { /* SP805 WDT */
- .dev_id = "1000f000.wdt",
- .clk = &v2m_ref_clk,
- }, { /* PL111 CLCD */
- .dev_id = "1001f000.clcd",
- .clk = &osc1_clk,
- },
- /* RS1 memory map */
- { /* PL180 MMCI */
- .dev_id = "mb:mmci", /* 1c050000.mmci */
- .clk = &osc2_clk,
- }, { /* PL050 KMI0 */
- .dev_id = "1c060000.kmi",
- .clk = &osc2_clk,
- }, { /* PL050 KMI1 */
- .dev_id = "1c070000.kmi",
- .clk = &osc2_clk,
- }, { /* PL011 UART0 */
- .dev_id = "1c090000.uart",
- .clk = &osc2_clk,
- }, { /* PL011 UART1 */
- .dev_id = "1c0a0000.uart",
- .clk = &osc2_clk,
- }, { /* PL011 UART2 */
- .dev_id = "1c0b0000.uart",
- .clk = &osc2_clk,
- }, { /* PL011 UART3 */
- .dev_id = "1c0c0000.uart",
- .clk = &osc2_clk,
- }, { /* SP805 WDT */
- .dev_id = "1c0f0000.wdt",
- .clk = &v2m_ref_clk,
- }, { /* PL111 CLCD */
- .dev_id = "1c1f0000.clcd",
- .clk = &osc1_clk,
- },
-};
-
void __init v2m_dt_init_early(void)
{
struct device_node *node;
@@ -620,8 +589,6 @@ void __init v2m_dt_init_early(void)
pr_warning("vexpress: DT HBI (%x) is not matching "
"hardware (%x)!\n", dt_hbi, hbi);
}
-
- clkdev_add_table(v2m_dt_lookups, ARRAY_SIZE(v2m_dt_lookups));
}
static struct of_device_id vexpress_irq_match[] __initdata = {
@@ -643,6 +610,8 @@ static void __init v2m_dt_timer_init(void)
node = of_find_compatible_node(NULL, NULL, "arm,sp810");
v2m_sysctl_init(of_iomap(node, 0));
+ v2m_clk_init();
+
err = of_property_read_string(of_aliases, "arm,v2m_timer", &path);
if (WARN_ON(err))
return;
diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig
index 81ee7cc..4b9f4bf 100644
--- a/arch/arm/plat-versatile/Kconfig
+++ b/arch/arm/plat-versatile/Kconfig
@@ -1,5 +1,10 @@
if PLAT_VERSATILE
+config PLAT_VERSATILE_CLOCK
+ bool
+ default y
+ depends on !COMMON_CLK
+
config PLAT_VERSATILE_CLCD
bool
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
index a5cb194..272769a8 100644
--- a/arch/arm/plat-versatile/Makefile
+++ b/arch/arm/plat-versatile/Makefile
@@ -1,4 +1,4 @@
-obj-y := clock.o
+obj-$(CONFIG_PLAT_VERSATILE_CLOCK) += clock.o
obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
--
1.7.9.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 1/2] ARM: vexpress: Check master site in daughterboard's sysctl operations
2012-06-08 12:50 [PATCH 1/2] ARM: vexpress: Check master site in daughterboard's sysctl operations Pawel Moll
2012-06-08 12:50 ` [PATCH 2/2] ARM: vexpress: Initial common clock support Pawel Moll
@ 2012-06-12 8:58 ` Jon Medhurst (Tixy)
2012-06-12 9:08 ` Pawel Moll
2012-06-12 13:02 ` Jon Medhurst (Tixy)
1 sibling, 2 replies; 6+ messages in thread
From: Jon Medhurst (Tixy) @ 2012-06-12 8:58 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 2012-06-08 at 13:50 +0100, Pawel Moll wrote:
> With recent enough motherboard firmware, core tile can be fitted
> in either of the two daughterboard sites. The non-DT tile code for
> V2P-CA9 did not check that when configuring DVI output nor setting
> CLCD pixel clock.
>
> Fixed now, providing "get master site" API in motherboard's code.
>
> Signed-off-by: Pawel Moll <pawel.moll@arm.com>
This patch makes an Ubuntu boot always hang for me, about the time it
would switch to GUI mode, it's not very consistent unfortunately.
If I modify ct_ca9x4_clcd_enable() to replace "v2m_get_master_site()"
with "1" then boot is OK. Even though if I put code it to test the
return value from v2m_get_master_site() it shows it gives 1.
I am running stock Version 3 firmware on my vexpress.
I also have some comments about this patch, see inline comments below...
> ---
> arch/arm/mach-vexpress/ct-ca9x4.c | 15 ++++++++++++---
> arch/arm/mach-vexpress/include/mach/motherboard.h | 9 ++++++---
> arch/arm/mach-vexpress/v2m.c | 12 +++++++++---
> 3 files changed, 27 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
> index c65cc3b..11cb248 100644
> --- a/arch/arm/mach-vexpress/ct-ca9x4.c
> +++ b/arch/arm/mach-vexpress/ct-ca9x4.c
> @@ -66,8 +66,15 @@ static void __init ct_ca9x4_init_irq(void)
>
> static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
> {
> - v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
> - v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE_DB1, 2);
> + u32 site = v2m_get_master_site();
> +
> + /*
> + * Old firmware was using the "site" component of the command
> + * to control the DVI muxer (while it should be always 0 ie. MB).
> + * Newer firmware uses the data register. Keep both for compatibility.
> + */
> + v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE(site), site);
> + v2m_cfg_write(SYS_CFG_DVIMODE, 2);
> }
>
> static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
> @@ -112,7 +119,9 @@ static long ct_round(struct clk *clk, unsigned long rate)
>
> static int ct_set(struct clk *clk, unsigned long rate)
> {
> - return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_DB1 | 1, rate);
> + u32 site = v2m_get_master_site();
> +
> + return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE(site) | 1, rate);
> }
>
> static const struct clk_ops osc1_clk_ops = {
> diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
> index 31a9289..f004ec9 100644
> --- a/arch/arm/mach-vexpress/include/mach/motherboard.h
> +++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
> @@ -104,9 +104,10 @@
> #define SYS_CFG_REBOOT (9 << 20)
> #define SYS_CFG_DVIMODE (11 << 20)
> #define SYS_CFG_POWER (12 << 20)
> -#define SYS_CFG_SITE_MB (0 << 16)
> -#define SYS_CFG_SITE_DB1 (1 << 16)
> -#define SYS_CFG_SITE_DB2 (2 << 16)
> +#define SYS_CFG_SITE(n) ((n) << 16)
> +#define SYS_CFG_SITE_MB 0
There are three uses of this latter macro you have left unaltered: in
v2m_osc1_set(), v2m_power_off() and v2m_restart(). Now 0 == (0<<16) so
the code will be functionally identical, but they should really be
updated replace SYS_CFG_SITE_MB with SYS_CFG_SITE(SYS_CFG_SITE_MB).
Though that looks a bit messy, perhaps instead we could have something
like...
#define SITE_MB 0
#define SITE_DB1 1
#define SITE_DB2 2
#define SYS_CFG_SITE(n) ((n) << 16)
#define SYS_CFG_SITE_MB SYS_CFG_SITE(SITE_MB)
#define SYS_CFG_SITE_DB1 SYS_CFG_SITE(SITE_DB1)
#define SYS_CFG_SITE_DB2 SYS_CFG_SITE(SITE_DB2)
> +#define SYS_CFG_SITE_DB1 1
> +#define SYS_CFG_SITE_DB2 2
> #define SYS_CFG_STACK(n) ((n) << 12)
>
> #define SYS_CFG_ERR (1 << 1)
> @@ -122,6 +123,8 @@ void v2m_flags_set(u32 data);
> #define SYS_MISC_MASTERSITE (1 << 14)
> #define SYS_PROCIDx_HBI_MASK 0xfff
>
> +int v2m_get_master_site(void);
> +
> /*
> * Core tile IDs
> */
> diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
> index fde26ad..aa6f9a6 100644
> --- a/arch/arm/mach-vexpress/v2m.c
> +++ b/arch/arm/mach-vexpress/v2m.c
> @@ -147,6 +147,13 @@ void __init v2m_flags_set(u32 data)
> writel(data, v2m_sysreg_base + V2M_SYS_FLAGSSET);
> }
>
> +int __init v2m_get_master_site(void)
> +{
> + u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC);
> +
> + return misc & SYS_MISC_MASTERSITE ? SYS_CFG_SITE_DB2 : SYS_CFG_SITE_DB1;
> +}
> +
>
> static struct resource v2m_pcie_i2c_resource = {
> .start = V2M_SERIAL_BUS_PCI,
> @@ -413,7 +420,6 @@ static void v2m_restart(char str, const char *cmd)
> if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0))
> printk(KERN_EMERG "Unable to reboot\n");
> }
> -
There's a spurious blank line deletion above.
> struct ct_desc *ct_desc;
>
> static struct ct_desc *ct_descs[] __initdata = {
> @@ -605,8 +611,8 @@ void __init v2m_dt_init_early(void)
>
> /* Confirm board type against DT property, if available */
> if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) {
> - u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC);
> - u32 id = readl(v2m_sysreg_base + (misc & SYS_MISC_MASTERSITE ?
> + int site = v2m_get_master_site();
> + u32 id = readl(v2m_sysreg_base + (site == SYS_CFG_SITE_DB2 ?
> V2M_SYS_PROCID1 : V2M_SYS_PROCID0));
> u32 hbi = id & SYS_PROCIDx_HBI_MASK;
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] ARM: vexpress: Check master site in daughterboard's sysctl operations
2012-06-12 8:58 ` [PATCH 1/2] ARM: vexpress: Check master site in daughterboard's sysctl operations Jon Medhurst (Tixy)
@ 2012-06-12 9:08 ` Pawel Moll
2012-06-12 13:02 ` Jon Medhurst (Tixy)
1 sibling, 0 replies; 6+ messages in thread
From: Pawel Moll @ 2012-06-12 9:08 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, 2012-06-12 at 09:58 +0100, Jon Medhurst (Tixy) wrote:
> On Fri, 2012-06-08 at 13:50 +0100, Pawel Moll wrote:
> > With recent enough motherboard firmware, core tile can be fitted
> > in either of the two daughterboard sites. The non-DT tile code for
> > V2P-CA9 did not check that when configuring DVI output nor setting
> > CLCD pixel clock.
> >
> > Fixed now, providing "get master site" API in motherboard's code.
> >
> > Signed-off-by: Pawel Moll <pawel.moll@arm.com>
>
> This patch makes an Ubuntu boot always hang for me, about the time it
> would switch to GUI mode, it's not very consistent unfortunately.
>
> If I modify ct_ca9x4_clcd_enable() to replace "v2m_get_master_site()"
> with "1" then boot is OK. Even though if I put code it to test the
> return value from v2m_get_master_site() it shows it gives 1.
>
> I am running stock Version 3 firmware on my vexpress.
Thanks for testing, I'll try to reproduce your problem here.
> > diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
> > index 31a9289..f004ec9 100644
> > --- a/arch/arm/mach-vexpress/include/mach/motherboard.h
> > +++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
> > @@ -104,9 +104,10 @@
> > #define SYS_CFG_REBOOT (9 << 20)
> > #define SYS_CFG_DVIMODE (11 << 20)
> > #define SYS_CFG_POWER (12 << 20)
> > -#define SYS_CFG_SITE_MB (0 << 16)
> > -#define SYS_CFG_SITE_DB1 (1 << 16)
> > -#define SYS_CFG_SITE_DB2 (2 << 16)
> > +#define SYS_CFG_SITE(n) ((n) << 16)
> > +#define SYS_CFG_SITE_MB 0
>
> There are three uses of this latter macro you have left unaltered: in
> v2m_osc1_set(), v2m_power_off() and v2m_restart().
Good point. I did grep for _DBx, forgot to do the same for _MB.
Having said that - I have to rework this whole lot anyway, to get all
functionality we need from sysreg/ctl, so don't bother with carrying
this patch in your tree.
Cheers!
Pawe?
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] ARM: vexpress: Check master site in daughterboard's sysctl operations
2012-06-12 8:58 ` [PATCH 1/2] ARM: vexpress: Check master site in daughterboard's sysctl operations Jon Medhurst (Tixy)
2012-06-12 9:08 ` Pawel Moll
@ 2012-06-12 13:02 ` Jon Medhurst (Tixy)
1 sibling, 0 replies; 6+ messages in thread
From: Jon Medhurst (Tixy) @ 2012-06-12 13:02 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, 2012-06-12 at 09:58 +0100, Jon Medhurst (Tixy) wrote:
> On Fri, 2012-06-08 at 13:50 +0100, Pawel Moll wrote:
> > With recent enough motherboard firmware, core tile can be fitted
> > in either of the two daughterboard sites. The non-DT tile code for
> > V2P-CA9 did not check that when configuring DVI output nor setting
> > CLCD pixel clock.
> >
> > Fixed now, providing "get master site" API in motherboard's code.
> >
> > Signed-off-by: Pawel Moll <pawel.moll@arm.com>
>
> This patch makes an Ubuntu boot always hang for me, about the time it
> would switch to GUI mode, it's not very consistent unfortunately.
I've found the cause of the problem, v2m_get_master_site() is marked
__init but is used by the non __init function ct_ca9x4_clcd_enable(). So
when Ubuntu GUI startup messes with the display it ends up calling into
freed memory.
Dropping __init from ct_ca9x4_clcd_enable() fixes my boot failures.
--
Tixy
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] ARM: vexpress: Initial common clock support
2012-06-08 12:50 ` [PATCH 2/2] ARM: vexpress: Initial common clock support Pawel Moll
@ 2012-06-13 10:07 ` Jon Medhurst (Tixy)
0 siblings, 0 replies; 6+ messages in thread
From: Jon Medhurst (Tixy) @ 2012-06-13 10:07 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 2012-06-08 at 13:50 +0100, Pawel Moll wrote:
> This patch makes Versatile Express use the common clock framework
> instead of the plat-versatile implementation (which remains intact
> for mach-versatile and mach-realview sake).
>
> It defines clock provider for VE's OSCs (clock generators) and
> registers all required fixed and variable clock sources (for both
> motherboard and core tile).
>
> Signed-off-by: Pawel Moll <pawel.moll@arm.com>
Tested-by: Jon Medhurst <tixy@linaro.org>
(Tested on CA9 non-device tree and CA15-TC1 with device tree.)
> ---
> arch/arm/Kconfig | 2 +-
> arch/arm/mach-vexpress/ct-ca9x4.c | 55 +----
> arch/arm/mach-vexpress/include/mach/clkdev.h | 15 --
> arch/arm/mach-vexpress/include/mach/motherboard.h | 20 ++
> arch/arm/mach-vexpress/v2m.c | 253 +++++++++------------
> arch/arm/plat-versatile/Kconfig | 5 +
> arch/arm/plat-versatile/Makefile | 2 +-
> 7 files changed, 150 insertions(+), 202 deletions(-)
> delete mode 100644 arch/arm/mach-vexpress/include/mach/clkdev.h
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 84449dd..6f3370e 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -306,7 +306,7 @@ config ARCH_VEXPRESS
> select ARM_AMBA
> select ARM_TIMER_SP804
> select CLKDEV_LOOKUP
> - select HAVE_MACH_CLKDEV
> + select COMMON_CLK
> select GENERIC_CLOCKEVENTS
> select HAVE_CLK
> select HAVE_PATA_PLATFORM
> diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
> index 11cb248..3ef3fda 100644
> --- a/arch/arm/mach-vexpress/ct-ca9x4.c
> +++ b/arch/arm/mach-vexpress/ct-ca9x4.c
> @@ -111,48 +111,22 @@ static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
> &gpio_device,
> };
>
> +static struct v2m_osc ct_osc1 = {
> + .osc = 1,
> + .rate_min = 10000000,
> + .rate_max = 80000000,
> + .rate_default = 23750000,
> +};
>
> -static long ct_round(struct clk *clk, unsigned long rate)
> -{
> - return rate;
> -}
> -
> -static int ct_set(struct clk *clk, unsigned long rate)
> +static void __init ct_ca9x4_init_clk(void)
> {
> - u32 site = v2m_get_master_site();
> + struct clk *clk;
>
> - return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE(site) | 1, rate);
> + ct_osc1.site = v2m_get_master_site();
> + clk = v2m_osc_register("ct:osc1", &ct_osc1);
> + clk_register_clkdev(clk, NULL, "ct:clcd");
> }
>
> -static const struct clk_ops osc1_clk_ops = {
> - .round = ct_round,
> - .set = ct_set,
> -};
> -
> -static struct clk osc1_clk = {
> - .ops = &osc1_clk_ops,
> - .rate = 24000000,
> -};
> -
> -static struct clk ct_sp804_clk = {
> - .rate = 1000000,
> -};
> -
> -static struct clk_lookup lookups[] = {
> - { /* CLCD */
> - .dev_id = "ct:clcd",
> - .clk = &osc1_clk,
> - }, { /* SP804 timers */
> - .dev_id = "sp804",
> - .con_id = "ct-timer0",
> - .clk = &ct_sp804_clk,
> - }, { /* SP804 timers */
> - .dev_id = "sp804",
> - .con_id = "ct-timer1",
> - .clk = &ct_sp804_clk,
> - },
> -};
> -
> static struct resource pmu_resources[] = {
> [0] = {
> .start = IRQ_CT_CA9X4_PMU_CPU0,
> @@ -183,11 +157,6 @@ static struct platform_device pmu_device = {
> .resource = pmu_resources,
> };
>
> -static void __init ct_ca9x4_init_early(void)
> -{
> - clkdev_add_table(lookups, ARRAY_SIZE(lookups));
> -}
> -
> static void __init ct_ca9x4_init(void)
> {
> int i;
> @@ -243,8 +212,8 @@ struct ct_desc ct_ca9x4_desc __initdata = {
> .id = V2M_CT_ID_CA9,
> .name = "CA9x4",
> .map_io = ct_ca9x4_map_io,
> - .init_early = ct_ca9x4_init_early,
> .init_irq = ct_ca9x4_init_irq,
> + .init_clk = ct_ca9x4_init_clk,
> .init_tile = ct_ca9x4_init,
> #ifdef CONFIG_SMP
> .init_cpu_map = ct_ca9x4_init_cpu_map,
> diff --git a/arch/arm/mach-vexpress/include/mach/clkdev.h b/arch/arm/mach-vexpress/include/mach/clkdev.h
> deleted file mode 100644
> index 3f8307d..0000000
> --- a/arch/arm/mach-vexpress/include/mach/clkdev.h
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -#ifndef __ASM_MACH_CLKDEV_H
> -#define __ASM_MACH_CLKDEV_H
> -
> -#include <plat/clock.h>
> -
> -struct clk {
> - const struct clk_ops *ops;
> - unsigned long rate;
> - const struct icst_params *params;
> -};
> -
> -#define __clk_get(clk) ({ 1; })
> -#define __clk_put(clk) do { } while (0)
> -
> -#endif
> diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
> index f004ec9..2762263 100644
> --- a/arch/arm/mach-vexpress/include/mach/motherboard.h
> +++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
> @@ -1,6 +1,8 @@
> #ifndef __MACH_MOTHERBOARD_H
> #define __MACH_MOTHERBOARD_H
>
> +#include <linux/clk-provider.h>
> +
> /*
> * Physical addresses, offset from V2M_PA_CS0-3
> */
> @@ -138,6 +140,7 @@ struct ct_desc {
> void (*map_io)(void);
> void (*init_early)(void);
> void (*init_irq)(void);
> + void (*init_clk)(void);
> void (*init_tile)(void);
> #ifdef CONFIG_SMP
> void (*init_cpu_map)(void);
> @@ -147,4 +150,21 @@ struct ct_desc {
>
> extern struct ct_desc *ct_desc;
>
> +/*
> + * OSC clock provider
> + */
> +struct v2m_osc {
> + struct clk_hw hw;
> + u8 site; /* 0 = motherboard, 1 = site 1, 2 = site 2 */
> + u8 stack; /* board stack position */
> + u16 osc;
> + unsigned long rate_min;
> + unsigned long rate_max;
> + unsigned long rate_default;
> +};
> +
> +#define to_v2m_osc(osc) container_of(osc, struct v2m_osc, hw)
> +
> +struct clk *v2m_osc_register(const char *name, struct v2m_osc *osc);
> +
> #endif
> diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
> index aa6f9a6..e1e2415 100644
> --- a/arch/arm/mach-vexpress/v2m.c
> +++ b/arch/arm/mach-vexpress/v2m.c
> @@ -16,6 +16,7 @@
> #include <linux/spinlock.h>
> #include <linux/usb/isp1760.h>
> #include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> #include <linux/mtd/physmap.h>
>
> #include <asm/arch_timer.h>
> @@ -81,16 +82,6 @@ static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
> sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0");
> }
>
> -static void __init v2m_timer_init(void)
> -{
> - v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K));
> - v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
> -}
> -
> -static struct sys_timer v2m_timer = {
> - .init = v2m_timer_init,
> -};
> -
>
> static DEFINE_SPINLOCK(v2m_cfg_lock);
>
> @@ -326,86 +317,135 @@ static struct amba_device *v2m_amba_devs[] __initdata = {
> };
>
>
> -static long v2m_osc_round(struct clk *clk, unsigned long rate)
> +static unsigned long v2m_osc_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct v2m_osc *osc = to_v2m_osc(hw);
> +
> + return !parent_rate ? osc->rate_default : parent_rate;
> +}
> +
> +static long v2m_osc_round_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long *parent_rate)
> {
> + struct v2m_osc *osc = to_v2m_osc(hw);
> +
> + if (WARN_ON(rate < osc->rate_min))
> + rate = osc->rate_min;
> +
> + if (WARN_ON(rate > osc->rate_max))
> + rate = osc->rate_max;
> +
> return rate;
> }
>
> -static int v2m_osc1_set(struct clk *clk, unsigned long rate)
> +static int v2m_osc_set_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long parent_rate)
> {
> - return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_MB | 1, rate);
> + struct v2m_osc *osc = to_v2m_osc(hw);
> +
> + v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE(osc->site) |
> + SYS_CFG_STACK(osc->stack) | osc->osc, rate);
> +
> + return 0;
> }
>
> -static const struct clk_ops osc1_clk_ops = {
> - .round = v2m_osc_round,
> - .set = v2m_osc1_set,
> +static struct clk_ops v2m_osc_ops = {
> + .recalc_rate = v2m_osc_recalc_rate,
> + .round_rate = v2m_osc_round_rate,
> + .set_rate = v2m_osc_set_rate,
> };
>
> -static struct clk osc1_clk = {
> - .ops = &osc1_clk_ops,
> - .rate = 24000000,
> +struct clk * __init v2m_osc_register(const char *name, struct v2m_osc *osc)
> +{
> + struct clk_init_data init;
> +
> + WARN_ON(osc->site > 2);
> + WARN_ON(osc->stack > 15);
> + WARN_ON(osc->osc > 4095);
> +
> + init.name = name;
> + init.ops = &v2m_osc_ops;
> + init.flags = CLK_IS_ROOT;
> + init.num_parents = 0;
> +
> + osc->hw.init = &init;
> +
> + return clk_register(NULL, &osc->hw);
> +}
> +
> +static struct v2m_osc v2m_mb_osc1 = {
> + .site = SYS_CFG_SITE_MB,
> + .osc = 1,
> + .rate_min = 23750000,
> + .rate_max = 63500000,
> + .rate_default = 23750000,
> };
>
> -static struct clk osc2_clk = {
> - .rate = 24000000,
> +static const char *v2m_ref_clk_periphs[] __initconst = {
> + "mb:wdt", "1000f000.wdt", "1c0f0000.wdt", /* SP805 WDT */
> };
>
> -static struct clk v2m_sp804_clk = {
> - .rate = 1000000,
> +static const char *v2m_osc1_periphs[] __initconst = {
> + "mb:clcd", "1001f000.clcd", "1c1f0000.clcd", /* PL111 CLCD */
> };
>
> -static struct clk v2m_ref_clk = {
> - .rate = 32768,
> +static const char *v2m_osc2_periphs[] __initconst = {
> + "mb:mmci", "10005000.mmci", "1c050000.mmci", /* PL180 MMCI */
> + "mb:kmi0", "10006000.kmi", "1c060000.kmi", /* PL050 KMI0 */
> + "mb:kmi1", "10007000.kmi", "1c070000.kmi", /* PL050 KMI1 */
> + "mb:uart0", "10009000.uart", "1c090000.uart", /* PL011 UART0 */
> + "mb:uart1", "1000a000.uart", "1c0a0000.uart", /* PL011 UART1 */
> + "mb:uart2", "1000b000.uart", "1c0b0000.uart", /* PL011 UART2 */
> + "mb:uart3", "1000c000.uart", "1c0c0000.uart", /* PL011 UART3 */
> };
>
> -static struct clk dummy_apb_pclk;
> -
> -static struct clk_lookup v2m_lookups[] = {
> - { /* AMBA bus clock */
> - .con_id = "apb_pclk",
> - .clk = &dummy_apb_pclk,
> - }, { /* UART0 */
> - .dev_id = "mb:uart0",
> - .clk = &osc2_clk,
> - }, { /* UART1 */
> - .dev_id = "mb:uart1",
> - .clk = &osc2_clk,
> - }, { /* UART2 */
> - .dev_id = "mb:uart2",
> - .clk = &osc2_clk,
> - }, { /* UART3 */
> - .dev_id = "mb:uart3",
> - .clk = &osc2_clk,
> - }, { /* KMI0 */
> - .dev_id = "mb:kmi0",
> - .clk = &osc2_clk,
> - }, { /* KMI1 */
> - .dev_id = "mb:kmi1",
> - .clk = &osc2_clk,
> - }, { /* MMC0 */
> - .dev_id = "mb:mmci",
> - .clk = &osc2_clk,
> - }, { /* CLCD */
> - .dev_id = "mb:clcd",
> - .clk = &osc1_clk,
> - }, { /* SP805 WDT */
> - .dev_id = "mb:wdt",
> - .clk = &v2m_ref_clk,
> - }, { /* SP804 timers */
> - .dev_id = "sp804",
> - .con_id = "v2m-timer0",
> - .clk = &v2m_sp804_clk,
> - }, { /* SP804 timers */
> - .dev_id = "sp804",
> - .con_id = "v2m-timer1",
> - .clk = &v2m_sp804_clk,
> - },
> +static void __init v2m_clk_init(void)
> +{
> + struct clk *clk;
> + int i;
> +
> + clk = clk_register_fixed_rate(NULL, "dummy_apb_pclk", NULL,
> + CLK_IS_ROOT, 0);
> + WARN_ON(clk_register_clkdev(clk, "abp_pclk", NULL));
> +
> + clk = clk_register_fixed_rate(NULL, "mb:ref_clk", NULL,
> + CLK_IS_ROOT, 32768);
> + for (i = 0; i < ARRAY_SIZE(v2m_ref_clk_periphs); i++)
> + WARN_ON(clk_register_clkdev(clk, NULL, v2m_ref_clk_periphs[i]));
> +
> + clk = clk_register_fixed_rate(NULL, "mb:sp804_clk", NULL,
> + CLK_IS_ROOT, 1000000);
> + WARN_ON(clk_register_clkdev(clk, "v2m-timer0", "sp804"));
> + WARN_ON(clk_register_clkdev(clk, "v2m-timer1", "sp804"));
> +
> + clk = v2m_osc_register("mb:osc1", &v2m_mb_osc1);
> + for (i = 0; i < ARRAY_SIZE(v2m_osc1_periphs); i++)
> + WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc1_periphs[i]));
> +
> + clk = clk_register_fixed_rate(NULL, "mb:osc2", NULL,
> + CLK_IS_ROOT, 24000000);
> + for (i = 0; i < ARRAY_SIZE(v2m_osc2_periphs); i++)
> + WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc2_periphs[i]));
> +}
> +
> +static void __init v2m_timer_init(void)
> +{
> + v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K));
> + v2m_clk_init();
> + if (ct_desc->init_clk)
> + ct_desc->init_clk();
> + v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
> +}
> +
> +static struct sys_timer v2m_timer = {
> + .init = v2m_timer_init,
> };
>
> static void __init v2m_init_early(void)
> {
> - ct_desc->init_early();
> - clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
> + if (ct_desc->init_early)
> + ct_desc->init_early();
> versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000);
> }
>
> @@ -528,77 +568,6 @@ void __init v2m_dt_map_io(void)
> #endif
> }
>
> -static struct clk_lookup v2m_dt_lookups[] = {
> - { /* AMBA bus clock */
> - .con_id = "apb_pclk",
> - .clk = &dummy_apb_pclk,
> - }, { /* SP804 timers */
> - .dev_id = "sp804",
> - .con_id = "v2m-timer0",
> - .clk = &v2m_sp804_clk,
> - }, { /* SP804 timers */
> - .dev_id = "sp804",
> - .con_id = "v2m-timer1",
> - .clk = &v2m_sp804_clk,
> - }, { /* PL180 MMCI */
> - .dev_id = "mb:mmci", /* 10005000.mmci */
> - .clk = &osc2_clk,
> - }, { /* PL050 KMI0 */
> - .dev_id = "10006000.kmi",
> - .clk = &osc2_clk,
> - }, { /* PL050 KMI1 */
> - .dev_id = "10007000.kmi",
> - .clk = &osc2_clk,
> - }, { /* PL011 UART0 */
> - .dev_id = "10009000.uart",
> - .clk = &osc2_clk,
> - }, { /* PL011 UART1 */
> - .dev_id = "1000a000.uart",
> - .clk = &osc2_clk,
> - }, { /* PL011 UART2 */
> - .dev_id = "1000b000.uart",
> - .clk = &osc2_clk,
> - }, { /* PL011 UART3 */
> - .dev_id = "1000c000.uart",
> - .clk = &osc2_clk,
> - }, { /* SP805 WDT */
> - .dev_id = "1000f000.wdt",
> - .clk = &v2m_ref_clk,
> - }, { /* PL111 CLCD */
> - .dev_id = "1001f000.clcd",
> - .clk = &osc1_clk,
> - },
> - /* RS1 memory map */
> - { /* PL180 MMCI */
> - .dev_id = "mb:mmci", /* 1c050000.mmci */
> - .clk = &osc2_clk,
> - }, { /* PL050 KMI0 */
> - .dev_id = "1c060000.kmi",
> - .clk = &osc2_clk,
> - }, { /* PL050 KMI1 */
> - .dev_id = "1c070000.kmi",
> - .clk = &osc2_clk,
> - }, { /* PL011 UART0 */
> - .dev_id = "1c090000.uart",
> - .clk = &osc2_clk,
> - }, { /* PL011 UART1 */
> - .dev_id = "1c0a0000.uart",
> - .clk = &osc2_clk,
> - }, { /* PL011 UART2 */
> - .dev_id = "1c0b0000.uart",
> - .clk = &osc2_clk,
> - }, { /* PL011 UART3 */
> - .dev_id = "1c0c0000.uart",
> - .clk = &osc2_clk,
> - }, { /* SP805 WDT */
> - .dev_id = "1c0f0000.wdt",
> - .clk = &v2m_ref_clk,
> - }, { /* PL111 CLCD */
> - .dev_id = "1c1f0000.clcd",
> - .clk = &osc1_clk,
> - },
> -};
> -
> void __init v2m_dt_init_early(void)
> {
> struct device_node *node;
> @@ -620,8 +589,6 @@ void __init v2m_dt_init_early(void)
> pr_warning("vexpress: DT HBI (%x) is not matching "
> "hardware (%x)!\n", dt_hbi, hbi);
> }
> -
> - clkdev_add_table(v2m_dt_lookups, ARRAY_SIZE(v2m_dt_lookups));
> }
>
> static struct of_device_id vexpress_irq_match[] __initdata = {
> @@ -643,6 +610,8 @@ static void __init v2m_dt_timer_init(void)
> node = of_find_compatible_node(NULL, NULL, "arm,sp810");
> v2m_sysctl_init(of_iomap(node, 0));
>
> + v2m_clk_init();
> +
> err = of_property_read_string(of_aliases, "arm,v2m_timer", &path);
> if (WARN_ON(err))
> return;
> diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig
> index 81ee7cc..4b9f4bf 100644
> --- a/arch/arm/plat-versatile/Kconfig
> +++ b/arch/arm/plat-versatile/Kconfig
> @@ -1,5 +1,10 @@
> if PLAT_VERSATILE
>
> +config PLAT_VERSATILE_CLOCK
> + bool
> + default y
> + depends on !COMMON_CLK
> +
> config PLAT_VERSATILE_CLCD
> bool
>
> diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
> index a5cb194..272769a8 100644
> --- a/arch/arm/plat-versatile/Makefile
> +++ b/arch/arm/plat-versatile/Makefile
> @@ -1,4 +1,4 @@
> -obj-y := clock.o
> +obj-$(CONFIG_PLAT_VERSATILE_CLOCK) += clock.o
> obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
> obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
> obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2012-06-13 10:07 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-08 12:50 [PATCH 1/2] ARM: vexpress: Check master site in daughterboard's sysctl operations Pawel Moll
2012-06-08 12:50 ` [PATCH 2/2] ARM: vexpress: Initial common clock support Pawel Moll
2012-06-13 10:07 ` Jon Medhurst (Tixy)
2012-06-12 8:58 ` [PATCH 1/2] ARM: vexpress: Check master site in daughterboard's sysctl operations Jon Medhurst (Tixy)
2012-06-12 9:08 ` Pawel Moll
2012-06-12 13:02 ` Jon Medhurst (Tixy)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).