From c1120542b99a67a620cd8a298975d76dca5a13f0 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 18 Dec 2013 17:18:48 +0100 Subject: [PATCH] microblaze: Add support for CCF Add support for CCF for Microblaze. Old binding: system_timer: system-timer@41c00000 { clock-frequency = <75000000>; ... } New binding: system_timer: system-timer@41c00000 { clocks = <&clk_bus>; ... } Both should be supported for a while Microblaze clock binding: clocks { #address-cells = <1>; #size-cells = <0>; clk_bus: bus { #clock-cells = <0>; clock-frequency = <75000000>; clock-output-names = "bus"; compatible = "fixed-clock"; reg = <1>; } ; clk_cpu: cpu { #clock-cells = <0>; clock-frequency = <75000000>; clock-output-names = "cpu"; compatible = "fixed-clock"; reg = <0>; } ; } ; Signed-off-by: Michal Simek --- arch/microblaze/Kconfig | 1 + arch/microblaze/include/asm/cpuinfo.h | 1 + arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c | 3 --- arch/microblaze/kernel/cpu/cpuinfo-static.c | 2 -- arch/microblaze/kernel/cpu/cpuinfo.c | 23 +++++++++++++++++-- arch/microblaze/kernel/setup.c | 3 +++ arch/microblaze/kernel/timer.c | 18 +++++++++++---- 7 files changed, 40 insertions(+), 11 deletions(-) diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index e23cccde9c27..a715eeaf9959 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -26,6 +26,7 @@ config MICROBLAZE select GENERIC_CPU_DEVICES select GENERIC_ATOMIC64 select GENERIC_CLOCKEVENTS + select COMMON_CLK select GENERIC_IDLE_POLL_SETUP select MODULES_USE_ELF_RELA select CLONE_BACKWARDS3 diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h index 7161fb575861..3337417fcdca 100644 --- a/arch/microblaze/include/asm/cpuinfo.h +++ b/arch/microblaze/include/asm/cpuinfo.h @@ -91,6 +91,7 @@ extern struct cpuinfo cpuinfo; /* fwd declarations of the various CPUinfo populators */ void setup_cpuinfo(void); +void setup_cpuinfo_clk(void); void set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu); void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu); diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c index ee4689415410..93c26cf50de5 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c +++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c @@ -112,7 +112,4 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu) CI(num_wr_brk, NUMBER_OF_WR_ADDR_BRK); CI(fpga_family_code, TARGET_FAMILY); - - /* take timebase-frequency from DTS */ - ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency"); } diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c index 592bb2e838c4..4854285b26e7 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo-static.c +++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c @@ -113,8 +113,6 @@ void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu) ci->num_rd_brk = fcpu(cpu, "xlnx,number-of-rd-addr-brk"); ci->num_wr_brk = fcpu(cpu, "xlnx,number-of-wr-addr-brk"); - ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency"); - ci->pvr_user1 = fcpu(cpu, "xlnx,pvr-user1"); ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2"); diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c index c9203b1007aa..ce1cfed731ea 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo.c +++ b/arch/microblaze/kernel/cpu/cpuinfo.c @@ -8,6 +8,7 @@ * for more details. */ +#include #include #include #include @@ -68,11 +69,10 @@ const struct family_string_key family_string_lookup[] = { }; struct cpuinfo cpuinfo; +static struct device_node *cpu; void __init setup_cpuinfo(void) { - struct device_node *cpu = NULL; - cpu = (struct device_node *) of_find_node_by_type(NULL, "cpu"); if (!cpu) pr_err("You don't have cpu!!!\n"); @@ -102,3 +102,22 @@ void __init setup_cpuinfo(void) pr_warn("%s: Stream instructions enabled" " - USERSPACE CAN LOCK THIS KERNEL!\n", __func__); } + +void __init setup_cpuinfo_clk(void) +{ + struct clk *clk; + + clk = of_clk_get(cpu, 0); + if (IS_ERR(clk)) { + pr_err("ERROR: CPU CCF input clock not found\n"); + /* take timebase-frequency from DTS */ + cpuinfo.cpu_clock_freq = fcpu(cpu, "timebase-frequency"); + } else { + cpuinfo.cpu_clock_freq = clk_get_rate(clk); + } + + if (!cpuinfo.cpu_clock_freq) { + pr_err("ERROR: CPU clock frequency not setup\n"); + BUG(); + } +} diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 603e22fec6d5..9d972d2bd924 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -195,6 +196,8 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, void __init time_init(void) { + of_clk_init(NULL); + setup_cpuinfo_clk(); clocksource_of_init(); } diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 3e39b1082fdf..55b19400951f 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -230,9 +230,9 @@ static int timer_initialized; static void __init xilinx_timer_init(struct device_node *timer) { + struct clk *clk; u32 irq; u32 timer_num = 1; - int ret; timer_baseaddr = of_iomap(timer, 0); if (!timer_baseaddr) { @@ -250,10 +250,20 @@ static void __init xilinx_timer_init(struct device_node *timer) pr_info("%s: irq=%d\n", timer->full_name, irq); - /* If there is clock-frequency property than use it */ - ret = of_property_read_u32(timer, "clock-frequency", &timer_clock_freq); - if (ret < 0) + clk = of_clk_get(timer, 0); + if (IS_ERR(clk)) { + pr_err("ERROR: timer CCF input clock not found\n"); + /* If there is clock-frequency property than use it */ + of_property_read_u32(timer, "clock-frequency", + &timer_clock_freq); + } else { + timer_clock_freq = clk_get_rate(clk); + } + + if (!timer_clock_freq) { + pr_err("ERROR: Using CPU clock frequency\n"); timer_clock_freq = cpuinfo.cpu_clock_freq; + } freq_div_hz = timer_clock_freq / HZ; -- 2.20.1