From 2f3edfd7e27ad4206acbc2ae99c9df5f46353024 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 26 Mar 2013 16:46:07 +0800 Subject: ARM: imx: fix sync issue between imx_cpu_die and imx_cpu_kill There is a sync issue with hotplug operation. It's possible that when imx_cpu_kill gets running on primary core, the imx_cpu_die execution on the core which is to be killed hasn't been finished yet. The problem will very likely be hit when running suspend without no_console_suspend setting on kernel cmdline. It uses cpu jumping argument register to sync imx_cpu_die and imx_cpu_kill. The register will be set in imx_cpu_die and imx_cpu_kill will wait for the register being cleared to actually kill the cpu. Signed-off-by: Shawn Guo Cc: --- arch/arm/mach-imx/common.h | 2 ++ arch/arm/mach-imx/hotplug.c | 12 ++++++++++++ arch/arm/mach-imx/src.c | 12 ++++++++++++ 3 files changed, 26 insertions(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 5a800bf..5bf4a97 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -110,6 +110,8 @@ void tzic_handle_irq(struct pt_regs *); extern void imx_enable_cpu(int cpu, bool enable); extern void imx_set_cpu_jump(int cpu, void *jump_addr); +extern u32 imx_get_cpu_arg(int cpu); +extern void imx_set_cpu_arg(int cpu, u32 arg); extern void v7_cpu_resume(void); extern u32 *pl310_get_save_ptr(void); #ifdef CONFIG_SMP diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c index 7bc5fe1..361a253 100644 --- a/arch/arm/mach-imx/hotplug.c +++ b/arch/arm/mach-imx/hotplug.c @@ -46,11 +46,23 @@ static inline void cpu_enter_lowpower(void) void imx_cpu_die(unsigned int cpu) { cpu_enter_lowpower(); + /* + * We use the cpu jumping argument register to sync with + * imx_cpu_kill() which is running on cpu0 and waiting for + * the register being cleared to kill the cpu. + */ + imx_set_cpu_arg(cpu, ~0); cpu_do_idle(); } int imx_cpu_kill(unsigned int cpu) { + unsigned long timeout = jiffies + msecs_to_jiffies(50); + + while (imx_get_cpu_arg(cpu) == 0) + if (time_after(jiffies, timeout)) + return 0; imx_enable_cpu(cpu, false); + imx_set_cpu_arg(cpu, 0); return 1; } diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index e15f155..09a742f 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c @@ -43,6 +43,18 @@ void imx_set_cpu_jump(int cpu, void *jump_addr) src_base + SRC_GPR1 + cpu * 8); } +u32 imx_get_cpu_arg(int cpu) +{ + cpu = cpu_logical_map(cpu); + return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4); +} + +void imx_set_cpu_arg(int cpu, u32 arg) +{ + cpu = cpu_logical_map(cpu); + writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); +} + void imx_src_prepare_restart(void) { u32 val; -- cgit v1.1 From 4e33a0634c051aff538f2daae81eff4b3e191d4a Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 13 Mar 2013 13:25:43 +0800 Subject: ARM: imx: remove duplicated function declaration Commit 13eed98 (arm/imx6q: add device tree machine support) added duplicated function declaration for imx_enable_cpu() and imx_set_cpu_jump(). Remove them. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/common.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 5a800bf..048e6c8 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -122,8 +122,6 @@ static inline void imx_scu_map_io(void) {} static inline void imx_smp_prepare(void) {} static inline void imx_scu_standby_enable(void) {} #endif -extern void imx_enable_cpu(int cpu, bool enable); -extern void imx_set_cpu_jump(int cpu, void *jump_addr); extern void imx_src_init(void); extern void imx_src_prepare_restart(void); extern void imx_gpc_init(void); -- cgit v1.1 From fda7f2267ded7e892b07466eaf7173633ccb17ad Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 13 Mar 2013 13:29:35 +0800 Subject: ARM: imx: remove pl310_get_save_ptr() declaration Commit a1f1c7e (arm/imx6q: add suspend/resume support) added declaration for a non-existing function pl310_get_save_ptr() by mistake. Remove it. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/common.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 048e6c8..d4b2f36 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -111,7 +111,6 @@ void tzic_handle_irq(struct pt_regs *); extern void imx_enable_cpu(int cpu, bool enable); extern void imx_set_cpu_jump(int cpu, void *jump_addr); extern void v7_cpu_resume(void); -extern u32 *pl310_get_save_ptr(void); #ifdef CONFIG_SMP extern void v7_secondary_startup(void); extern void imx_scu_map_io(void); -- cgit v1.1 From 180cb7d6ab8cb2a48f11fe2bdde85aa3ab359c3a Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Wed, 27 Mar 2013 14:01:34 +0100 Subject: ARM: imx: Remove cpufreq driver The old cpufreq driver is not necessary anymore with DT and cpufreq-cpu0. Signed-off-by: Markus Pargmann Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Makefile | 3 +- arch/arm/mach-imx/cpu_op-mx51.c | 31 ----- arch/arm/mach-imx/cpu_op-mx51.h | 14 --- arch/arm/mach-imx/cpufreq.c | 206 ---------------------------------- arch/arm/mach-imx/mach-cpuimx51sd.c | 5 - arch/arm/mach-imx/mach-mx51_babbage.c | 4 - 6 files changed, 1 insertion(+), 262 deletions(-) delete mode 100644 arch/arm/mach-imx/cpu_op-mx51.c delete mode 100644 arch/arm/mach-imx/cpu_op-mx51.h delete mode 100644 arch/arm/mach-imx/cpufreq.c (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index c4ce090..23555b0 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -12,7 +12,7 @@ obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci- obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o imx5-pm-$(CONFIG_PM) += pm-imx5.o -obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o $(imx5-pm-y) cpu_op-mx51.o +obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o $(imx5-pm-y) obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ clk-pfd.o clk-busy.o clk.o @@ -27,7 +27,6 @@ obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o obj-$(CONFIG_MXC_ULPI) += ulpi.o obj-$(CONFIG_MXC_USE_EPIT) += epit.o obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o -obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o ifeq ($(CONFIG_CPU_IDLE),y) obj-y += cpuidle.o diff --git a/arch/arm/mach-imx/cpu_op-mx51.c b/arch/arm/mach-imx/cpu_op-mx51.c deleted file mode 100644 index b9ef692..0000000 --- a/arch/arm/mach-imx/cpu_op-mx51.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include -#include -#include - -#include "hardware.h" - -static struct cpu_op mx51_cpu_op[] = { - { - .cpu_rate = 160000000,}, - { - .cpu_rate = 800000000,}, -}; - -struct cpu_op *mx51_get_cpu_op(int *op) -{ - *op = ARRAY_SIZE(mx51_cpu_op); - return mx51_cpu_op; -} diff --git a/arch/arm/mach-imx/cpu_op-mx51.h b/arch/arm/mach-imx/cpu_op-mx51.h deleted file mode 100644 index 97477fe..0000000 --- a/arch/arm/mach-imx/cpu_op-mx51.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -extern struct cpu_op *mx51_get_cpu_op(int *op); diff --git a/arch/arm/mach-imx/cpufreq.c b/arch/arm/mach-imx/cpufreq.c deleted file mode 100644 index d8c75c3..0000000 --- a/arch/arm/mach-imx/cpufreq.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -/* - * A driver for the Freescale Semiconductor i.MXC CPUfreq module. - * The CPUFREQ driver is for controlling CPU frequency. It allows you to change - * the CPU clock speed on the fly. - */ - -#include -#include -#include -#include -#include - -#include "hardware.h" - -#define CLK32_FREQ 32768 -#define NANOSECOND (1000 * 1000 * 1000) - -struct cpu_op *(*get_cpu_op)(int *op); - -static int cpu_freq_khz_min; -static int cpu_freq_khz_max; - -static struct clk *cpu_clk; -static struct cpufreq_frequency_table *imx_freq_table; - -static int cpu_op_nr; -static struct cpu_op *cpu_op_tbl; - -static int set_cpu_freq(int freq) -{ - int ret = 0; - int org_cpu_rate; - - org_cpu_rate = clk_get_rate(cpu_clk); - if (org_cpu_rate == freq) - return ret; - - ret = clk_set_rate(cpu_clk, freq); - if (ret != 0) { - printk(KERN_DEBUG "cannot set CPU clock rate\n"); - return ret; - } - - return ret; -} - -static int mxc_verify_speed(struct cpufreq_policy *policy) -{ - if (policy->cpu != 0) - return -EINVAL; - - return cpufreq_frequency_table_verify(policy, imx_freq_table); -} - -static unsigned int mxc_get_speed(unsigned int cpu) -{ - if (cpu) - return 0; - - return clk_get_rate(cpu_clk) / 1000; -} - -static int mxc_set_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) -{ - struct cpufreq_freqs freqs; - int freq_Hz; - int ret = 0; - unsigned int index; - - cpufreq_frequency_table_target(policy, imx_freq_table, - target_freq, relation, &index); - freq_Hz = imx_freq_table[index].frequency * 1000; - - freqs.old = clk_get_rate(cpu_clk) / 1000; - freqs.new = freq_Hz / 1000; - freqs.cpu = 0; - freqs.flags = 0; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - ret = set_cpu_freq(freq_Hz); - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - return ret; -} - -static int mxc_cpufreq_init(struct cpufreq_policy *policy) -{ - int ret; - int i; - - printk(KERN_INFO "i.MXC CPU frequency driver\n"); - - if (policy->cpu != 0) - return -EINVAL; - - if (!get_cpu_op) - return -EINVAL; - - cpu_clk = clk_get(NULL, "cpu_clk"); - if (IS_ERR(cpu_clk)) { - printk(KERN_ERR "%s: failed to get cpu clock\n", __func__); - return PTR_ERR(cpu_clk); - } - - cpu_op_tbl = get_cpu_op(&cpu_op_nr); - - cpu_freq_khz_min = cpu_op_tbl[0].cpu_rate / 1000; - cpu_freq_khz_max = cpu_op_tbl[0].cpu_rate / 1000; - - imx_freq_table = kmalloc( - sizeof(struct cpufreq_frequency_table) * (cpu_op_nr + 1), - GFP_KERNEL); - if (!imx_freq_table) { - ret = -ENOMEM; - goto err1; - } - - for (i = 0; i < cpu_op_nr; i++) { - imx_freq_table[i].index = i; - imx_freq_table[i].frequency = cpu_op_tbl[i].cpu_rate / 1000; - - if ((cpu_op_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min) - cpu_freq_khz_min = cpu_op_tbl[i].cpu_rate / 1000; - - if ((cpu_op_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max) - cpu_freq_khz_max = cpu_op_tbl[i].cpu_rate / 1000; - } - - imx_freq_table[i].index = i; - imx_freq_table[i].frequency = CPUFREQ_TABLE_END; - - policy->cur = clk_get_rate(cpu_clk) / 1000; - policy->min = policy->cpuinfo.min_freq = cpu_freq_khz_min; - policy->max = policy->cpuinfo.max_freq = cpu_freq_khz_max; - - /* Manual states, that PLL stabilizes in two CLK32 periods */ - policy->cpuinfo.transition_latency = 2 * NANOSECOND / CLK32_FREQ; - - ret = cpufreq_frequency_table_cpuinfo(policy, imx_freq_table); - - if (ret < 0) { - printk(KERN_ERR "%s: failed to register i.MXC CPUfreq with error code %d\n", - __func__, ret); - goto err; - } - - cpufreq_frequency_table_get_attr(imx_freq_table, policy->cpu); - return 0; -err: - kfree(imx_freq_table); -err1: - clk_put(cpu_clk); - return ret; -} - -static int mxc_cpufreq_exit(struct cpufreq_policy *policy) -{ - cpufreq_frequency_table_put_attr(policy->cpu); - - set_cpu_freq(cpu_freq_khz_max * 1000); - clk_put(cpu_clk); - kfree(imx_freq_table); - return 0; -} - -static struct cpufreq_driver mxc_driver = { - .flags = CPUFREQ_STICKY, - .verify = mxc_verify_speed, - .target = mxc_set_target, - .get = mxc_get_speed, - .init = mxc_cpufreq_init, - .exit = mxc_cpufreq_exit, - .name = "imx", -}; - -static int mxc_cpufreq_driver_init(void) -{ - return cpufreq_register_driver(&mxc_driver); -} - -static void mxc_cpufreq_driver_exit(void) -{ - cpufreq_unregister_driver(&mxc_driver); -} - -module_init(mxc_cpufreq_driver_init); -module_exit(mxc_cpufreq_driver_exit); - -MODULE_AUTHOR("Freescale Semiconductor Inc. Yong Shen "); -MODULE_DESCRIPTION("CPUfreq driver for i.MX"); -MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-imx/mach-cpuimx51sd.c b/arch/arm/mach-imx/mach-cpuimx51sd.c index 9b73932..9b5ddf5 100644 --- a/arch/arm/mach-imx/mach-cpuimx51sd.c +++ b/arch/arm/mach-imx/mach-cpuimx51sd.c @@ -33,7 +33,6 @@ #include "common.h" #include "devices-imx51.h" -#include "cpu_op-mx51.h" #include "eukrea-baseboards.h" #include "hardware.h" #include "iomux-mx51.h" @@ -285,10 +284,6 @@ static void __init eukrea_cpuimx51sd_init(void) mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads, ARRAY_SIZE(eukrea_cpuimx51sd_pads)); -#if defined(CONFIG_CPU_FREQ_IMX) - get_cpu_op = mx51_get_cpu_op; -#endif - imx51_add_imx_uart(0, &uart_pdata); imx51_add_mxc_nand(&eukrea_cpuimx51sd_nand_board_info); imx51_add_imx2_wdt(0); diff --git a/arch/arm/mach-imx/mach-mx51_babbage.c b/arch/arm/mach-imx/mach-mx51_babbage.c index 6c4d7fe..f3d264a 100644 --- a/arch/arm/mach-imx/mach-mx51_babbage.c +++ b/arch/arm/mach-imx/mach-mx51_babbage.c @@ -27,7 +27,6 @@ #include "common.h" #include "devices-imx51.h" -#include "cpu_op-mx51.h" #include "hardware.h" #include "iomux-mx51.h" @@ -371,9 +370,6 @@ static void __init mx51_babbage_init(void) imx51_soc_init(); -#if defined(CONFIG_CPU_FREQ_IMX) - get_cpu_op = mx51_get_cpu_op; -#endif imx51_babbage_common_init(); imx51_add_imx_uart(0, &uart_pdata); -- cgit v1.1 From 5fe839d997f955e9e62b70d798d3faaa19620383 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 5 Feb 2013 15:36:16 -0200 Subject: ARM: imx: avic: Move avic_saved_mask_reg under CONFIG_PM When building a kernel with CONFIG_PM undefined, the following warning happens: arch/arm/mach-imx/avic.c:57:12: warning: 'avic_saved_mask_reg' defined but not used [-Wunused-variable] Move avic_saved_mask_reg definition inside the '#ifdef CONFIG_PM' block to avoid the warning. Signed-off-by: Fabio Estevam Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/avic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c index 0eff23e..49c87e7 100644 --- a/arch/arm/mach-imx/avic.c +++ b/arch/arm/mach-imx/avic.c @@ -54,8 +54,6 @@ void __iomem *avic_base; static struct irq_domain *domain; -static u32 avic_saved_mask_reg[2]; - #ifdef CONFIG_MXC_IRQ_PRIOR static int avic_irq_set_priority(unsigned char irq, unsigned char prio) { @@ -113,6 +111,8 @@ static struct mxc_extra_irq avic_extra_irq = { }; #ifdef CONFIG_PM +static u32 avic_saved_mask_reg[2]; + static void avic_irq_suspend(struct irq_data *d) { struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); -- cgit v1.1 From 9591b8204b9fb9dab616e5e525d4d7676c4982f2 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 29 Jan 2013 10:17:35 -0200 Subject: ARM: imx: clk-imx27: Do not register peripheral clock for SSI imx ssi block has two types of clocks: - ipg: bus clock, the clock needed for accessing registers. - per: peripheral clock, the clock needed for generating the bit rate. Currently ssi driver only supports slave mode and thus need only to handle the ipg clock, because the peripheral clock comes from the master codec. Only register the ipg clock and do not register the peripheral clock for ssi Signed-off-by: Fabio Estevam Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx27.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c index 30b3242..8e3b657 100644 --- a/arch/arm/mach-imx/clk-imx27.c +++ b/arch/arm/mach-imx/clk-imx27.c @@ -278,8 +278,6 @@ int __init mx27_clocks_init(unsigned long fref) clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL); clk_register_clkdev(clk[cpu_div], "cpu", NULL); clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL); - clk_register_clkdev(clk[ssi1_baud_gate], "bitrate" , "imx-ssi.0"); - clk_register_clkdev(clk[ssi2_baud_gate], "bitrate" , "imx-ssi.1"); mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1); -- cgit v1.1 From 585b9f0bfdbdb4e41993f52f470eef7f093de0a2 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 2 Apr 2013 21:51:27 +0800 Subject: ARM: imx: remove Makefile.boot Since we have converted IMX to multiplatform build, Makefile.boot is not used anyway. Remove it. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Makefile.boot | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 arch/arm/mach-imx/Makefile.boot (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot deleted file mode 100644 index 41ba1bb..0000000 --- a/arch/arm/mach-imx/Makefile.boot +++ /dev/null @@ -1,35 +0,0 @@ -zreladdr-$(CONFIG_SOC_IMX1) += 0x08008000 -params_phys-$(CONFIG_SOC_IMX1) := 0x08000100 -initrd_phys-$(CONFIG_SOC_IMX1) := 0x08800000 - -zreladdr-$(CONFIG_SOC_IMX21) += 0xC0008000 -params_phys-$(CONFIG_SOC_IMX21) := 0xC0000100 -initrd_phys-$(CONFIG_SOC_IMX21) := 0xC0800000 - -zreladdr-$(CONFIG_SOC_IMX25) += 0x80008000 -params_phys-$(CONFIG_SOC_IMX25) := 0x80000100 -initrd_phys-$(CONFIG_SOC_IMX25) := 0x80800000 - -zreladdr-$(CONFIG_SOC_IMX27) += 0xA0008000 -params_phys-$(CONFIG_SOC_IMX27) := 0xA0000100 -initrd_phys-$(CONFIG_SOC_IMX27) := 0xA0800000 - -zreladdr-$(CONFIG_SOC_IMX31) += 0x80008000 -params_phys-$(CONFIG_SOC_IMX31) := 0x80000100 -initrd_phys-$(CONFIG_SOC_IMX31) := 0x80800000 - -zreladdr-$(CONFIG_SOC_IMX35) += 0x80008000 -params_phys-$(CONFIG_SOC_IMX35) := 0x80000100 -initrd_phys-$(CONFIG_SOC_IMX35) := 0x80800000 - -zreladdr-$(CONFIG_SOC_IMX51) += 0x90008000 -params_phys-$(CONFIG_SOC_IMX51) := 0x90000100 -initrd_phys-$(CONFIG_SOC_IMX51) := 0x90800000 - -zreladdr-$(CONFIG_SOC_IMX53) += 0x70008000 -params_phys-$(CONFIG_SOC_IMX53) := 0x70000100 -initrd_phys-$(CONFIG_SOC_IMX53) := 0x70800000 - -zreladdr-$(CONFIG_SOC_IMX6Q) += 0x10008000 -params_phys-$(CONFIG_SOC_IMX6Q) := 0x10000100 -initrd_phys-$(CONFIG_SOC_IMX6Q) := 0x10800000 -- cgit v1.1 From 50dc3ef5365a8109a27084e62f2a17af02a06596 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 2 Apr 2013 22:06:01 +0800 Subject: ARM: imx: remove mx6q.h Those stuff defined in mx6q.h is used nowhere now. Remove the header. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/hardware.h | 1 - arch/arm/mach-imx/mx6q.h | 31 ------------------------------- 2 files changed, 32 deletions(-) delete mode 100644 arch/arm/mach-imx/mx6q.h (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/hardware.h b/arch/arm/mach-imx/hardware.h index 911e9b3..356131f 100644 --- a/arch/arm/mach-imx/hardware.h +++ b/arch/arm/mach-imx/hardware.h @@ -102,7 +102,6 @@ #include "mxc.h" -#include "mx6q.h" #include "mx51.h" #include "mx53.h" #include "mx3x.h" diff --git a/arch/arm/mach-imx/mx6q.h b/arch/arm/mach-imx/mx6q.h deleted file mode 100644 index 19d3f54..0000000 --- a/arch/arm/mach-imx/mx6q.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2011 Linaro Ltd. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#ifndef __MACH_MX6Q_H__ -#define __MACH_MX6Q_H__ - -#define MX6Q_IO_P2V(x) IMX_IO_P2V(x) -#define MX6Q_IO_ADDRESS(x) IOMEM(MX6Q_IO_P2V(x)) - -/* - * The following are the blocks that need to be statically mapped. - * For other blocks, the base address really should be retrieved from - * device tree. - */ -#define MX6Q_SCU_BASE_ADDR 0x00a00000 -#define MX6Q_SCU_SIZE 0x1000 -#define MX6Q_CCM_BASE_ADDR 0x020c4000 -#define MX6Q_CCM_SIZE 0x4000 -#define MX6Q_ANATOP_BASE_ADDR 0x020c8000 -#define MX6Q_ANATOP_SIZE 0x1000 - -#endif /* __MACH_MX6Q_H__ */ -- cgit v1.1 From cab1e0a36c9dd0b0671fb84197ed294513f5adc1 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Fri, 29 Mar 2013 16:20:09 +0100 Subject: ARM: clk-imx35: Bugfix iomux clock This patch enables iomuxc_gate clock. It is necessary to be able to reconfigure iomux pads. Without this clock enabled, the clk_disable_unused function will disable this clock and the iomux pads are not configurable anymore. This happens at every boot. After a reboot (watchdog system reset) the clock is not enabled again, so all iomux pad reconfigurations in boot code are without effect. The iomux pads should be always configurable, so this patch always enables it. Signed-off-by: Markus Pargmann Cc: stable@vger.kernel.org Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx35.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index e13a8fa..b95898a 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -265,6 +265,7 @@ int __init mx35_clocks_init(void) clk_prepare_enable(clk[iim_gate]); clk_prepare_enable(clk[emi_gate]); clk_prepare_enable(clk[max_gate]); + clk_prepare_enable(clk[iomuxc_gate]); /* * SCC is needed to boot via mmc after a watchdog reset. The clock code -- cgit v1.1 From 75498083e25e96932ad998ffdeadb17234c68d3a Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Fri, 29 Mar 2013 16:20:10 +0100 Subject: ARM: imx35 Bugfix admux clock The admux clock seems to be the audmux clock as tests show. audmux does not work without this clock enabled. Currently imx35 does not register a clock device for audmux. This patch adds this registration. imx-audmux driver already handles a clock device, so no changes are necessary there. Signed-off-by: Markus Pargmann Cc: stable@vger.kernel.org Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx35.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index b95898a..2193c83 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -257,6 +257,7 @@ int __init mx35_clocks_init(void) clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0"); clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); + clk_register_clkdev(clk[admux_gate], "audmux", NULL); clk_prepare_enable(clk[spba_gate]); clk_prepare_enable(clk[gpio1_gate]); -- cgit v1.1 From 2bb4b70b1dbb45f0c1a3ba98066e6635d8aa3fe0 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 3 Apr 2013 23:50:09 +0800 Subject: ARM: imx: provide twd clock lookup from device tree While booting from device tree, imx6q used to provide twd clock lookup by calling clk_register_clkdev() in clock driver. However, the commit bd60345 (ARM: use device tree to get smp_twd clock) forces DT boot to look up the clock from device tree. It causes the failure below when twd driver tries to get the clock, and hence kernel has to calibrate the local timer frequency. smp_twd: clock not found -2 ... Calibrating local timer... 396.13MHz. Fix the regression by providing twd clock lookup from device tree, and remove the unused twd clk_register_clkdev() call from clock driver. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 2f9ff93..22a3021 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -443,7 +443,6 @@ int __init mx6q_clocks_init(void) clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0"); clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); - clk_register_clkdev(clk[twd], NULL, "smp_twd"); clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL); clk_register_clkdev(clk[ahb], "ahb", NULL); clk_register_clkdev(clk[cko1], "cko1", NULL); -- cgit v1.1 From e8094b2c17126c7dfdeafa296f206a4a3b122d23 Mon Sep 17 00:00:00 2001 From: Dirk Behme Date: Thu, 4 Apr 2013 16:03:29 +0200 Subject: ARM i.MX6: Fix ldb_di clock selection According to the recent i.MX6 Quad technical reference manual, mode 0x4 (100b) of the CCM_CS2DCR register (address 0x020C402C) bits [11-9] and [14-12] select the PLL3 clock, and not the PLL3 PFD1 540M clock. In our code, the PLL3 root clock is named 'pll3_usb_otg', select this instead of the 540M clock. Signed-off-by: Dirk Behme Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 22a3021..d38e54f 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -115,7 +115,7 @@ static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m" static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; -static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_pfd1_540m", }; +static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", }; static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; -- cgit v1.1 From e27da53bae60247d87c29cf744fb92afce673d6a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 9 Apr 2013 08:58:22 +0200 Subject: ARM i.MX53: remove platform ahci support The i.MX53 ahci platform support is unused in mainline. To demotivate people using it just remove it from the tree. Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/devices/Kconfig | 4 - arch/arm/mach-imx/devices/Makefile | 1 - arch/arm/mach-imx/devices/devices-common.h | 10 -- arch/arm/mach-imx/devices/platform-ahci-imx.c | 157 -------------------------- 4 files changed, 172 deletions(-) delete mode 100644 arch/arm/mach-imx/devices/platform-ahci-imx.c (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/devices/Kconfig b/arch/arm/mach-imx/devices/Kconfig index 9b9ba1f..3dd2b1b 100644 --- a/arch/arm/mach-imx/devices/Kconfig +++ b/arch/arm/mach-imx/devices/Kconfig @@ -86,7 +86,3 @@ config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX config IMX_HAVE_PLATFORM_SPI_IMX bool - -config IMX_HAVE_PLATFORM_AHCI - bool - default y if ARCH_MX53 diff --git a/arch/arm/mach-imx/devices/Makefile b/arch/arm/mach-imx/devices/Makefile index 6acf37e..67416fb 100644 --- a/arch/arm/mach-imx/devices/Makefile +++ b/arch/arm/mach-imx/devices/Makefile @@ -29,5 +29,4 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RTC) += platform-mxc_rtc.o obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) += platform-ahci-imx.o obj-$(CONFIG_IMX_HAVE_PLATFORM_MX2_EMMA) += platform-mx2-emma.o diff --git a/arch/arm/mach-imx/devices/devices-common.h b/arch/arm/mach-imx/devices/devices-common.h index 9bd5777..453e20b 100644 --- a/arch/arm/mach-imx/devices/devices-common.h +++ b/arch/arm/mach-imx/devices/devices-common.h @@ -344,13 +344,3 @@ struct platform_device *imx_add_imx_dma(char *name, resource_size_t iobase, int irq, int irq_err); struct platform_device *imx_add_imx_sdma(char *name, resource_size_t iobase, int irq, struct sdma_platform_data *pdata); - -#include -struct imx_ahci_imx_data { - const char *devid; - resource_size_t iobase; - resource_size_t irq; -}; -struct platform_device *__init imx_add_ahci_imx( - const struct imx_ahci_imx_data *data, - const struct ahci_platform_data *pdata); diff --git a/arch/arm/mach-imx/devices/platform-ahci-imx.c b/arch/arm/mach-imx/devices/platform-ahci-imx.c deleted file mode 100644 index 3d87dd9..0000000 --- a/arch/arm/mach-imx/devices/platform-ahci-imx.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include -#include -#include - -#include "../hardware.h" -#include "devices-common.h" - -#define imx_ahci_imx_data_entry_single(soc, _devid) \ - { \ - .devid = _devid, \ - .iobase = soc ## _SATA_BASE_ADDR, \ - .irq = soc ## _INT_SATA, \ - } - -#ifdef CONFIG_SOC_IMX53 -const struct imx_ahci_imx_data imx53_ahci_imx_data __initconst = - imx_ahci_imx_data_entry_single(MX53, "imx53-ahci"); -#endif - -enum { - HOST_CAP = 0x00, - HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ - HOST_PORTS_IMPL = 0x0c, - HOST_TIMER1MS = 0xe0, /* Timer 1-ms */ -}; - -static struct clk *sata_clk, *sata_ref_clk; - -/* AHCI module Initialization, if return 0, initialization is successful. */ -static int imx_sata_init(struct device *dev, void __iomem *addr) -{ - u32 tmpdata; - int ret = 0; - struct clk *clk; - - sata_clk = clk_get(dev, "ahci"); - if (IS_ERR(sata_clk)) { - dev_err(dev, "no sata clock.\n"); - return PTR_ERR(sata_clk); - } - ret = clk_prepare_enable(sata_clk); - if (ret) { - dev_err(dev, "can't prepare/enable sata clock.\n"); - goto put_sata_clk; - } - - /* Get the AHCI SATA PHY CLK */ - sata_ref_clk = clk_get(dev, "ahci_phy"); - if (IS_ERR(sata_ref_clk)) { - dev_err(dev, "no sata ref clock.\n"); - ret = PTR_ERR(sata_ref_clk); - goto release_sata_clk; - } - ret = clk_prepare_enable(sata_ref_clk); - if (ret) { - dev_err(dev, "can't prepare/enable sata ref clock.\n"); - goto put_sata_ref_clk; - } - - /* Get the AHB clock rate, and configure the TIMER1MS reg later */ - clk = clk_get(dev, "ahci_dma"); - if (IS_ERR(clk)) { - dev_err(dev, "no dma clock.\n"); - ret = PTR_ERR(clk); - goto release_sata_ref_clk; - } - tmpdata = clk_get_rate(clk) / 1000; - clk_put(clk); - - writel(tmpdata, addr + HOST_TIMER1MS); - - tmpdata = readl(addr + HOST_CAP); - if (!(tmpdata & HOST_CAP_SSS)) { - tmpdata |= HOST_CAP_SSS; - writel(tmpdata, addr + HOST_CAP); - } - - if (!(readl(addr + HOST_PORTS_IMPL) & 0x1)) - writel((readl(addr + HOST_PORTS_IMPL) | 0x1), - addr + HOST_PORTS_IMPL); - - return 0; - -release_sata_ref_clk: - clk_disable_unprepare(sata_ref_clk); -put_sata_ref_clk: - clk_put(sata_ref_clk); -release_sata_clk: - clk_disable_unprepare(sata_clk); -put_sata_clk: - clk_put(sata_clk); - - return ret; -} - -static void imx_sata_exit(struct device *dev) -{ - clk_disable_unprepare(sata_ref_clk); - clk_put(sata_ref_clk); - - clk_disable_unprepare(sata_clk); - clk_put(sata_clk); - -} -struct platform_device *__init imx_add_ahci_imx( - const struct imx_ahci_imx_data *data, - const struct ahci_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - - return imx_add_platform_device_dmamask(data->devid, 0, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata), DMA_BIT_MASK(32)); -} - -struct platform_device *__init imx53_add_ahci_imx(void) -{ - struct ahci_platform_data pdata = { - .init = imx_sata_init, - .exit = imx_sata_exit, - }; - - return imx_add_ahci_imx(&imx53_ahci_imx_data, &pdata); -} -- cgit v1.1 From 3442a7b51d1cfae144f3289ab0be44e27c236f53 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 9 Apr 2013 08:58:23 +0200 Subject: ARM: i.MX: remove unused ARCH_* configs This removes the unused Kconfig options ARCH_MX5, ARCH_MX51, ARCH_MX53 and MACH_MX21. Signed-off-by: Paul Bolle Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 4c9c6f9..6575e4e 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -83,24 +83,12 @@ config ARCH_MXC_IOMUX_V3 config ARCH_MX1 bool -config MACH_MX21 - bool - config ARCH_MX25 bool config MACH_MX27 bool -config ARCH_MX5 - bool - -config ARCH_MX51 - bool - -config ARCH_MX53 - bool - config SOC_IMX1 bool select ARCH_MX1 @@ -114,7 +102,6 @@ config SOC_IMX21 select COMMON_CLK select CPU_ARM926T select IMX_HAVE_IOMUX_V1 - select MACH_MX21 select MXC_AVIC config SOC_IMX25 @@ -155,7 +142,6 @@ config SOC_IMX35 config SOC_IMX5 bool select ARCH_HAS_CPUFREQ - select ARCH_MX5 select ARCH_MXC_IOMUX_V3 select COMMON_CLK select CPU_V7 @@ -163,8 +149,6 @@ config SOC_IMX5 config SOC_IMX51 bool - select ARCH_MX5 - select ARCH_MX51 select PINCTRL select PINCTRL_IMX51 select SOC_IMX5 @@ -789,8 +773,6 @@ comment "Device tree only" config SOC_IMX53 bool "i.MX53 support" - select ARCH_MX5 - select ARCH_MX53 select HAVE_CAN_FLEXCAN if CAN select IMX_HAVE_PLATFORM_IMX2_WDT select PINCTRL -- cgit v1.1 From e95dddb34c896f33e89f97365491e7932f89a0c0 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 20 Mar 2013 19:39:42 -0400 Subject: ARM: imx: enable anatop suspend/resume Anatop module have sereval configurations for user to reduce the power consumption in suspend, provide suspend/resume interface for further use and enable fet_odrive to reduce CORE LDO leakage during suspend. As we have a common anatop file, remove all the operations of anatop module in other files, use anatop interfaces to do that. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 4 +++ arch/arm/mach-imx/Makefile | 1 + arch/arm/mach-imx/anatop.c | 74 ++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/common.h | 7 +++- arch/arm/mach-imx/mach-imx6q.c | 48 ++++----------------------- arch/arm/mach-imx/pm-imx6q.c | 4 ++- 6 files changed, 94 insertions(+), 44 deletions(-) create mode 100644 arch/arm/mach-imx/anatop.c (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 6575e4e..f694074 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -65,6 +65,9 @@ config IRAM_ALLOC bool select GENERIC_ALLOCATOR +config HAVE_IMX_ANATOP + bool + config HAVE_IMX_GPC bool @@ -795,6 +798,7 @@ config SOC_IMX6Q select CPU_V7 select HAVE_ARM_SCU select HAVE_CAN_FLEXCAN if CAN + select HAVE_IMX_ANATOP select HAVE_IMX_GPC select HAVE_IMX_MMDC select HAVE_IMX_SRC diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 23555b0..b16eb39 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_MACH_EUKREA_CPUIMX35SD) += mach-cpuimx35.o obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o +obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o obj-$(CONFIG_HAVE_IMX_SRC) += src.o diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c new file mode 100644 index 0000000..b396b92 --- /dev/null +++ b/arch/arm/mach-imx/anatop.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2013 Freescale Semiconductor, Inc. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include + +#define REG_SET 0x4 +#define REG_CLR 0x8 + +#define ANADIG_REG_CORE 0x140 +#define ANADIG_USB1_CHRG_DETECT 0x1b0 +#define ANADIG_USB2_CHRG_DETECT 0x210 +#define ANADIG_DIGPROG 0x260 + +#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000 +#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000 +#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000 + +static struct regmap *anatop; + +static void imx_anatop_enable_fet_odrive(bool enable) +{ + regmap_write(anatop, ANADIG_REG_CORE + (enable ? REG_SET : REG_CLR), + BM_ANADIG_REG_CORE_FET_ODRIVE); +} + +void imx_anatop_pre_suspend(void) +{ + imx_anatop_enable_fet_odrive(true); +} + +void imx_anatop_post_resume(void) +{ + imx_anatop_enable_fet_odrive(false); +} + +void imx_anatop_usb_chrg_detect_disable(void) +{ + regmap_write(anatop, ANADIG_USB1_CHRG_DETECT, + BM_ANADIG_USB_CHRG_DETECT_EN_B + | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); + regmap_write(anatop, ANADIG_USB2_CHRG_DETECT, + BM_ANADIG_USB_CHRG_DETECT_EN_B | + BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); +} + +u32 imx_anatop_get_digprog(void) +{ + u32 val; + + regmap_read(anatop, ANADIG_DIGPROG, &val); + return val; +} + +void __init imx_anatop_init(void) +{ + anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop"); + if (IS_ERR(anatop)) { + pr_err("%s: failed to find imx6q-anatop regmap!\n", __func__); + return; + } +} diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 9fea252..d557bf3 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -128,6 +128,11 @@ extern void imx_src_prepare_restart(void); extern void imx_gpc_init(void); extern void imx_gpc_pre_suspend(void); extern void imx_gpc_post_resume(void); +extern void imx_anatop_init(void); +extern void imx_anatop_pre_suspend(void); +extern void imx_anatop_post_resume(void); +extern void imx_anatop_usb_chrg_detect_disable(void); +extern u32 imx_anatop_get_digprog(void); extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); extern void imx6q_set_chicken_bit(void); diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 9ffd103..31aee4d 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2013 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * * The code contained herein is licensed under the GNU General Public @@ -39,27 +39,12 @@ #include "cpuidle.h" #include "hardware.h" -#define IMX6Q_ANALOG_DIGPROG 0x260 - static int imx6q_revision(void) { - struct device_node *np; - void __iomem *base; static u32 rev; - if (!rev) { - np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); - if (!np) - return IMX_CHIP_REVISION_UNKNOWN; - base = of_iomap(np, 0); - if (!base) { - of_node_put(np); - return IMX_CHIP_REVISION_UNKNOWN; - } - rev = readl_relaxed(base + IMX6Q_ANALOG_DIGPROG); - iounmap(base); - of_node_put(np); - } + if (!rev) + rev = imx_anatop_get_digprog(); switch (rev & 0xff) { case 0: @@ -165,29 +150,7 @@ static void __init imx6q_1588_init(void) } static void __init imx6q_usb_init(void) { - struct regmap *anatop; - -#define HW_ANADIG_USB1_CHRG_DETECT 0x000001b0 -#define HW_ANADIG_USB2_CHRG_DETECT 0x00000210 - -#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x00100000 -#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x00080000 - - anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop"); - if (!IS_ERR(anatop)) { - /* - * The external charger detector needs to be disabled, - * or the signal at DP will be poor - */ - regmap_write(anatop, HW_ANADIG_USB1_CHRG_DETECT, - BM_ANADIG_USB_CHRG_DETECT_EN_B - | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); - regmap_write(anatop, HW_ANADIG_USB2_CHRG_DETECT, - BM_ANADIG_USB_CHRG_DETECT_EN_B | - BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); - } else { - pr_warn("failed to find fsl,imx6q-anatop regmap\n"); - } + imx_anatop_usb_chrg_detect_disable(); } static void __init imx6q_init_machine(void) @@ -197,9 +160,11 @@ static void __init imx6q_init_machine(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + imx_anatop_init(); imx6q_pm_init(); imx6q_usb_init(); imx6q_1588_init(); + imx_print_silicon_rev("i.MX6Q", imx6q_revision()); } #define OCOTP_CFG3 0x440 @@ -293,7 +258,6 @@ static void __init imx6q_timer_init(void) { mx6q_clocks_init(); twd_local_timer_of_register(); - imx_print_silicon_rev("i.MX6Q", imx6q_revision()); } static const char *imx6q_dt_compat[] __initdata = { diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c index 5faba7a..2049427 100644 --- a/arch/arm/mach-imx/pm-imx6q.c +++ b/arch/arm/mach-imx/pm-imx6q.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2013 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * * The code contained herein is licensed under the GNU General Public @@ -34,10 +34,12 @@ static int imx6q_pm_enter(suspend_state_t state) case PM_SUSPEND_MEM: imx6q_set_lpm(STOP_POWER_OFF); imx_gpc_pre_suspend(); + imx_anatop_pre_suspend(); imx_set_cpu_jump(0, v7_cpu_resume); /* Zzz ... */ cpu_suspend(0, imx6q_suspend_finish); imx_smp_prepare(); + imx_anatop_post_resume(); imx_gpc_post_resume(); imx6q_set_lpm(WAIT_CLOCKED); break; -- cgit v1.1 From e7b82d645d8b0345508d4b7be85e10f961fbfa3e Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 20 Mar 2013 19:39:43 -0400 Subject: ARM: imx: enable periphery well bias for suspend Enable periphery charge pump for well biasing at suspend to reduce periphery leakage. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index d38e54f..262b7b6 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2013 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * * The code contained herein is licensed under the GNU General Public @@ -23,6 +23,9 @@ #include "clk.h" #include "common.h" +#define CCR 0x0 +#define BM_CCR_WB_COUNT (0x7 << 16) + #define CCGR0 0x68 #define CCGR1 0x6c #define CCGR2 0x70 @@ -67,6 +70,29 @@ void imx6q_set_chicken_bit(void) writel_relaxed(val, ccm_base + CGPR); } +static void imx6q_enable_wb(bool enable) +{ + u32 val; + static bool last_wb_mode; + + if (last_wb_mode == enable) + return; + + /* configure well bias enable bit */ + val = readl_relaxed(ccm_base + CLPCR); + val &= ~BM_CLPCR_WB_PER_AT_LPM; + val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0; + writel_relaxed(val, ccm_base + CLPCR); + + /* configure well bias count */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_WB_COUNT; + val |= enable ? BM_CCR_WB_COUNT : 0; + writel_relaxed(val, ccm_base + CCR); + + last_wb_mode = enable; +} + int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) { u32 val = readl_relaxed(ccm_base + CLPCR); @@ -74,6 +100,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) val &= ~BM_CLPCR_LPM; switch (mode) { case WAIT_CLOCKED: + imx6q_enable_wb(false); break; case WAIT_UNCLOCKED: val |= 0x1 << BP_CLPCR_LPM; @@ -92,6 +119,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) val |= 0x3 << BP_CLPCR_STBY_COUNT; val |= BM_CLPCR_VSTBY; val |= BM_CLPCR_SBYOS; + imx6q_enable_wb(true); break; default: return -EINVAL; -- cgit v1.1 From 263475d4e0b0623fb7a22f8ac0a5c01017eabf20 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Thu, 21 Mar 2013 10:58:06 -0400 Subject: ARM: imx: enable RBC to support anatop LPM mode RBC is to control whether some ANATOP sub modules can enter lpm mode when SOC is into STOP mode, if RBC is enabled and PMIC_VSTBY_REQ is set, ANATOP will have below behaviors: 1. Digital LDOs(CORE, SOC and PU) are bypassed; 2. Analog LDOs(1P1, 2P5, 3P0) are disabled; As the 2P5 is necessary for DRAM IO pre-drive in STOP mode, so we need to enable weak 2P5 in STOP mode when 2P5 LDO is disabled. For RBC settings, there are some rules as below due to hardware design: 1. All interrupts must be masked during operating RBC registers; 2. At least 2 CKIL(32K) cycles is needed after the RBC setting is changed. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/anatop.c | 19 +++++++++++++++++++ arch/arm/mach-imx/clk-imx6q.c | 43 +++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/common.h | 2 ++ arch/arm/mach-imx/gpc.c | 23 ++++++++++++++++++++++- 4 files changed, 86 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index b396b92..8b18b3c 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -19,17 +19,34 @@ #define REG_SET 0x4 #define REG_CLR 0x8 +#define ANADIG_REG_2P5 0x130 #define ANADIG_REG_CORE 0x140 +#define ANADIG_ANA_MISC0 0x150 #define ANADIG_USB1_CHRG_DETECT 0x1b0 #define ANADIG_USB2_CHRG_DETECT 0x210 #define ANADIG_DIGPROG 0x260 +#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 #define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000 +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000 #define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000 #define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000 static struct regmap *anatop; +static void imx_anatop_enable_weak2p5(bool enable) +{ + u32 reg, val; + + regmap_read(anatop, ANADIG_ANA_MISC0, &val); + + /* can only be enabled when stop_mode_config is clear. */ + reg = ANADIG_REG_2P5; + reg += (enable && (val & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) ? + REG_SET : REG_CLR; + regmap_write(anatop, reg, BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG); +} + static void imx_anatop_enable_fet_odrive(bool enable) { regmap_write(anatop, ANADIG_REG_CORE + (enable ? REG_SET : REG_CLR), @@ -38,12 +55,14 @@ static void imx_anatop_enable_fet_odrive(bool enable) void imx_anatop_pre_suspend(void) { + imx_anatop_enable_weak2p5(true); imx_anatop_enable_fet_odrive(true); } void imx_anatop_post_resume(void) { imx_anatop_enable_fet_odrive(false); + imx_anatop_enable_weak2p5(false); } void imx_anatop_usb_chrg_detect_disable(void) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 262b7b6..23b799a 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,8 @@ #define CCR 0x0 #define BM_CCR_WB_COUNT (0x7 << 16) +#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21) +#define BM_CCR_RBC_EN (0x1 << 27) #define CCGR0 0x68 #define CCGR1 0x6c @@ -70,6 +73,44 @@ void imx6q_set_chicken_bit(void) writel_relaxed(val, ccm_base + CGPR); } +static void imx6q_enable_rbc(bool enable) +{ + u32 val; + static bool last_rbc_mode; + + if (last_rbc_mode == enable) + return; + /* + * need to mask all interrupts in GPC before + * operating RBC configurations + */ + imx_gpc_mask_all(); + + /* configure RBC enable bit */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_RBC_EN; + val |= enable ? BM_CCR_RBC_EN : 0; + writel_relaxed(val, ccm_base + CCR); + + /* configure RBC count */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_RBC_BYPASS_COUNT; + val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0; + writel(val, ccm_base + CCR); + + /* + * need to delay at least 2 cycles of CKIL(32K) + * due to hardware design requirement, which is + * ~61us, here we use 65us for safe + */ + udelay(65); + + /* restore GPC interrupt mask settings */ + imx_gpc_restore_all(); + + last_rbc_mode = enable; +} + static void imx6q_enable_wb(bool enable) { u32 val; @@ -101,6 +142,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) switch (mode) { case WAIT_CLOCKED: imx6q_enable_wb(false); + imx6q_enable_rbc(false); break; case WAIT_UNCLOCKED: val |= 0x1 << BP_CLPCR_LPM; @@ -120,6 +162,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) val |= BM_CLPCR_VSTBY; val |= BM_CLPCR_SBYOS; imx6q_enable_wb(true); + imx6q_enable_rbc(true); break; default: return -EINVAL; diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index d557bf3..bcb11b1 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -128,6 +128,8 @@ extern void imx_src_prepare_restart(void); extern void imx_gpc_init(void); extern void imx_gpc_pre_suspend(void); extern void imx_gpc_post_resume(void); +extern void imx_gpc_mask_all(void); +extern void imx_gpc_restore_all(void); extern void imx_anatop_init(void); extern void imx_anatop_pre_suspend(void); extern void imx_anatop_post_resume(void); diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index a96ccc7..c20445c 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2013 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * * The code contained herein is licensed under the GNU General Public @@ -68,6 +68,27 @@ static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on) return 0; } +void imx_gpc_mask_all(void) +{ + void __iomem *reg_imr1 = gpc_base + GPC_IMR1; + int i; + + for (i = 0; i < IMR_NUM; i++) { + gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4); + writel_relaxed(~0, reg_imr1 + i * 4); + } + +} + +void imx_gpc_restore_all(void) +{ + void __iomem *reg_imr1 = gpc_base + GPC_IMR1; + int i; + + for (i = 0; i < IMR_NUM; i++) + writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4); +} + static void imx_gpc_irq_unmask(struct irq_data *d) { void __iomem *reg; -- cgit v1.1 From fcc4f9fc5b23e6bb80f2c7833da323a485cad1b6 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 25 Mar 2013 09:20:41 -0300 Subject: ARM: mach-imx: anatop: Include "common.h" Fix the following sparse warnings: arch/arm/mach-imx/anatop.c:56:6: warning: symbol 'imx_anatop_pre_suspend' was not declared. Should it be static? arch/arm/mach-imx/anatop.c:62:6: warning: symbol 'imx_anatop_post_resume' was not declared. Should it be static? arch/arm/mach-imx/anatop.c:68:6: warning: symbol 'imx_anatop_usb_chrg_detect_disable' was not declared. Should it be static? arch/arm/mach-imx/anatop.c:78:5: warning: symbol 'imx_anatop_get_digprog' was not declared. Should it be static? arch/arm/mach-imx/anatop.c:86:13: warning: symbol 'imx_anatop_init' was not declared. Should it be static? Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/anatop.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 8b18b3c..472beee 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -15,6 +15,7 @@ #include #include #include +#include "common.h" #define REG_SET 0x4 #define REG_CLR 0x8 -- cgit v1.1 From 8ecb167f4978d86fa39d6a9c533a4c1ef3169c81 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 27 Mar 2013 10:51:33 +0100 Subject: ARM i.MX53: Add GPU clocks to clock tree This patch adds the missing GPU2D and GPU3D mux and gate clocks, and the graphics arbiter gate clock. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index 0f39f8c..fdd8657 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -47,6 +47,8 @@ static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", }; static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", }; static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", }; static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; +static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; +static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", }; @@ -83,7 +85,7 @@ enum imx5_clks { ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate, epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate, can_sel, can1_serial_gate, can1_ipg_gate, - owire_gate, + owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate, clk_max }; @@ -200,6 +202,11 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk[nfc_gate] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20); clk[ipu_di0_gate] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10); clk[ipu_di1_gate] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12); + clk[gpu3d_s] = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel)); + clk[gpu2d_s] = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel)); + clk[gpu3d_gate] = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2); + clk[garb_gate] = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4); + clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14); clk[vpu_s] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel)); clk[vpu_gate] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6); clk[vpu_reference_gate] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8); -- cgit v1.1 From 686631042325a209766be89b5566b426875ca05e Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Wed, 27 Mar 2013 14:01:31 +0100 Subject: ARM: imx27, imx5: Add kconfig selects for cpufreq-cpu0 There are some config options not selected by imx27 and imx5 that are necessary to use the cpufreq-cpu0 driver. Signed-off-by: Markus Pargmann Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index f694074..1ab069c 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -118,6 +118,8 @@ config SOC_IMX25 config SOC_IMX27 bool + select ARCH_HAS_CPUFREQ + select ARCH_HAS_OPP select COMMON_CLK select CPU_ARM926T select IMX_HAVE_IOMUX_V1 @@ -145,6 +147,7 @@ config SOC_IMX35 config SOC_IMX5 bool select ARCH_HAS_CPUFREQ + select ARCH_HAS_OPP select ARCH_MXC_IOMUX_V3 select COMMON_CLK select CPU_V7 -- cgit v1.1 From b1a3582dc6f1f85a56b60f688305a5194e266e02 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 27 Mar 2013 18:30:37 +0100 Subject: ARM i.MX6q: export imx6q_revision So it can be used in clk-imx6q.c for revision dependent clock tree setup. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/common.h | 1 + arch/arm/mach-imx/mach-imx6q.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index bcb11b1..4cba7db 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -74,6 +74,7 @@ extern void mxc_set_cpu_type(unsigned int type); extern void mxc_restart(char, const char *); extern void mxc_arch_reset_init(void __iomem *); extern int mx53_revision(void); +extern int imx6q_revision(void); extern int mx53_display_revision(void); extern void imx_set_aips(void __iomem *); extern int mxc_device_init(void); diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 31aee4d..0af330d 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -39,7 +39,7 @@ #include "cpuidle.h" #include "hardware.h" -static int imx6q_revision(void) +int imx6q_revision(void) { static u32 rev; -- cgit v1.1 From 3ce921702bea62fb1d4466939d4ea841a10d534e Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 27 Mar 2013 18:30:40 +0100 Subject: ARM i.MX: Add imx_clk_divider_flags and imx_clk_mux_flags The default is for dividers to set CLK_SET_PARENT_RATE and for muxes to not set that flag. In the LDB clock tree, we need the opposite, so add functions to create divider and mux clocks with configurable flags. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h index 9d1f3b9..d9d9d9c 100644 --- a/arch/arm/mach-imx/clk.h +++ b/arch/arm/mach-imx/clk.h @@ -59,6 +59,14 @@ static inline struct clk *imx_clk_divider(const char *name, const char *parent, reg, shift, width, 0, &imx_ccm_lock); } +static inline struct clk *imx_clk_divider_flags(const char *name, + const char *parent, void __iomem *reg, u8 shift, u8 width, + unsigned long flags) +{ + return clk_register_divider(NULL, name, parent, flags, + reg, shift, width, 0, &imx_ccm_lock); +} + static inline struct clk *imx_clk_gate(const char *name, const char *parent, void __iomem *reg, u8 shift) { @@ -73,6 +81,15 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg, width, 0, &imx_ccm_lock); } +static inline struct clk *imx_clk_mux_flags(const char *name, + void __iomem *reg, u8 shift, u8 width, const char **parents, + int num_parents, unsigned long flags) +{ + return clk_register_mux(NULL, name, parents, num_parents, + flags, reg, shift, width, 0, + &imx_ccm_lock); +} + static inline struct clk *imx_clk_fixed_factor(const char *name, const char *parent, unsigned int mult, unsigned int div) { -- cgit v1.1 From cc7b633909877c5e004e3feae19a11b4053eb157 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 27 Mar 2013 18:30:41 +0100 Subject: ARM i.MX53: fix ldb di divider and selector clocks Use imx_clk_mux_flags and imx_clk_divider_flags to set the appropriate flags for the LDB display interface divider and selector clocks. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index fdd8657..8a448c3 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -430,15 +430,15 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE); clk[pll4_sw] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE); - clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1, - mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel)); clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); - clk[ldb_di1_div] = imx_clk_divider("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1); + clk[ldb_di1_div] = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0); + clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1, + mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT); clk[di_pll4_podf] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3); - clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1, - mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel)); clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); - clk[ldb_di0_div] = imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1); + clk[ldb_di0_div] = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0); + clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1, + mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT); clk[ldb_di0_gate] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28); clk[ldb_di1_gate] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30); clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, -- cgit v1.1 From d19dacb732209ba25e2e1f912b74d9d64a608bb0 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 27 Mar 2013 18:30:42 +0100 Subject: ARM i.MX6q: fix ldb di divider and selector clocks Use imx_clk_mux_flags and imx_clk_divider_flags to set the appropriate flags for the LDB display interface divider and selector clocks. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 23b799a..47d0af1 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -354,8 +354,8 @@ int __init mx6q_clocks_init(void) clk[gpu3d_shader_sel] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); clk[ipu1_sel] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); - clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); - clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); + clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); + clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); clk[ipu1_di0_pre_sel] = imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); clk[ipu1_di1_pre_sel] = imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); clk[ipu2_di0_pre_sel] = imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); @@ -403,9 +403,9 @@ int __init mx6q_clocks_init(void) clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); - clk[ldb_di0_podf] = imx_clk_divider("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1); + clk[ldb_di0_podf] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0); clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); - clk[ldb_di1_podf] = imx_clk_divider("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1); + clk[ldb_di1_podf] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0); clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3); clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3); clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3); -- cgit v1.1 From 2df1d026edc11e88ad0a2216e79232737f5939e2 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 29 Mar 2013 19:29:02 +0800 Subject: ARM i.MX6q: Add audio/video PLL post dividers for i.MX6q rev 1.1 Query silicon revision to determine clock tree and add post dividers for newer revisions. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 47d0af1..2b230f8 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -23,6 +23,7 @@ #include "clk.h" #include "common.h" +#include "hardware.h" #define CCR 0x0 #define BM_CCR_WB_COUNT (0x7 << 16) @@ -180,29 +181,29 @@ static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", }; static const char *periph_sels[] = { "periph_pre", "periph_clk2", }; static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", }; -static const char *audio_sels[] = { "pll4_audio", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; +static const char *audio_sels[] = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; static const char *gpu_axi_sels[] = { "axi", "ahb", }; static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", }; static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", }; -static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; +static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", }; static const char *pcie_axi_sels[] = { "axi", "ahb", }; -static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio", }; +static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_post_div", }; static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", }; static const char *emi_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", }; static const char *vdo_axi_sels[] = { "axi", "ahb", }; static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", }; -static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video", +static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", - "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", }; + "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_post_div", }; enum mx6q_clks { dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m, @@ -236,7 +237,7 @@ enum mx6q_clks { pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg, ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5, sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate, - usbphy2_gate, clk_max + usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, clk_max }; static struct clk *clk[clk_max]; @@ -253,6 +254,21 @@ static struct clk_div_table clk_enet_ref_table[] = { { .val = 3, .div = 4, }, }; +static struct clk_div_table post_div_table[] = { + { .val = 2, .div = 1, }, + { .val = 1, .div = 2, }, + { .val = 0, .div = 4, }, + { } +}; + +static struct clk_div_table video_div_table[] = { + { .val = 0, .div = 1, }, + { .val = 1, .div = 2, }, + { .val = 2, .div = 1, }, + { .val = 3, .div = 4, }, + { } +}; + int __init mx6q_clocks_init(void) { struct device_node *np; @@ -279,6 +295,14 @@ int __init mx6q_clocks_init(void) base = of_iomap(np, 0); WARN_ON(!base); + /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */ + if (imx6q_revision() == IMX_CHIP_REVISION_1_0) { + post_div_table[1].div = 1; + post_div_table[2].div = 1; + video_div_table[1].div = 1; + video_div_table[2].div = 1; + }; + /* type name parent_name base div_mask */ clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f); clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1); @@ -331,6 +355,10 @@ int __init mx6q_clocks_init(void) clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2); + clk[pll4_post_div] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); + clk[pll5_post_div] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); + clk[pll5_video_div] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm"); base = of_iomap(np, 0); WARN_ON(!base); -- cgit v1.1 From 32f3b8da222b0817e0544acd888071aff674b629 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 28 Mar 2013 16:23:32 +0100 Subject: ARM i.MX6q: set the LDB serial clock parent to the video PLL On i.MX6q revision 1.1 and later, set the video PLL as parent for the LDB clock branch. On revision 1.0, the video PLL is useless due to missing dividers, so keep the default parent (mmdc_ch1_axi). Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 2b230f8..43dbcd6 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -547,6 +547,11 @@ int __init mx6q_clocks_init(void) clk_register_clkdev(clk[cko1], "cko1", NULL); clk_register_clkdev(clk[arm], NULL, "cpu0"); + if (imx6q_revision() != IMX_CHIP_REVISION_1_0) { + clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]); + clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]); + } + /* * The gpmi needs 100MHz frequency in the EDO/Sync mode, * We can not get the 100MHz from the pll2_pfd0_352m. -- cgit v1.1 From 7006ba24c26313631f21fff5a087c971f5c7d2ef Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sun, 31 Mar 2013 22:39:22 +0800 Subject: ARM: imx: do not use regmap_read for ANADIG_DIGPROG Function imx_anatop_get_digprog() that reads register ANADIG_DIGPROG is called to identify silicon version. Users might query silicon version earlier than regmap subsystem is ready. For example, imx6q clock driver query revision in mx6q_clocks_init(), where regmap is not initialized yet. Change imx_anatop_get_digprog() to map anatop block and read ANADIG_DIGPROG in the native way, so that the function can work at very early stage. While at it, let's move imx_print_silicon_rev() back to imx6q_timer_init() to have the message show up a little earlier. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/anatop.c | 15 ++++++++++++--- arch/arm/mach-imx/mach-imx6q.c | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 472beee..0cfa07d 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -78,10 +78,19 @@ void imx_anatop_usb_chrg_detect_disable(void) u32 imx_anatop_get_digprog(void) { - u32 val; + struct device_node *np; + void __iomem *anatop_base; + static u32 digprog; - regmap_read(anatop, ANADIG_DIGPROG, &val); - return val; + if (digprog) + return digprog; + + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); + anatop_base = of_iomap(np, 0); + WARN_ON(!anatop_base); + digprog = readl_relaxed(anatop_base + ANADIG_DIGPROG); + + return digprog; } void __init imx_anatop_init(void) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 0af330d..221f319 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -164,7 +164,6 @@ static void __init imx6q_init_machine(void) imx6q_pm_init(); imx6q_usb_init(); imx6q_1588_init(); - imx_print_silicon_rev("i.MX6Q", imx6q_revision()); } #define OCOTP_CFG3 0x440 @@ -258,6 +257,7 @@ static void __init imx6q_timer_init(void) { mx6q_clocks_init(); twd_local_timer_of_register(); + imx_print_silicon_rev("i.MX6Q", imx6q_revision()); } static const char *imx6q_dt_compat[] __initdata = { -- cgit v1.1 From 02985b94638b4de3ef9f2eb2ac5befe5bab12c26 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 28 Mar 2013 17:35:19 +0100 Subject: ARM i.MX6q: Add GPU, VPU, IPU, and OpenVG resets to System Reset Controller (SRC) The SRC has auto-deasserting reset bits that control reset lines to the GPU, VPU, IPU, and OpenVG IP modules. This patch adds a reset controller that can be controlled by those devices using the reset controller API. Signed-off-by: Philipp Zabel Reviewed-by: Stephen Warren Reviewed-by: Marek Vasut Reviewed-by: Pavel Machek Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 1 + arch/arm/mach-imx/src.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 1ab069c..5b676d4 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -76,6 +76,7 @@ config HAVE_IMX_MMDC config HAVE_IMX_SRC def_bool y if SMP + select ARCH_HAS_RESET_CONTROLLER config IMX_HAVE_IOMUX_V1 bool diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index 09a742f..dec6411 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c @@ -14,16 +14,72 @@ #include #include #include +#include #include #include #define SRC_SCR 0x000 #define SRC_GPR1 0x020 #define BP_SRC_SCR_WARM_RESET_ENABLE 0 +#define BP_SRC_SCR_SW_GPU_RST 1 +#define BP_SRC_SCR_SW_VPU_RST 2 +#define BP_SRC_SCR_SW_IPU1_RST 3 +#define BP_SRC_SCR_SW_OPEN_VG_RST 4 +#define BP_SRC_SCR_SW_IPU2_RST 12 #define BP_SRC_SCR_CORE1_RST 14 #define BP_SRC_SCR_CORE1_ENABLE 22 static void __iomem *src_base; +static DEFINE_SPINLOCK(scr_lock); + +static const int sw_reset_bits[5] = { + BP_SRC_SCR_SW_GPU_RST, + BP_SRC_SCR_SW_VPU_RST, + BP_SRC_SCR_SW_IPU1_RST, + BP_SRC_SCR_SW_OPEN_VG_RST, + BP_SRC_SCR_SW_IPU2_RST +}; + +static int imx_src_reset_module(struct reset_controller_dev *rcdev, + unsigned long sw_reset_idx) +{ + unsigned long timeout; + unsigned long flags; + int bit; + u32 val; + + if (!src_base) + return -ENODEV; + + if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits)) + return -EINVAL; + + bit = 1 << sw_reset_bits[sw_reset_idx]; + + spin_lock_irqsave(&scr_lock, flags); + val = readl_relaxed(src_base + SRC_SCR); + val |= bit; + writel_relaxed(val, src_base + SRC_SCR); + spin_unlock_irqrestore(&scr_lock, flags); + + timeout = jiffies + msecs_to_jiffies(1000); + while (readl(src_base + SRC_SCR) & bit) { + if (time_after(jiffies, timeout)) + return -ETIME; + cpu_relax(); + } + + return 0; +} + +static struct reset_control_ops imx_src_ops = { + .reset = imx_src_reset_module, +}; + +static struct reset_controller_dev imx_reset_controller = { + .ops = &imx_src_ops, + .nr_resets = ARRAY_SIZE(sw_reset_bits), +}; void imx_enable_cpu(int cpu, bool enable) { @@ -31,9 +87,11 @@ void imx_enable_cpu(int cpu, bool enable) cpu = cpu_logical_map(cpu); mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1); + spin_lock(&scr_lock); val = readl_relaxed(src_base + SRC_SCR); val = enable ? val | mask : val & ~mask; writel_relaxed(val, src_base + SRC_SCR); + spin_unlock(&scr_lock); } void imx_set_cpu_jump(int cpu, void *jump_addr) @@ -60,9 +118,11 @@ void imx_src_prepare_restart(void) u32 val; /* clear enable bits of secondary cores */ + spin_lock(&scr_lock); val = readl_relaxed(src_base + SRC_SCR); val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE); writel_relaxed(val, src_base + SRC_SCR); + spin_unlock(&scr_lock); /* clear persistent entry register of primary core */ writel_relaxed(0, src_base + SRC_GPR1); @@ -77,11 +137,16 @@ void __init imx_src_init(void) src_base = of_iomap(np, 0); WARN_ON(!src_base); + imx_reset_controller.of_node = np; + reset_controller_register(&imx_reset_controller); + /* * force warm reset sources to generate cold reset * for a more reliable restart */ + spin_lock(&scr_lock); val = readl_relaxed(src_base + SRC_SCR); val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE); writel_relaxed(val, src_base + SRC_SCR); + spin_unlock(&scr_lock); } -- cgit v1.1 From 04b41e84ff6a49e62c8a787b278af823e78354f4 Mon Sep 17 00:00:00 2001 From: Martin Fuzzey Date: Tue, 19 Mar 2013 17:57:01 +0100 Subject: ARM: i.MX53 Add the cko1, cko2 clock outputs. These two clocks connect to external pins and can be muxed to various internal clocks. They are typically used either for debugging or to provide clocks to external chips (eg audio codecs). Currently only the selectable clocks that already exist in the clock tree have been added. Signed-off-by: Martin Fuzzey Acked-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index 8a448c3..a163e0e 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -51,6 +51,28 @@ static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", }; +static const char *mx53_cko1_sel[] = { + "cpu_podf", "pll1_sw", "pll2_sw", "pll3_sw", + "emi_slow_podf", "pll4_sw", "nfc_podf", "dummy", + "di_pred", "dummy", "dummy", "ahb", + "ipg", "per_root", "ckil", "dummy",}; +static const char *mx53_cko2_sel[] = { + "dummy"/* dptc_core */, "dummy"/* dptc_perich */, + "dummy", "esdhc_a_podf", + "usboh3_podf", "dummy"/* wrck_clk_root */, + "ecspi_podf", "dummy"/* pll1_ref_clk */, + "esdhc_b_podf", "dummy"/* ddr_clk_root */, + "dummy"/* arm_axi_clk_root */, "dummy"/* usb_phy_out */, + "vpu_sel", "ipu_sel", + "osc", "ckih1", + "dummy", "esdhc_c_sel", + "ssi1_root_podf", "ssi2_root_podf", + "dummy", "dummy", + "dummy"/* lpsr_clk_root */, "dummy"/* pgc_clk_root */, + "dummy"/* tve_out */, "usb_phy_sel", + "tve_sel", "lp_apm", + "uart_root", "dummy"/* spdif0_clk_root */, + "dummy", "dummy", }; enum imx5_clks { dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred, @@ -86,6 +108,8 @@ enum imx5_clks { epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate, can_sel, can1_serial_gate, can1_ipg_gate, owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate, + cko1_sel, cko1_podf, cko1, + cko2_sel, cko2_podf, cko2, clk_max }; @@ -463,6 +487,16 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6); clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); + clk[cko1_sel] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4, + mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel)); + clk[cko1_podf] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3); + clk[cko1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7); + + clk[cko2_sel] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5, + mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel)); + clk[cko2_podf] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3); + clk[cko2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24); + for (i = 0; i < ARRAY_SIZE(clk); i++) if (IS_ERR(clk[i])) pr_err("i.MX53 clk %d: register failed with %ld\n", -- cgit v1.1 From 9a37ac481aab63c61488562c03125ba279ad57c6 Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Sat, 16 Mar 2013 16:49:59 +0100 Subject: ARM: imx1: mm: add call to mxc_device_init mxc_device_init() is mandatory for mxc_aips and mxc_ahb bus registration, needed as parents, at least, for gpio and dma. Signed-off-by: Gwenhael Goavec-Merou Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mm-imx1.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/mm-imx1.c b/arch/arm/mach-imx/mm-imx1.c index 7a14667..3c609c5 100644 --- a/arch/arm/mach-imx/mm-imx1.c +++ b/arch/arm/mach-imx/mm-imx1.c @@ -51,6 +51,8 @@ void __init mx1_init_irq(void) void __init imx1_soc_init(void) { + mxc_device_init(); + mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256, MX1_GPIO_INT_PORTA, 0); mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256, -- cgit v1.1 From 3c03a2fed63881abf5ecb5596625157ecfc9e4eb Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Mon, 1 Apr 2013 22:13:32 +0800 Subject: ARM: imx: add initial imx6dl support The i.MX6 DualLite/Solo is another i.MX6 family SoC, which is highly compatible with i.MX6 Quad/Dual. And that's why we choose to support it using imx6q code with cpu_is_imx6dl() check when necessary. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 2 +- arch/arm/mach-imx/clk-imx6q.c | 2 +- arch/arm/mach-imx/mach-imx6q.c | 30 +++++++++++++++++++++--------- arch/arm/mach-imx/mxc.h | 11 +++++++++++ 4 files changed, 34 insertions(+), 11 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 5b676d4..2b09a04 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -790,7 +790,7 @@ config SOC_IMX53 This enables support for Freescale i.MX53 processor. config SOC_IMX6Q - bool "i.MX6 Quad support" + bool "i.MX6 Quad/DualLite support" select ARCH_HAS_CPUFREQ select ARCH_HAS_OPP select ARM_CPU_SUSPEND if PM diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 43dbcd6..1512590 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -296,7 +296,7 @@ int __init mx6q_clocks_init(void) WARN_ON(!base); /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */ - if (imx6q_revision() == IMX_CHIP_REVISION_1_0) { + if (cpu_is_imx6q() && imx6q_revision() == IMX_CHIP_REVISION_1_0) { post_div_table[1].div = 1; post_div_table[2].div = 1; video_div_table[1].div = 1; diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 221f319..8aa9d90 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -39,23 +39,32 @@ #include "cpuidle.h" #include "hardware.h" +static u32 chip_revision; + int imx6q_revision(void) { - static u32 rev; + return chip_revision; +} - if (!rev) - rev = imx_anatop_get_digprog(); +static void __init imx6q_init_revision(void) +{ + u32 rev = imx_anatop_get_digprog(); switch (rev & 0xff) { case 0: - return IMX_CHIP_REVISION_1_0; + chip_revision = IMX_CHIP_REVISION_1_0; + break; case 1: - return IMX_CHIP_REVISION_1_1; + chip_revision = IMX_CHIP_REVISION_1_1; + break; case 2: - return IMX_CHIP_REVISION_1_2; + chip_revision = IMX_CHIP_REVISION_1_2; + break; default: - return IMX_CHIP_REVISION_UNKNOWN; + chip_revision = IMX_CHIP_REVISION_UNKNOWN; } + + mxc_set_cpu_type(rev >> 16 & 0xff); } void imx6q_restart(char mode, const char *cmd) @@ -247,6 +256,7 @@ static void __init imx6q_map_io(void) static void __init imx6q_init_irq(void) { + imx6q_init_revision(); l2x0_of_init(0, ~0UL); imx_src_init(); imx_gpc_init(); @@ -257,15 +267,17 @@ static void __init imx6q_timer_init(void) { mx6q_clocks_init(); twd_local_timer_of_register(); - imx_print_silicon_rev("i.MX6Q", imx6q_revision()); + imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", + imx6q_revision()); } static const char *imx6q_dt_compat[] __initdata = { + "fsl,imx6dl", "fsl,imx6q", NULL, }; -DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)") +DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)") .smp = smp_ops(imx_smp_ops), .map_io = imx6q_map_io, .init_irq = imx6q_init_irq, diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index 7dce17a..8629e5b 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -34,6 +34,8 @@ #define MXC_CPU_MX35 35 #define MXC_CPU_MX51 51 #define MXC_CPU_MX53 53 +#define MXC_CPU_IMX6DL 0x61 +#define MXC_CPU_IMX6Q 0x63 #define IMX_CHIP_REVISION_1_0 0x10 #define IMX_CHIP_REVISION_1_1 0x11 @@ -150,6 +152,15 @@ extern unsigned int __mxc_cpu_type; #endif #ifndef __ASSEMBLY__ +static inline bool cpu_is_imx6dl(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX6DL; +} + +static inline bool cpu_is_imx6q(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX6Q; +} struct cpu_op { u32 cpu_rate; -- cgit v1.1 From dc13ba2950acdd7ca64de3a8addcf85ada8ee908 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 2 Apr 2013 16:37:21 +0800 Subject: ARM: imx: do not bring up unavailable cores The i.MX6 Quad can be fused as i.MX6 Dual chip, and similarly i.MX6 DualLite can be fused as i.MX6 Solo. The actual number of available cores can be found out from SCU. Since we do not reflect the fusing thing in device tree, the function arm_dt_init_cpu_maps() will always call set_cpu_possible(true) for 4 cores on i.MX6 Quad/Dual and 2 cores for i.MX6 DualLite/Solo. This causes failures when kernel tries to bring those unavailable cores online. For example, the following failure message will be seen when booting an i.MX6 Solo chip. CPU1: failed to come online Though kernel will still boot fine, the message is somehow annoying. Let's get rid of it by calling set_cpu_possible(false) on those unavailable cores. While at it, the set_cpu_possible(true) for available cores is removed, since it's already been done in arm_dt_init_cpu_maps(). Signed-off-by: Shawn Guo --- arch/arm/mach-imx/platsmp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index 7c0b03f..7061bde 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c @@ -79,8 +79,8 @@ static void __init imx_smp_init_cpus(void) ncores = scu_get_core_count(scu_base); - for (i = 0; i < ncores; i++) - set_cpu_possible(i, true); + for (i = ncores; i < NR_CPUS; i++) + set_cpu_possible(i, false); } void imx_smp_prepare(void) -- cgit v1.1 From 5d530bb0ad84d403d1aac79a8a8acf2c2b0a8dd7 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 4 Apr 2013 11:25:08 +0200 Subject: ARM: i.MX5: Add PATA and SRTC clocks This adds the clock gates and the binding documentation for PATA and SRTC. Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index a163e0e..efbccc0 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -110,6 +110,7 @@ enum imx5_clks { owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate, cko1_sel, cko1_podf, cko1, cko2_sel, cko2_podf, cko2, + srtc_gate, pata_gate, clk_max }; @@ -266,6 +267,8 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk[epit2_ipg_gate] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6); clk[epit2_hf_gate] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8); clk[owire_gate] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22); + clk[srtc_gate] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28); + clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0); for (i = 0; i < ARRAY_SIZE(clk); i++) if (IS_ERR(clk[i])) -- cgit v1.1 From 3f487bed1b78140a38760d774b893ff2ea8e3d17 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 8 Apr 2013 16:46:19 +0200 Subject: ARM i.MX5: Remove tve_sel clock from i.MX53 clock tree On i.MX53, there is only tve_ext_sel. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index efbccc0..a68bb38 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -45,7 +45,7 @@ static const char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", " static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", }; static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", }; static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", }; -static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", }; +static const char *mx51_tve_sel[] = { "tve_pred", "tve_ext_sel", }; static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; @@ -188,7 +188,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3); clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); clk[tve_di] = imx_clk_fixed("tve_di", 65000000); /* FIXME */ - clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, tve_sel, ARRAY_SIZE(tve_sel)); clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8); @@ -367,6 +366,8 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel)); clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel)); + clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, + mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel)); clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30); clk[tve_pred] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3); clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); -- cgit v1.1 From 866f2f0d8d94957a36811bde43a14abd373dfb37 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 8 Apr 2013 16:46:20 +0200 Subject: ARM i.MX53: Remove unused tve_gate clkdev entry Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index a68bb38..7e50ec9 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -319,7 +319,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0"); clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1"); clk_register_clkdev(clk[dummy], NULL, "imx-keypad"); - clk_register_clkdev(clk[tve_gate], NULL, "imx-tve.0"); clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0"); clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL); clk_register_clkdev(clk[epit1_ipg_gate], "ipg", "imx-epit.0"); -- cgit v1.1 From f550e70175c43686e5b2df24b1a4054c5afce6e4 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 8 Apr 2013 16:46:21 +0200 Subject: ARM i.MX53: make tve_ext_sel propagate rate change to PLL This is needed so the Television Encoder driver can set the rate on tve_clk and have it propagated up to pll4_sw. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index 7e50ec9..a107e81 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -472,8 +472,8 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel)); clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel)); - clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, - mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel)); + clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, + mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT); clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30); clk[tve_pred] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3); clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); -- cgit v1.1 From d24de4952314afbbcd51b1fb72e5a320d60379dc Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 8 Apr 2013 16:46:22 +0200 Subject: ARM i.MX53: tve_di clock is not part of the CCM, but of TVE Remove the tve_di clock from the CCM clock tree. It will be provided by the Television Encoder driver, as this clock is an output signal of the TVE module. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index a107e81..cac6a5f 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -78,7 +78,7 @@ enum imx5_clks { dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred, uart_root, esdhc_a_pred, esdhc_b_pred, esdhc_c_s, esdhc_d_s, emi_sel, emi_slow_podf, nfc_podf, ecspi_pred, ecspi_podf, usboh3_pred, - usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di, + usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di_unused, tve_s, uart1_ipg_gate, uart1_per_gate, uart2_ipg_gate, uart2_per_gate, uart3_ipg_gate, uart3_per_gate, i2c1_gate, i2c2_gate, gpt_ipg_gate, pwm1_ipg_gate, pwm1_hf_gate, pwm2_ipg_gate, pwm2_hf_gate, @@ -187,7 +187,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str)); clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3); clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); - clk[tve_di] = imx_clk_fixed("tve_di", 65000000); /* FIXME */ clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8); -- cgit v1.1 From 80f72d2d33263429ac6a50b84b2ec5fa681a5e84 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 8 Apr 2013 16:46:23 +0200 Subject: ARM i.MX53: set CLK_SET_RATE_PARENT flag on the tve_ext_sel clock Use imx_clk_mux_flags to set the appropriate flags for the TVE selector clock. This is needed so tve_clk rate changes can propagate up to pll4_sw. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index cac6a5f..41dd4d6 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -362,8 +362,8 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel)); clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel)); - clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, - mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel)); + clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, + mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT); clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel)); clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30); -- cgit v1.1