aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/Kconfig28
-rw-r--r--arch/arm/mach-imx/Makefile4
-rw-r--r--arch/arm/mach-imx/Makefile.boot35
-rw-r--r--arch/arm/mach-imx/anatop.c103
-rw-r--r--arch/arm/mach-imx/avic.c4
-rw-r--r--arch/arm/mach-imx/clk-imx27.c2
-rw-r--r--arch/arm/mach-imx/clk-imx35.c2
-rw-r--r--arch/arm/mach-imx/clk-imx51-imx53.c75
-rw-r--r--arch/arm/mach-imx/clk-imx6q.c129
-rw-r--r--arch/arm/mach-imx/clk.h17
-rw-r--r--arch/arm/mach-imx/common.h15
-rw-r--r--arch/arm/mach-imx/cpu_op-mx51.c31
-rw-r--r--arch/arm/mach-imx/cpu_op-mx51.h14
-rw-r--r--arch/arm/mach-imx/cpufreq.c206
-rw-r--r--arch/arm/mach-imx/devices/Kconfig4
-rw-r--r--arch/arm/mach-imx/devices/Makefile1
-rw-r--r--arch/arm/mach-imx/devices/devices-common.h10
-rw-r--r--arch/arm/mach-imx/devices/platform-ahci-imx.c157
-rw-r--r--arch/arm/mach-imx/gpc.c23
-rw-r--r--arch/arm/mach-imx/hardware.h1
-rw-r--r--arch/arm/mach-imx/hotplug.c12
-rw-r--r--arch/arm/mach-imx/mach-cpuimx51sd.c5
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c74
-rw-r--r--arch/arm/mach-imx/mach-mx51_babbage.c4
-rw-r--r--arch/arm/mach-imx/mm-imx1.c2
-rw-r--r--arch/arm/mach-imx/mx6q.h31
-rw-r--r--arch/arm/mach-imx/mxc.h11
-rw-r--r--arch/arm/mach-imx/platsmp.c4
-rw-r--r--arch/arm/mach-imx/pm-imx6q.c4
-rw-r--r--arch/arm/mach-imx/src.c77
30 files changed, 475 insertions, 610 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 4c9c6f9d2c55..2b09a0471d7b 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -65,6 +65,9 @@ config IRAM_ALLOC
65 bool 65 bool
66 select GENERIC_ALLOCATOR 66 select GENERIC_ALLOCATOR
67 67
68config HAVE_IMX_ANATOP
69 bool
70
68config HAVE_IMX_GPC 71config HAVE_IMX_GPC
69 bool 72 bool
70 73
@@ -73,6 +76,7 @@ config HAVE_IMX_MMDC
73 76
74config HAVE_IMX_SRC 77config HAVE_IMX_SRC
75 def_bool y if SMP 78 def_bool y if SMP
79 select ARCH_HAS_RESET_CONTROLLER
76 80
77config IMX_HAVE_IOMUX_V1 81config IMX_HAVE_IOMUX_V1
78 bool 82 bool
@@ -83,24 +87,12 @@ config ARCH_MXC_IOMUX_V3
83config ARCH_MX1 87config ARCH_MX1
84 bool 88 bool
85 89
86config MACH_MX21
87 bool
88
89config ARCH_MX25 90config ARCH_MX25
90 bool 91 bool
91 92
92config MACH_MX27 93config MACH_MX27
93 bool 94 bool
94 95
95config ARCH_MX5
96 bool
97
98config ARCH_MX51
99 bool
100
101config ARCH_MX53
102 bool
103
104config SOC_IMX1 96config SOC_IMX1
105 bool 97 bool
106 select ARCH_MX1 98 select ARCH_MX1
@@ -114,7 +106,6 @@ config SOC_IMX21
114 select COMMON_CLK 106 select COMMON_CLK
115 select CPU_ARM926T 107 select CPU_ARM926T
116 select IMX_HAVE_IOMUX_V1 108 select IMX_HAVE_IOMUX_V1
117 select MACH_MX21
118 select MXC_AVIC 109 select MXC_AVIC
119 110
120config SOC_IMX25 111config SOC_IMX25
@@ -128,6 +119,8 @@ config SOC_IMX25
128 119
129config SOC_IMX27 120config SOC_IMX27
130 bool 121 bool
122 select ARCH_HAS_CPUFREQ
123 select ARCH_HAS_OPP
131 select COMMON_CLK 124 select COMMON_CLK
132 select CPU_ARM926T 125 select CPU_ARM926T
133 select IMX_HAVE_IOMUX_V1 126 select IMX_HAVE_IOMUX_V1
@@ -155,7 +148,7 @@ config SOC_IMX35
155config SOC_IMX5 148config SOC_IMX5
156 bool 149 bool
157 select ARCH_HAS_CPUFREQ 150 select ARCH_HAS_CPUFREQ
158 select ARCH_MX5 151 select ARCH_HAS_OPP
159 select ARCH_MXC_IOMUX_V3 152 select ARCH_MXC_IOMUX_V3
160 select COMMON_CLK 153 select COMMON_CLK
161 select CPU_V7 154 select CPU_V7
@@ -163,8 +156,6 @@ config SOC_IMX5
163 156
164config SOC_IMX51 157config SOC_IMX51
165 bool 158 bool
166 select ARCH_MX5
167 select ARCH_MX51
168 select PINCTRL 159 select PINCTRL
169 select PINCTRL_IMX51 160 select PINCTRL_IMX51
170 select SOC_IMX5 161 select SOC_IMX5
@@ -789,8 +780,6 @@ comment "Device tree only"
789 780
790config SOC_IMX53 781config SOC_IMX53
791 bool "i.MX53 support" 782 bool "i.MX53 support"
792 select ARCH_MX5
793 select ARCH_MX53
794 select HAVE_CAN_FLEXCAN if CAN 783 select HAVE_CAN_FLEXCAN if CAN
795 select IMX_HAVE_PLATFORM_IMX2_WDT 784 select IMX_HAVE_PLATFORM_IMX2_WDT
796 select PINCTRL 785 select PINCTRL
@@ -801,7 +790,7 @@ config SOC_IMX53
801 This enables support for Freescale i.MX53 processor. 790 This enables support for Freescale i.MX53 processor.
802 791
803config SOC_IMX6Q 792config SOC_IMX6Q
804 bool "i.MX6 Quad support" 793 bool "i.MX6 Quad/DualLite support"
805 select ARCH_HAS_CPUFREQ 794 select ARCH_HAS_CPUFREQ
806 select ARCH_HAS_OPP 795 select ARCH_HAS_OPP
807 select ARM_CPU_SUSPEND if PM 796 select ARM_CPU_SUSPEND if PM
@@ -813,6 +802,7 @@ config SOC_IMX6Q
813 select CPU_V7 802 select CPU_V7
814 select HAVE_ARM_SCU 803 select HAVE_ARM_SCU
815 select HAVE_CAN_FLEXCAN if CAN 804 select HAVE_CAN_FLEXCAN if CAN
805 select HAVE_IMX_ANATOP
816 select HAVE_IMX_GPC 806 select HAVE_IMX_GPC
817 select HAVE_IMX_MMDC 807 select HAVE_IMX_MMDC
818 select HAVE_IMX_SRC 808 select HAVE_IMX_SRC
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index c4ce0906d76a..b16eb39b9f5d 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-
12obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o 12obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o
13 13
14imx5-pm-$(CONFIG_PM) += pm-imx5.o 14imx5-pm-$(CONFIG_PM) += pm-imx5.o
15obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o $(imx5-pm-y) cpu_op-mx51.o 15obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o $(imx5-pm-y)
16 16
17obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ 17obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
18 clk-pfd.o clk-busy.o clk.o 18 clk-pfd.o clk-busy.o clk.o
@@ -27,7 +27,6 @@ obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
27obj-$(CONFIG_MXC_ULPI) += ulpi.o 27obj-$(CONFIG_MXC_ULPI) += ulpi.o
28obj-$(CONFIG_MXC_USE_EPIT) += epit.o 28obj-$(CONFIG_MXC_USE_EPIT) += epit.o
29obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o 29obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
30obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
31 30
32ifeq ($(CONFIG_CPU_IDLE),y) 31ifeq ($(CONFIG_CPU_IDLE),y)
33obj-y += cpuidle.o 32obj-y += cpuidle.o
@@ -92,6 +91,7 @@ obj-$(CONFIG_MACH_EUKREA_CPUIMX35SD) += mach-cpuimx35.o
92obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o 91obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
93obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o 92obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
94 93
94obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o
95obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o 95obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
96obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o 96obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
97obj-$(CONFIG_HAVE_IMX_SRC) += src.o 97obj-$(CONFIG_HAVE_IMX_SRC) += src.o
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
deleted file mode 100644
index 41ba1bb0437b..000000000000
--- a/arch/arm/mach-imx/Makefile.boot
+++ /dev/null
@@ -1,35 +0,0 @@
1zreladdr-$(CONFIG_SOC_IMX1) += 0x08008000
2params_phys-$(CONFIG_SOC_IMX1) := 0x08000100
3initrd_phys-$(CONFIG_SOC_IMX1) := 0x08800000
4
5zreladdr-$(CONFIG_SOC_IMX21) += 0xC0008000
6params_phys-$(CONFIG_SOC_IMX21) := 0xC0000100
7initrd_phys-$(CONFIG_SOC_IMX21) := 0xC0800000
8
9zreladdr-$(CONFIG_SOC_IMX25) += 0x80008000
10params_phys-$(CONFIG_SOC_IMX25) := 0x80000100
11initrd_phys-$(CONFIG_SOC_IMX25) := 0x80800000
12
13zreladdr-$(CONFIG_SOC_IMX27) += 0xA0008000
14params_phys-$(CONFIG_SOC_IMX27) := 0xA0000100
15initrd_phys-$(CONFIG_SOC_IMX27) := 0xA0800000
16
17zreladdr-$(CONFIG_SOC_IMX31) += 0x80008000
18params_phys-$(CONFIG_SOC_IMX31) := 0x80000100
19initrd_phys-$(CONFIG_SOC_IMX31) := 0x80800000
20
21zreladdr-$(CONFIG_SOC_IMX35) += 0x80008000
22params_phys-$(CONFIG_SOC_IMX35) := 0x80000100
23initrd_phys-$(CONFIG_SOC_IMX35) := 0x80800000
24
25zreladdr-$(CONFIG_SOC_IMX51) += 0x90008000
26params_phys-$(CONFIG_SOC_IMX51) := 0x90000100
27initrd_phys-$(CONFIG_SOC_IMX51) := 0x90800000
28
29zreladdr-$(CONFIG_SOC_IMX53) += 0x70008000
30params_phys-$(CONFIG_SOC_IMX53) := 0x70000100
31initrd_phys-$(CONFIG_SOC_IMX53) := 0x70800000
32
33zreladdr-$(CONFIG_SOC_IMX6Q) += 0x10008000
34params_phys-$(CONFIG_SOC_IMX6Q) := 0x10000100
35initrd_phys-$(CONFIG_SOC_IMX6Q) := 0x10800000
diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c
new file mode 100644
index 000000000000..0cfa07dd9aa4
--- /dev/null
+++ b/arch/arm/mach-imx/anatop.c
@@ -0,0 +1,103 @@
1/*
2 * Copyright (C) 2013 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/err.h>
13#include <linux/io.h>
14#include <linux/of.h>
15#include <linux/of_address.h>
16#include <linux/mfd/syscon.h>
17#include <linux/regmap.h>
18#include "common.h"
19
20#define REG_SET 0x4
21#define REG_CLR 0x8
22
23#define ANADIG_REG_2P5 0x130
24#define ANADIG_REG_CORE 0x140
25#define ANADIG_ANA_MISC0 0x150
26#define ANADIG_USB1_CHRG_DETECT 0x1b0
27#define ANADIG_USB2_CHRG_DETECT 0x210
28#define ANADIG_DIGPROG 0x260
29
30#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000
31#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000
32#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000
33#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000
34#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000
35
36static struct regmap *anatop;
37
38static void imx_anatop_enable_weak2p5(bool enable)
39{
40 u32 reg, val;
41
42 regmap_read(anatop, ANADIG_ANA_MISC0, &val);
43
44 /* can only be enabled when stop_mode_config is clear. */
45 reg = ANADIG_REG_2P5;
46 reg += (enable && (val & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) ?
47 REG_SET : REG_CLR;
48 regmap_write(anatop, reg, BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG);
49}
50
51static void imx_anatop_enable_fet_odrive(bool enable)
52{
53 regmap_write(anatop, ANADIG_REG_CORE + (enable ? REG_SET : REG_CLR),
54 BM_ANADIG_REG_CORE_FET_ODRIVE);
55}
56
57void imx_anatop_pre_suspend(void)
58{
59 imx_anatop_enable_weak2p5(true);
60 imx_anatop_enable_fet_odrive(true);
61}
62
63void imx_anatop_post_resume(void)
64{
65 imx_anatop_enable_fet_odrive(false);
66 imx_anatop_enable_weak2p5(false);
67}
68
69void imx_anatop_usb_chrg_detect_disable(void)
70{
71 regmap_write(anatop, ANADIG_USB1_CHRG_DETECT,
72 BM_ANADIG_USB_CHRG_DETECT_EN_B
73 | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
74 regmap_write(anatop, ANADIG_USB2_CHRG_DETECT,
75 BM_ANADIG_USB_CHRG_DETECT_EN_B |
76 BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
77}
78
79u32 imx_anatop_get_digprog(void)
80{
81 struct device_node *np;
82 void __iomem *anatop_base;
83 static u32 digprog;
84
85 if (digprog)
86 return digprog;
87
88 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
89 anatop_base = of_iomap(np, 0);
90 WARN_ON(!anatop_base);
91 digprog = readl_relaxed(anatop_base + ANADIG_DIGPROG);
92
93 return digprog;
94}
95
96void __init imx_anatop_init(void)
97{
98 anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
99 if (IS_ERR(anatop)) {
100 pr_err("%s: failed to find imx6q-anatop regmap!\n", __func__);
101 return;
102 }
103}
diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c
index 0eff23ed92b9..49c87e7aa817 100644
--- a/arch/arm/mach-imx/avic.c
+++ b/arch/arm/mach-imx/avic.c
@@ -54,8 +54,6 @@
54void __iomem *avic_base; 54void __iomem *avic_base;
55static struct irq_domain *domain; 55static struct irq_domain *domain;
56 56
57static u32 avic_saved_mask_reg[2];
58
59#ifdef CONFIG_MXC_IRQ_PRIOR 57#ifdef CONFIG_MXC_IRQ_PRIOR
60static int avic_irq_set_priority(unsigned char irq, unsigned char prio) 58static int avic_irq_set_priority(unsigned char irq, unsigned char prio)
61{ 59{
@@ -113,6 +111,8 @@ static struct mxc_extra_irq avic_extra_irq = {
113}; 111};
114 112
115#ifdef CONFIG_PM 113#ifdef CONFIG_PM
114static u32 avic_saved_mask_reg[2];
115
116static void avic_irq_suspend(struct irq_data *d) 116static void avic_irq_suspend(struct irq_data *d)
117{ 117{
118 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 118 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
index 30b3242a7d49..8e3b65719106 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)
278 clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL); 278 clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL);
279 clk_register_clkdev(clk[cpu_div], "cpu", NULL); 279 clk_register_clkdev(clk[cpu_div], "cpu", NULL);
280 clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL); 280 clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL);
281 clk_register_clkdev(clk[ssi1_baud_gate], "bitrate" , "imx-ssi.0");
282 clk_register_clkdev(clk[ssi2_baud_gate], "bitrate" , "imx-ssi.1");
283 281
284 mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1); 282 mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1);
285 283
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
index e13a8fa5e62c..2193c834f55c 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)
257 clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); 257 clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
258 clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0"); 258 clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
259 clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); 259 clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
260 clk_register_clkdev(clk[admux_gate], "audmux", NULL);
260 261
261 clk_prepare_enable(clk[spba_gate]); 262 clk_prepare_enable(clk[spba_gate]);
262 clk_prepare_enable(clk[gpio1_gate]); 263 clk_prepare_enable(clk[gpio1_gate]);
@@ -265,6 +266,7 @@ int __init mx35_clocks_init(void)
265 clk_prepare_enable(clk[iim_gate]); 266 clk_prepare_enable(clk[iim_gate]);
266 clk_prepare_enable(clk[emi_gate]); 267 clk_prepare_enable(clk[emi_gate]);
267 clk_prepare_enable(clk[max_gate]); 268 clk_prepare_enable(clk[max_gate]);
269 clk_prepare_enable(clk[iomuxc_gate]);
268 270
269 /* 271 /*
270 * SCC is needed to boot via mmc after a watchdog reset. The clock code 272 * SCC is needed to boot via mmc after a watchdog reset. The clock code
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index 0f39f8c93b94..41dd4d6e5b91 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -45,16 +45,40 @@ static const char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "
45static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", }; 45static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", };
46static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", }; 46static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", };
47static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", }; 47static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", };
48static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", }; 48static const char *mx51_tve_sel[] = { "tve_pred", "tve_ext_sel", };
49static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; 49static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
50static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" };
51static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" };
50static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; 52static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
51static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", }; 53static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", };
54static const char *mx53_cko1_sel[] = {
55 "cpu_podf", "pll1_sw", "pll2_sw", "pll3_sw",
56 "emi_slow_podf", "pll4_sw", "nfc_podf", "dummy",
57 "di_pred", "dummy", "dummy", "ahb",
58 "ipg", "per_root", "ckil", "dummy",};
59static const char *mx53_cko2_sel[] = {
60 "dummy"/* dptc_core */, "dummy"/* dptc_perich */,
61 "dummy", "esdhc_a_podf",
62 "usboh3_podf", "dummy"/* wrck_clk_root */,
63 "ecspi_podf", "dummy"/* pll1_ref_clk */,
64 "esdhc_b_podf", "dummy"/* ddr_clk_root */,
65 "dummy"/* arm_axi_clk_root */, "dummy"/* usb_phy_out */,
66 "vpu_sel", "ipu_sel",
67 "osc", "ckih1",
68 "dummy", "esdhc_c_sel",
69 "ssi1_root_podf", "ssi2_root_podf",
70 "dummy", "dummy",
71 "dummy"/* lpsr_clk_root */, "dummy"/* pgc_clk_root */,
72 "dummy"/* tve_out */, "usb_phy_sel",
73 "tve_sel", "lp_apm",
74 "uart_root", "dummy"/* spdif0_clk_root */,
75 "dummy", "dummy", };
52 76
53enum imx5_clks { 77enum imx5_clks {
54 dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred, 78 dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred,
55 uart_root, esdhc_a_pred, esdhc_b_pred, esdhc_c_s, esdhc_d_s, 79 uart_root, esdhc_a_pred, esdhc_b_pred, esdhc_c_s, esdhc_d_s,
56 emi_sel, emi_slow_podf, nfc_podf, ecspi_pred, ecspi_podf, usboh3_pred, 80 emi_sel, emi_slow_podf, nfc_podf, ecspi_pred, ecspi_podf, usboh3_pred,
57 usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di, 81 usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di_unused,
58 tve_s, uart1_ipg_gate, uart1_per_gate, uart2_ipg_gate, 82 tve_s, uart1_ipg_gate, uart1_per_gate, uart2_ipg_gate,
59 uart2_per_gate, uart3_ipg_gate, uart3_per_gate, i2c1_gate, i2c2_gate, 83 uart2_per_gate, uart3_ipg_gate, uart3_per_gate, i2c1_gate, i2c2_gate,
60 gpt_ipg_gate, pwm1_ipg_gate, pwm1_hf_gate, pwm2_ipg_gate, pwm2_hf_gate, 84 gpt_ipg_gate, pwm1_ipg_gate, pwm1_hf_gate, pwm2_ipg_gate, pwm2_hf_gate,
@@ -83,7 +107,10 @@ enum imx5_clks {
83 ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate, 107 ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate,
84 epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate, 108 epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate,
85 can_sel, can1_serial_gate, can1_ipg_gate, 109 can_sel, can1_serial_gate, can1_ipg_gate,
86 owire_gate, 110 owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate,
111 cko1_sel, cko1_podf, cko1,
112 cko2_sel, cko2_podf, cko2,
113 srtc_gate, pata_gate,
87 clk_max 114 clk_max
88}; 115};
89 116
@@ -160,8 +187,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
160 usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str)); 187 usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
161 clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3); 188 clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3);
162 clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); 189 clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3);
163 clk[tve_di] = imx_clk_fixed("tve_di", 65000000); /* FIXME */
164 clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, tve_sel, ARRAY_SIZE(tve_sel));
165 clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); 190 clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30);
166 clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); 191 clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6);
167 clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8); 192 clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8);
@@ -200,6 +225,11 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
200 clk[nfc_gate] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20); 225 clk[nfc_gate] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20);
201 clk[ipu_di0_gate] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10); 226 clk[ipu_di0_gate] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10);
202 clk[ipu_di1_gate] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12); 227 clk[ipu_di1_gate] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12);
228 clk[gpu3d_s] = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel));
229 clk[gpu2d_s] = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel));
230 clk[gpu3d_gate] = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2);
231 clk[garb_gate] = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4);
232 clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14);
203 clk[vpu_s] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel)); 233 clk[vpu_s] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel));
204 clk[vpu_gate] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6); 234 clk[vpu_gate] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6);
205 clk[vpu_reference_gate] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8); 235 clk[vpu_reference_gate] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8);
@@ -235,6 +265,8 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
235 clk[epit2_ipg_gate] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6); 265 clk[epit2_ipg_gate] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6);
236 clk[epit2_hf_gate] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8); 266 clk[epit2_hf_gate] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8);
237 clk[owire_gate] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22); 267 clk[owire_gate] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22);
268 clk[srtc_gate] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28);
269 clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0);
238 270
239 for (i = 0; i < ARRAY_SIZE(clk); i++) 271 for (i = 0; i < ARRAY_SIZE(clk); i++)
240 if (IS_ERR(clk[i])) 272 if (IS_ERR(clk[i]))
@@ -286,7 +318,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
286 clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0"); 318 clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0");
287 clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1"); 319 clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1");
288 clk_register_clkdev(clk[dummy], NULL, "imx-keypad"); 320 clk_register_clkdev(clk[dummy], NULL, "imx-keypad");
289 clk_register_clkdev(clk[tve_gate], NULL, "imx-tve.0");
290 clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0"); 321 clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0");
291 clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL); 322 clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL);
292 clk_register_clkdev(clk[epit1_ipg_gate], "ipg", "imx-epit.0"); 323 clk_register_clkdev(clk[epit1_ipg_gate], "ipg", "imx-epit.0");
@@ -331,8 +362,10 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
331 mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel)); 362 mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
332 clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, 363 clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
333 mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel)); 364 mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
334 clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, 365 clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
335 mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel)); 366 mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT);
367 clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1,
368 mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel));
336 clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30); 369 clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30);
337 clk[tve_pred] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3); 370 clk[tve_pred] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3);
338 clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); 371 clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
@@ -423,23 +456,23 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
423 clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE); 456 clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE);
424 clk[pll4_sw] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE); 457 clk[pll4_sw] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE);
425 458
426 clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
427 mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel));
428 clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); 459 clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
429 clk[ldb_di1_div] = imx_clk_divider("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1); 460 clk[ldb_di1_div] = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0);
461 clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
462 mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT);
430 clk[di_pll4_podf] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3); 463 clk[di_pll4_podf] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3);
431 clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
432 mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel));
433 clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); 464 clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
434 clk[ldb_di0_div] = imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1); 465 clk[ldb_di0_div] = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0);
466 clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
467 mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT);
435 clk[ldb_di0_gate] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28); 468 clk[ldb_di0_gate] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28);
436 clk[ldb_di1_gate] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30); 469 clk[ldb_di1_gate] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30);
437 clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, 470 clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
438 mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel)); 471 mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
439 clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, 472 clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
440 mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel)); 473 mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
441 clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, 474 clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
442 mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel)); 475 mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT);
443 clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30); 476 clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
444 clk[tve_pred] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3); 477 clk[tve_pred] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3);
445 clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); 478 clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
@@ -456,6 +489,16 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
456 clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6); 489 clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6);
457 clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); 490 clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
458 491
492 clk[cko1_sel] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
493 mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
494 clk[cko1_podf] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3);
495 clk[cko1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7);
496
497 clk[cko2_sel] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5,
498 mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel));
499 clk[cko2_podf] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3);
500 clk[cko2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
501
459 for (i = 0; i < ARRAY_SIZE(clk); i++) 502 for (i = 0; i < ARRAY_SIZE(clk); i++)
460 if (IS_ERR(clk[i])) 503 if (IS_ERR(clk[i]))
461 pr_err("i.MX53 clk %d: register failed with %ld\n", 504 pr_err("i.MX53 clk %d: register failed with %ld\n",
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 2f9ff93a4e61..151259003086 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. 2 * Copyright 2011-2013 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd. 3 * Copyright 2011 Linaro Ltd.
4 * 4 *
5 * The code contained herein is licensed under the GNU General Public 5 * The code contained herein is licensed under the GNU General Public
@@ -14,6 +14,7 @@
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/clkdev.h> 16#include <linux/clkdev.h>
17#include <linux/delay.h>
17#include <linux/err.h> 18#include <linux/err.h>
18#include <linux/io.h> 19#include <linux/io.h>
19#include <linux/of.h> 20#include <linux/of.h>
@@ -22,6 +23,12 @@
22 23
23#include "clk.h" 24#include "clk.h"
24#include "common.h" 25#include "common.h"
26#include "hardware.h"
27
28#define CCR 0x0
29#define BM_CCR_WB_COUNT (0x7 << 16)
30#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21)
31#define BM_CCR_RBC_EN (0x1 << 27)
25 32
26#define CCGR0 0x68 33#define CCGR0 0x68
27#define CCGR1 0x6c 34#define CCGR1 0x6c
@@ -67,6 +74,67 @@ void imx6q_set_chicken_bit(void)
67 writel_relaxed(val, ccm_base + CGPR); 74 writel_relaxed(val, ccm_base + CGPR);
68} 75}
69 76
77static void imx6q_enable_rbc(bool enable)
78{
79 u32 val;
80 static bool last_rbc_mode;
81
82 if (last_rbc_mode == enable)
83 return;
84 /*
85 * need to mask all interrupts in GPC before
86 * operating RBC configurations
87 */
88 imx_gpc_mask_all();
89
90 /* configure RBC enable bit */
91 val = readl_relaxed(ccm_base + CCR);
92 val &= ~BM_CCR_RBC_EN;
93 val |= enable ? BM_CCR_RBC_EN : 0;
94 writel_relaxed(val, ccm_base + CCR);
95
96 /* configure RBC count */
97 val = readl_relaxed(ccm_base + CCR);
98 val &= ~BM_CCR_RBC_BYPASS_COUNT;
99 val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
100 writel(val, ccm_base + CCR);
101
102 /*
103 * need to delay at least 2 cycles of CKIL(32K)
104 * due to hardware design requirement, which is
105 * ~61us, here we use 65us for safe
106 */
107 udelay(65);
108
109 /* restore GPC interrupt mask settings */
110 imx_gpc_restore_all();
111
112 last_rbc_mode = enable;
113}
114
115static void imx6q_enable_wb(bool enable)
116{
117 u32 val;
118 static bool last_wb_mode;
119
120 if (last_wb_mode == enable)
121 return;
122
123 /* configure well bias enable bit */
124 val = readl_relaxed(ccm_base + CLPCR);
125 val &= ~BM_CLPCR_WB_PER_AT_LPM;
126 val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
127 writel_relaxed(val, ccm_base + CLPCR);
128
129 /* configure well bias count */
130 val = readl_relaxed(ccm_base + CCR);
131 val &= ~BM_CCR_WB_COUNT;
132 val |= enable ? BM_CCR_WB_COUNT : 0;
133 writel_relaxed(val, ccm_base + CCR);
134
135 last_wb_mode = enable;
136}
137
70int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) 138int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
71{ 139{
72 u32 val = readl_relaxed(ccm_base + CLPCR); 140 u32 val = readl_relaxed(ccm_base + CLPCR);
@@ -74,6 +142,8 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
74 val &= ~BM_CLPCR_LPM; 142 val &= ~BM_CLPCR_LPM;
75 switch (mode) { 143 switch (mode) {
76 case WAIT_CLOCKED: 144 case WAIT_CLOCKED:
145 imx6q_enable_wb(false);
146 imx6q_enable_rbc(false);
77 break; 147 break;
78 case WAIT_UNCLOCKED: 148 case WAIT_UNCLOCKED:
79 val |= 0x1 << BP_CLPCR_LPM; 149 val |= 0x1 << BP_CLPCR_LPM;
@@ -92,6 +162,8 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
92 val |= 0x3 << BP_CLPCR_STBY_COUNT; 162 val |= 0x3 << BP_CLPCR_STBY_COUNT;
93 val |= BM_CLPCR_VSTBY; 163 val |= BM_CLPCR_VSTBY;
94 val |= BM_CLPCR_SBYOS; 164 val |= BM_CLPCR_SBYOS;
165 imx6q_enable_wb(true);
166 imx6q_enable_rbc(true);
95 break; 167 break;
96 default: 168 default:
97 return -EINVAL; 169 return -EINVAL;
@@ -109,29 +181,29 @@ static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", };
109static const char *periph_sels[] = { "periph_pre", "periph_clk2", }; 181static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
110static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; 182static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
111static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", }; 183static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", };
112static const char *audio_sels[] = { "pll4_audio", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; 184static const char *audio_sels[] = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
113static const char *gpu_axi_sels[] = { "axi", "ahb", }; 185static const char *gpu_axi_sels[] = { "axi", "ahb", };
114static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", }; 186static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
115static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; 187static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
116static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; 188static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", };
117static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; 189static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
118static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_pfd1_540m", }; 190static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
119static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; 191static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
120static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; 192static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
121static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; 193static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
122static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; 194static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
123static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; 195static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
124static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", }; 196static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", };
125static const char *pcie_axi_sels[] = { "axi", "ahb", }; 197static const char *pcie_axi_sels[] = { "axi", "ahb", };
126static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio", }; 198static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_post_div", };
127static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; 199static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
128static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", }; 200static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", };
129static const char *emi_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", }; 201static const char *emi_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
130static const char *vdo_axi_sels[] = { "axi", "ahb", }; 202static const char *vdo_axi_sels[] = { "axi", "ahb", };
131static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", }; 203static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", };
132static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video", 204static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
133 "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", 205 "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
134 "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", }; 206 "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_post_div", };
135 207
136enum mx6q_clks { 208enum mx6q_clks {
137 dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m, 209 dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m,
@@ -165,7 +237,7 @@ enum mx6q_clks {
165 pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg, 237 pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg,
166 ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5, 238 ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
167 sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate, 239 sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate,
168 usbphy2_gate, clk_max 240 usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, clk_max
169}; 241};
170 242
171static struct clk *clk[clk_max]; 243static struct clk *clk[clk_max];
@@ -182,6 +254,21 @@ static struct clk_div_table clk_enet_ref_table[] = {
182 { .val = 3, .div = 4, }, 254 { .val = 3, .div = 4, },
183}; 255};
184 256
257static struct clk_div_table post_div_table[] = {
258 { .val = 2, .div = 1, },
259 { .val = 1, .div = 2, },
260 { .val = 0, .div = 4, },
261 { }
262};
263
264static struct clk_div_table video_div_table[] = {
265 { .val = 0, .div = 1, },
266 { .val = 1, .div = 2, },
267 { .val = 2, .div = 1, },
268 { .val = 3, .div = 4, },
269 { }
270};
271
185int __init mx6q_clocks_init(void) 272int __init mx6q_clocks_init(void)
186{ 273{
187 struct device_node *np; 274 struct device_node *np;
@@ -208,6 +295,14 @@ int __init mx6q_clocks_init(void)
208 base = of_iomap(np, 0); 295 base = of_iomap(np, 0);
209 WARN_ON(!base); 296 WARN_ON(!base);
210 297
298 /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
299 if (cpu_is_imx6q() && imx6q_revision() == IMX_CHIP_REVISION_1_0) {
300 post_div_table[1].div = 1;
301 post_div_table[2].div = 1;
302 video_div_table[1].div = 1;
303 video_div_table[2].div = 1;
304 };
305
211 /* type name parent_name base div_mask */ 306 /* type name parent_name base div_mask */
212 clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f); 307 clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
213 clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1); 308 clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
@@ -260,6 +355,10 @@ int __init mx6q_clocks_init(void)
260 clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); 355 clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
261 clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2); 356 clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2);
262 357
358 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);
359 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);
360 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);
361
263 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm"); 362 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm");
264 base = of_iomap(np, 0); 363 base = of_iomap(np, 0);
265 WARN_ON(!base); 364 WARN_ON(!base);
@@ -283,8 +382,8 @@ int __init mx6q_clocks_init(void)
283 clk[gpu3d_shader_sel] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); 382 clk[gpu3d_shader_sel] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
284 clk[ipu1_sel] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); 383 clk[ipu1_sel] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
285 clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); 384 clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
286 clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); 385 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);
287 clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); 386 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);
288 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)); 387 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));
289 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)); 388 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));
290 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)); 389 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));
@@ -332,9 +431,9 @@ int __init mx6q_clocks_init(void)
332 clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); 431 clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3);
333 clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); 432 clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3);
334 clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); 433 clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
335 clk[ldb_di0_podf] = imx_clk_divider("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1); 434 clk[ldb_di0_podf] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0);
336 clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); 435 clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
337 clk[ldb_di1_podf] = imx_clk_divider("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1); 436 clk[ldb_di1_podf] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0);
338 clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3); 437 clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3);
339 clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3); 438 clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3);
340 clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3); 439 clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3);
@@ -443,12 +542,16 @@ int __init mx6q_clocks_init(void)
443 542
444 clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0"); 543 clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0");
445 clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); 544 clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
446 clk_register_clkdev(clk[twd], NULL, "smp_twd");
447 clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL); 545 clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL);
448 clk_register_clkdev(clk[ahb], "ahb", NULL); 546 clk_register_clkdev(clk[ahb], "ahb", NULL);
449 clk_register_clkdev(clk[cko1], "cko1", NULL); 547 clk_register_clkdev(clk[cko1], "cko1", NULL);
450 clk_register_clkdev(clk[arm], NULL, "cpu0"); 548 clk_register_clkdev(clk[arm], NULL, "cpu0");
451 549
550 if (imx6q_revision() != IMX_CHIP_REVISION_1_0) {
551 clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
552 clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
553 }
554
452 /* 555 /*
453 * The gpmi needs 100MHz frequency in the EDO/Sync mode, 556 * The gpmi needs 100MHz frequency in the EDO/Sync mode,
454 * We can not get the 100MHz from the pll2_pfd0_352m. 557 * We can not get the 100MHz from the pll2_pfd0_352m.
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index 9d1f3b99d1d3..d9d9d9c66dff 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,
59 reg, shift, width, 0, &imx_ccm_lock); 59 reg, shift, width, 0, &imx_ccm_lock);
60} 60}
61 61
62static inline struct clk *imx_clk_divider_flags(const char *name,
63 const char *parent, void __iomem *reg, u8 shift, u8 width,
64 unsigned long flags)
65{
66 return clk_register_divider(NULL, name, parent, flags,
67 reg, shift, width, 0, &imx_ccm_lock);
68}
69
62static inline struct clk *imx_clk_gate(const char *name, const char *parent, 70static inline struct clk *imx_clk_gate(const char *name, const char *parent,
63 void __iomem *reg, u8 shift) 71 void __iomem *reg, u8 shift)
64{ 72{
@@ -73,6 +81,15 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
73 width, 0, &imx_ccm_lock); 81 width, 0, &imx_ccm_lock);
74} 82}
75 83
84static inline struct clk *imx_clk_mux_flags(const char *name,
85 void __iomem *reg, u8 shift, u8 width, const char **parents,
86 int num_parents, unsigned long flags)
87{
88 return clk_register_mux(NULL, name, parents, num_parents,
89 flags, reg, shift, width, 0,
90 &imx_ccm_lock);
91}
92
76static inline struct clk *imx_clk_fixed_factor(const char *name, 93static inline struct clk *imx_clk_fixed_factor(const char *name,
77 const char *parent, unsigned int mult, unsigned int div) 94 const char *parent, unsigned int mult, unsigned int div)
78{ 95{
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 5a800bfcec5b..4cba7dbb079f 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. 2 * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
3 */ 3 */
4 4
5/* 5/*
@@ -74,6 +74,7 @@ extern void mxc_set_cpu_type(unsigned int type);
74extern void mxc_restart(char, const char *); 74extern void mxc_restart(char, const char *);
75extern void mxc_arch_reset_init(void __iomem *); 75extern void mxc_arch_reset_init(void __iomem *);
76extern int mx53_revision(void); 76extern int mx53_revision(void);
77extern int imx6q_revision(void);
77extern int mx53_display_revision(void); 78extern int mx53_display_revision(void);
78extern void imx_set_aips(void __iomem *); 79extern void imx_set_aips(void __iomem *);
79extern int mxc_device_init(void); 80extern int mxc_device_init(void);
@@ -110,8 +111,9 @@ void tzic_handle_irq(struct pt_regs *);
110 111
111extern void imx_enable_cpu(int cpu, bool enable); 112extern void imx_enable_cpu(int cpu, bool enable);
112extern void imx_set_cpu_jump(int cpu, void *jump_addr); 113extern void imx_set_cpu_jump(int cpu, void *jump_addr);
114extern u32 imx_get_cpu_arg(int cpu);
115extern void imx_set_cpu_arg(int cpu, u32 arg);
113extern void v7_cpu_resume(void); 116extern void v7_cpu_resume(void);
114extern u32 *pl310_get_save_ptr(void);
115#ifdef CONFIG_SMP 117#ifdef CONFIG_SMP
116extern void v7_secondary_startup(void); 118extern void v7_secondary_startup(void);
117extern void imx_scu_map_io(void); 119extern void imx_scu_map_io(void);
@@ -122,13 +124,18 @@ static inline void imx_scu_map_io(void) {}
122static inline void imx_smp_prepare(void) {} 124static inline void imx_smp_prepare(void) {}
123static inline void imx_scu_standby_enable(void) {} 125static inline void imx_scu_standby_enable(void) {}
124#endif 126#endif
125extern void imx_enable_cpu(int cpu, bool enable);
126extern void imx_set_cpu_jump(int cpu, void *jump_addr);
127extern void imx_src_init(void); 127extern void imx_src_init(void);
128extern void imx_src_prepare_restart(void); 128extern void imx_src_prepare_restart(void);
129extern void imx_gpc_init(void); 129extern void imx_gpc_init(void);
130extern void imx_gpc_pre_suspend(void); 130extern void imx_gpc_pre_suspend(void);
131extern void imx_gpc_post_resume(void); 131extern void imx_gpc_post_resume(void);
132extern void imx_gpc_mask_all(void);
133extern void imx_gpc_restore_all(void);
134extern void imx_anatop_init(void);
135extern void imx_anatop_pre_suspend(void);
136extern void imx_anatop_post_resume(void);
137extern void imx_anatop_usb_chrg_detect_disable(void);
138extern u32 imx_anatop_get_digprog(void);
132extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); 139extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
133extern void imx6q_set_chicken_bit(void); 140extern void imx6q_set_chicken_bit(void);
134 141
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 b9ef692b61a2..000000000000
--- a/arch/arm/mach-imx/cpu_op-mx51.c
+++ /dev/null
@@ -1,31 +0,0 @@
1/*
2 * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
3 */
4
5/*
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14#include <linux/bug.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17
18#include "hardware.h"
19
20static struct cpu_op mx51_cpu_op[] = {
21 {
22 .cpu_rate = 160000000,},
23 {
24 .cpu_rate = 800000000,},
25};
26
27struct cpu_op *mx51_get_cpu_op(int *op)
28{
29 *op = ARRAY_SIZE(mx51_cpu_op);
30 return mx51_cpu_op;
31}
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 97477fecb469..000000000000
--- a/arch/arm/mach-imx/cpu_op-mx51.h
+++ /dev/null
@@ -1,14 +0,0 @@
1/*
2 * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
3 */
4
5/*
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14extern 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 d8c75c3c925d..000000000000
--- a/arch/arm/mach-imx/cpufreq.c
+++ /dev/null
@@ -1,206 +0,0 @@
1/*
2 * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
3 */
4
5/*
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14/*
15 * A driver for the Freescale Semiconductor i.MXC CPUfreq module.
16 * The CPUFREQ driver is for controlling CPU frequency. It allows you to change
17 * the CPU clock speed on the fly.
18 */
19
20#include <linux/module.h>
21#include <linux/cpufreq.h>
22#include <linux/clk.h>
23#include <linux/err.h>
24#include <linux/slab.h>
25
26#include "hardware.h"
27
28#define CLK32_FREQ 32768
29#define NANOSECOND (1000 * 1000 * 1000)
30
31struct cpu_op *(*get_cpu_op)(int *op);
32
33static int cpu_freq_khz_min;
34static int cpu_freq_khz_max;
35
36static struct clk *cpu_clk;
37static struct cpufreq_frequency_table *imx_freq_table;
38
39static int cpu_op_nr;
40static struct cpu_op *cpu_op_tbl;
41
42static int set_cpu_freq(int freq)
43{
44 int ret = 0;
45 int org_cpu_rate;
46
47 org_cpu_rate = clk_get_rate(cpu_clk);
48 if (org_cpu_rate == freq)
49 return ret;
50
51 ret = clk_set_rate(cpu_clk, freq);
52 if (ret != 0) {
53 printk(KERN_DEBUG "cannot set CPU clock rate\n");
54 return ret;
55 }
56
57 return ret;
58}
59
60static int mxc_verify_speed(struct cpufreq_policy *policy)
61{
62 if (policy->cpu != 0)
63 return -EINVAL;
64
65 return cpufreq_frequency_table_verify(policy, imx_freq_table);
66}
67
68static unsigned int mxc_get_speed(unsigned int cpu)
69{
70 if (cpu)
71 return 0;
72
73 return clk_get_rate(cpu_clk) / 1000;
74}
75
76static int mxc_set_target(struct cpufreq_policy *policy,
77 unsigned int target_freq, unsigned int relation)
78{
79 struct cpufreq_freqs freqs;
80 int freq_Hz;
81 int ret = 0;
82 unsigned int index;
83
84 cpufreq_frequency_table_target(policy, imx_freq_table,
85 target_freq, relation, &index);
86 freq_Hz = imx_freq_table[index].frequency * 1000;
87
88 freqs.old = clk_get_rate(cpu_clk) / 1000;
89 freqs.new = freq_Hz / 1000;
90 freqs.cpu = 0;
91 freqs.flags = 0;
92 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
93
94 ret = set_cpu_freq(freq_Hz);
95
96 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
97
98 return ret;
99}
100
101static int mxc_cpufreq_init(struct cpufreq_policy *policy)
102{
103 int ret;
104 int i;
105
106 printk(KERN_INFO "i.MXC CPU frequency driver\n");
107
108 if (policy->cpu != 0)
109 return -EINVAL;
110
111 if (!get_cpu_op)
112 return -EINVAL;
113
114 cpu_clk = clk_get(NULL, "cpu_clk");
115 if (IS_ERR(cpu_clk)) {
116 printk(KERN_ERR "%s: failed to get cpu clock\n", __func__);
117 return PTR_ERR(cpu_clk);
118 }
119
120 cpu_op_tbl = get_cpu_op(&cpu_op_nr);
121
122 cpu_freq_khz_min = cpu_op_tbl[0].cpu_rate / 1000;
123 cpu_freq_khz_max = cpu_op_tbl[0].cpu_rate / 1000;
124
125 imx_freq_table = kmalloc(
126 sizeof(struct cpufreq_frequency_table) * (cpu_op_nr + 1),
127 GFP_KERNEL);
128 if (!imx_freq_table) {
129 ret = -ENOMEM;
130 goto err1;
131 }
132
133 for (i = 0; i < cpu_op_nr; i++) {
134 imx_freq_table[i].index = i;
135 imx_freq_table[i].frequency = cpu_op_tbl[i].cpu_rate / 1000;
136
137 if ((cpu_op_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min)
138 cpu_freq_khz_min = cpu_op_tbl[i].cpu_rate / 1000;
139
140 if ((cpu_op_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max)
141 cpu_freq_khz_max = cpu_op_tbl[i].cpu_rate / 1000;
142 }
143
144 imx_freq_table[i].index = i;
145 imx_freq_table[i].frequency = CPUFREQ_TABLE_END;
146
147 policy->cur = clk_get_rate(cpu_clk) / 1000;
148 policy->min = policy->cpuinfo.min_freq = cpu_freq_khz_min;
149 policy->max = policy->cpuinfo.max_freq = cpu_freq_khz_max;
150
151 /* Manual states, that PLL stabilizes in two CLK32 periods */
152 policy->cpuinfo.transition_latency = 2 * NANOSECOND / CLK32_FREQ;
153
154 ret = cpufreq_frequency_table_cpuinfo(policy, imx_freq_table);
155
156 if (ret < 0) {
157 printk(KERN_ERR "%s: failed to register i.MXC CPUfreq with error code %d\n",
158 __func__, ret);
159 goto err;
160 }
161
162 cpufreq_frequency_table_get_attr(imx_freq_table, policy->cpu);
163 return 0;
164err:
165 kfree(imx_freq_table);
166err1:
167 clk_put(cpu_clk);
168 return ret;
169}
170
171static int mxc_cpufreq_exit(struct cpufreq_policy *policy)
172{
173 cpufreq_frequency_table_put_attr(policy->cpu);
174
175 set_cpu_freq(cpu_freq_khz_max * 1000);
176 clk_put(cpu_clk);
177 kfree(imx_freq_table);
178 return 0;
179}
180
181static struct cpufreq_driver mxc_driver = {
182 .flags = CPUFREQ_STICKY,
183 .verify = mxc_verify_speed,
184 .target = mxc_set_target,
185 .get = mxc_get_speed,
186 .init = mxc_cpufreq_init,
187 .exit = mxc_cpufreq_exit,
188 .name = "imx",
189};
190
191static int mxc_cpufreq_driver_init(void)
192{
193 return cpufreq_register_driver(&mxc_driver);
194}
195
196static void mxc_cpufreq_driver_exit(void)
197{
198 cpufreq_unregister_driver(&mxc_driver);
199}
200
201module_init(mxc_cpufreq_driver_init);
202module_exit(mxc_cpufreq_driver_exit);
203
204MODULE_AUTHOR("Freescale Semiconductor Inc. Yong Shen <yong.shen@linaro.org>");
205MODULE_DESCRIPTION("CPUfreq driver for i.MX");
206MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-imx/devices/Kconfig b/arch/arm/mach-imx/devices/Kconfig
index 9b9ba1f4ffe1..3dd2b1b041d1 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
86 86
87config IMX_HAVE_PLATFORM_SPI_IMX 87config IMX_HAVE_PLATFORM_SPI_IMX
88 bool 88 bool
89
90config IMX_HAVE_PLATFORM_AHCI
91 bool
92 default y if ARCH_MX53
diff --git a/arch/arm/mach-imx/devices/Makefile b/arch/arm/mach-imx/devices/Makefile
index 6acf37e0c119..67416fb1dc69 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
29obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o 29obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o
30obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o 30obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o
31obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o 31obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o
32obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) += platform-ahci-imx.o
33obj-$(CONFIG_IMX_HAVE_PLATFORM_MX2_EMMA) += platform-mx2-emma.o 32obj-$(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 9bd5777ff0e7..453e20bc2657 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,
344 int irq, int irq_err); 344 int irq, int irq_err);
345struct platform_device *imx_add_imx_sdma(char *name, 345struct platform_device *imx_add_imx_sdma(char *name,
346 resource_size_t iobase, int irq, struct sdma_platform_data *pdata); 346 resource_size_t iobase, int irq, struct sdma_platform_data *pdata);
347
348#include <linux/ahci_platform.h>
349struct imx_ahci_imx_data {
350 const char *devid;
351 resource_size_t iobase;
352 resource_size_t irq;
353};
354struct platform_device *__init imx_add_ahci_imx(
355 const struct imx_ahci_imx_data *data,
356 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 3d87dd9c284a..000000000000
--- a/arch/arm/mach-imx/devices/platform-ahci-imx.c
+++ /dev/null
@@ -1,157 +0,0 @@
1/*
2 * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 */
4
5/*
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include <linux/io.h>
22#include <linux/clk.h>
23#include <linux/err.h>
24#include <linux/device.h>
25#include <linux/dma-mapping.h>
26#include <asm/sizes.h>
27
28#include "../hardware.h"
29#include "devices-common.h"
30
31#define imx_ahci_imx_data_entry_single(soc, _devid) \
32 { \
33 .devid = _devid, \
34 .iobase = soc ## _SATA_BASE_ADDR, \
35 .irq = soc ## _INT_SATA, \
36 }
37
38#ifdef CONFIG_SOC_IMX53
39const struct imx_ahci_imx_data imx53_ahci_imx_data __initconst =
40 imx_ahci_imx_data_entry_single(MX53, "imx53-ahci");
41#endif
42
43enum {
44 HOST_CAP = 0x00,
45 HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
46 HOST_PORTS_IMPL = 0x0c,
47 HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
48};
49
50static struct clk *sata_clk, *sata_ref_clk;
51
52/* AHCI module Initialization, if return 0, initialization is successful. */
53static int imx_sata_init(struct device *dev, void __iomem *addr)
54{
55 u32 tmpdata;
56 int ret = 0;
57 struct clk *clk;
58
59 sata_clk = clk_get(dev, "ahci");
60 if (IS_ERR(sata_clk)) {
61 dev_err(dev, "no sata clock.\n");
62 return PTR_ERR(sata_clk);
63 }
64 ret = clk_prepare_enable(sata_clk);
65 if (ret) {
66 dev_err(dev, "can't prepare/enable sata clock.\n");
67 goto put_sata_clk;
68 }
69
70 /* Get the AHCI SATA PHY CLK */
71 sata_ref_clk = clk_get(dev, "ahci_phy");
72 if (IS_ERR(sata_ref_clk)) {
73 dev_err(dev, "no sata ref clock.\n");
74 ret = PTR_ERR(sata_ref_clk);
75 goto release_sata_clk;
76 }
77 ret = clk_prepare_enable(sata_ref_clk);
78 if (ret) {
79 dev_err(dev, "can't prepare/enable sata ref clock.\n");
80 goto put_sata_ref_clk;
81 }
82
83 /* Get the AHB clock rate, and configure the TIMER1MS reg later */
84 clk = clk_get(dev, "ahci_dma");
85 if (IS_ERR(clk)) {
86 dev_err(dev, "no dma clock.\n");
87 ret = PTR_ERR(clk);
88 goto release_sata_ref_clk;
89 }
90 tmpdata = clk_get_rate(clk) / 1000;
91 clk_put(clk);
92
93 writel(tmpdata, addr + HOST_TIMER1MS);
94
95 tmpdata = readl(addr + HOST_CAP);
96 if (!(tmpdata & HOST_CAP_SSS)) {
97 tmpdata |= HOST_CAP_SSS;
98 writel(tmpdata, addr + HOST_CAP);
99 }
100
101 if (!(readl(addr + HOST_PORTS_IMPL) & 0x1))
102 writel((readl(addr + HOST_PORTS_IMPL) | 0x1),
103 addr + HOST_PORTS_IMPL);
104
105 return 0;
106
107release_sata_ref_clk:
108 clk_disable_unprepare(sata_ref_clk);
109put_sata_ref_clk:
110 clk_put(sata_ref_clk);
111release_sata_clk:
112 clk_disable_unprepare(sata_clk);
113put_sata_clk:
114 clk_put(sata_clk);
115
116 return ret;
117}
118
119static void imx_sata_exit(struct device *dev)
120{
121 clk_disable_unprepare(sata_ref_clk);
122 clk_put(sata_ref_clk);
123
124 clk_disable_unprepare(sata_clk);
125 clk_put(sata_clk);
126
127}
128struct platform_device *__init imx_add_ahci_imx(
129 const struct imx_ahci_imx_data *data,
130 const struct ahci_platform_data *pdata)
131{
132 struct resource res[] = {
133 {
134 .start = data->iobase,
135 .end = data->iobase + SZ_4K - 1,
136 .flags = IORESOURCE_MEM,
137 }, {
138 .start = data->irq,
139 .end = data->irq,
140 .flags = IORESOURCE_IRQ,
141 },
142 };
143
144 return imx_add_platform_device_dmamask(data->devid, 0,
145 res, ARRAY_SIZE(res),
146 pdata, sizeof(*pdata), DMA_BIT_MASK(32));
147}
148
149struct platform_device *__init imx53_add_ahci_imx(void)
150{
151 struct ahci_platform_data pdata = {
152 .init = imx_sata_init,
153 .exit = imx_sata_exit,
154 };
155
156 return imx_add_ahci_imx(&imx53_ahci_imx_data, &pdata);
157}
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index a96ccc7f5012..c20445c56032 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. 2 * Copyright 2011-2013 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd. 3 * Copyright 2011 Linaro Ltd.
4 * 4 *
5 * The code contained herein is licensed under the GNU General Public 5 * 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)
68 return 0; 68 return 0;
69} 69}
70 70
71void imx_gpc_mask_all(void)
72{
73 void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
74 int i;
75
76 for (i = 0; i < IMR_NUM; i++) {
77 gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
78 writel_relaxed(~0, reg_imr1 + i * 4);
79 }
80
81}
82
83void imx_gpc_restore_all(void)
84{
85 void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
86 int i;
87
88 for (i = 0; i < IMR_NUM; i++)
89 writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
90}
91
71static void imx_gpc_irq_unmask(struct irq_data *d) 92static void imx_gpc_irq_unmask(struct irq_data *d)
72{ 93{
73 void __iomem *reg; 94 void __iomem *reg;
diff --git a/arch/arm/mach-imx/hardware.h b/arch/arm/mach-imx/hardware.h
index 911e9b31b03f..356131f7b591 100644
--- a/arch/arm/mach-imx/hardware.h
+++ b/arch/arm/mach-imx/hardware.h
@@ -102,7 +102,6 @@
102 102
103#include "mxc.h" 103#include "mxc.h"
104 104
105#include "mx6q.h"
106#include "mx51.h" 105#include "mx51.h"
107#include "mx53.h" 106#include "mx53.h"
108#include "mx3x.h" 107#include "mx3x.h"
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c
index 7bc5fe15dda2..361a253e2b63 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)
46void imx_cpu_die(unsigned int cpu) 46void imx_cpu_die(unsigned int cpu)
47{ 47{
48 cpu_enter_lowpower(); 48 cpu_enter_lowpower();
49 /*
50 * We use the cpu jumping argument register to sync with
51 * imx_cpu_kill() which is running on cpu0 and waiting for
52 * the register being cleared to kill the cpu.
53 */
54 imx_set_cpu_arg(cpu, ~0);
49 cpu_do_idle(); 55 cpu_do_idle();
50} 56}
51 57
52int imx_cpu_kill(unsigned int cpu) 58int imx_cpu_kill(unsigned int cpu)
53{ 59{
60 unsigned long timeout = jiffies + msecs_to_jiffies(50);
61
62 while (imx_get_cpu_arg(cpu) == 0)
63 if (time_after(jiffies, timeout))
64 return 0;
54 imx_enable_cpu(cpu, false); 65 imx_enable_cpu(cpu, false);
66 imx_set_cpu_arg(cpu, 0);
55 return 1; 67 return 1;
56} 68}
diff --git a/arch/arm/mach-imx/mach-cpuimx51sd.c b/arch/arm/mach-imx/mach-cpuimx51sd.c
index 9b7393234f6f..9b5ddf5bbd33 100644
--- a/arch/arm/mach-imx/mach-cpuimx51sd.c
+++ b/arch/arm/mach-imx/mach-cpuimx51sd.c
@@ -33,7 +33,6 @@
33 33
34#include "common.h" 34#include "common.h"
35#include "devices-imx51.h" 35#include "devices-imx51.h"
36#include "cpu_op-mx51.h"
37#include "eukrea-baseboards.h" 36#include "eukrea-baseboards.h"
38#include "hardware.h" 37#include "hardware.h"
39#include "iomux-mx51.h" 38#include "iomux-mx51.h"
@@ -285,10 +284,6 @@ static void __init eukrea_cpuimx51sd_init(void)
285 mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads, 284 mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads,
286 ARRAY_SIZE(eukrea_cpuimx51sd_pads)); 285 ARRAY_SIZE(eukrea_cpuimx51sd_pads));
287 286
288#if defined(CONFIG_CPU_FREQ_IMX)
289 get_cpu_op = mx51_get_cpu_op;
290#endif
291
292 imx51_add_imx_uart(0, &uart_pdata); 287 imx51_add_imx_uart(0, &uart_pdata);
293 imx51_add_mxc_nand(&eukrea_cpuimx51sd_nand_board_info); 288 imx51_add_mxc_nand(&eukrea_cpuimx51sd_nand_board_info);
294 imx51_add_imx2_wdt(0); 289 imx51_add_imx2_wdt(0);
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index b59ddcb57c78..7230aede4ca2 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. 2 * Copyright 2011-2013 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd. 3 * Copyright 2011 Linaro Ltd.
4 * 4 *
5 * The code contained herein is licensed under the GNU General Public 5 * The code contained herein is licensed under the GNU General Public
@@ -38,38 +38,32 @@
38#include "cpuidle.h" 38#include "cpuidle.h"
39#include "hardware.h" 39#include "hardware.h"
40 40
41#define IMX6Q_ANALOG_DIGPROG 0x260 41static u32 chip_revision;
42 42
43static int imx6q_revision(void) 43int imx6q_revision(void)
44{ 44{
45 struct device_node *np; 45 return chip_revision;
46 void __iomem *base; 46}
47 static u32 rev; 47
48 48static void __init imx6q_init_revision(void)
49 if (!rev) { 49{
50 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); 50 u32 rev = imx_anatop_get_digprog();
51 if (!np)
52 return IMX_CHIP_REVISION_UNKNOWN;
53 base = of_iomap(np, 0);
54 if (!base) {
55 of_node_put(np);
56 return IMX_CHIP_REVISION_UNKNOWN;
57 }
58 rev = readl_relaxed(base + IMX6Q_ANALOG_DIGPROG);
59 iounmap(base);
60 of_node_put(np);
61 }
62 51
63 switch (rev & 0xff) { 52 switch (rev & 0xff) {
64 case 0: 53 case 0:
65 return IMX_CHIP_REVISION_1_0; 54 chip_revision = IMX_CHIP_REVISION_1_0;
55 break;
66 case 1: 56 case 1:
67 return IMX_CHIP_REVISION_1_1; 57 chip_revision = IMX_CHIP_REVISION_1_1;
58 break;
68 case 2: 59 case 2:
69 return IMX_CHIP_REVISION_1_2; 60 chip_revision = IMX_CHIP_REVISION_1_2;
61 break;
70 default: 62 default:
71 return IMX_CHIP_REVISION_UNKNOWN; 63 chip_revision = IMX_CHIP_REVISION_UNKNOWN;
72 } 64 }
65
66 mxc_set_cpu_type(rev >> 16 & 0xff);
73} 67}
74 68
75void imx6q_restart(char mode, const char *cmd) 69void imx6q_restart(char mode, const char *cmd)
@@ -164,29 +158,7 @@ static void __init imx6q_1588_init(void)
164} 158}
165static void __init imx6q_usb_init(void) 159static void __init imx6q_usb_init(void)
166{ 160{
167 struct regmap *anatop; 161 imx_anatop_usb_chrg_detect_disable();
168
169#define HW_ANADIG_USB1_CHRG_DETECT 0x000001b0
170#define HW_ANADIG_USB2_CHRG_DETECT 0x00000210
171
172#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x00100000
173#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x00080000
174
175 anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
176 if (!IS_ERR(anatop)) {
177 /*
178 * The external charger detector needs to be disabled,
179 * or the signal at DP will be poor
180 */
181 regmap_write(anatop, HW_ANADIG_USB1_CHRG_DETECT,
182 BM_ANADIG_USB_CHRG_DETECT_EN_B
183 | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
184 regmap_write(anatop, HW_ANADIG_USB2_CHRG_DETECT,
185 BM_ANADIG_USB_CHRG_DETECT_EN_B |
186 BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
187 } else {
188 pr_warn("failed to find fsl,imx6q-anatop regmap\n");
189 }
190} 162}
191 163
192static void __init imx6q_init_machine(void) 164static void __init imx6q_init_machine(void)
@@ -196,6 +168,7 @@ static void __init imx6q_init_machine(void)
196 168
197 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 169 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
198 170
171 imx_anatop_init();
199 imx6q_pm_init(); 172 imx6q_pm_init();
200 imx6q_usb_init(); 173 imx6q_usb_init();
201 imx6q_1588_init(); 174 imx6q_1588_init();
@@ -282,6 +255,7 @@ static void __init imx6q_map_io(void)
282 255
283static void __init imx6q_init_irq(void) 256static void __init imx6q_init_irq(void)
284{ 257{
258 imx6q_init_revision();
285 l2x0_of_init(0, ~0UL); 259 l2x0_of_init(0, ~0UL);
286 imx_src_init(); 260 imx_src_init();
287 imx_gpc_init(); 261 imx_gpc_init();
@@ -292,15 +266,17 @@ static void __init imx6q_timer_init(void)
292{ 266{
293 mx6q_clocks_init(); 267 mx6q_clocks_init();
294 clocksource_of_init(); 268 clocksource_of_init();
295 imx_print_silicon_rev("i.MX6Q", imx6q_revision()); 269 imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
270 imx6q_revision());
296} 271}
297 272
298static const char *imx6q_dt_compat[] __initdata = { 273static const char *imx6q_dt_compat[] __initdata = {
274 "fsl,imx6dl",
299 "fsl,imx6q", 275 "fsl,imx6q",
300 NULL, 276 NULL,
301}; 277};
302 278
303DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)") 279DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
304 .smp = smp_ops(imx_smp_ops), 280 .smp = smp_ops(imx_smp_ops),
305 .map_io = imx6q_map_io, 281 .map_io = imx6q_map_io,
306 .init_irq = imx6q_init_irq, 282 .init_irq = imx6q_init_irq,
diff --git a/arch/arm/mach-imx/mach-mx51_babbage.c b/arch/arm/mach-imx/mach-mx51_babbage.c
index 6c4d7feb4520..f3d264a636fa 100644
--- a/arch/arm/mach-imx/mach-mx51_babbage.c
+++ b/arch/arm/mach-imx/mach-mx51_babbage.c
@@ -27,7 +27,6 @@
27 27
28#include "common.h" 28#include "common.h"
29#include "devices-imx51.h" 29#include "devices-imx51.h"
30#include "cpu_op-mx51.h"
31#include "hardware.h" 30#include "hardware.h"
32#include "iomux-mx51.h" 31#include "iomux-mx51.h"
33 32
@@ -371,9 +370,6 @@ static void __init mx51_babbage_init(void)
371 370
372 imx51_soc_init(); 371 imx51_soc_init();
373 372
374#if defined(CONFIG_CPU_FREQ_IMX)
375 get_cpu_op = mx51_get_cpu_op;
376#endif
377 imx51_babbage_common_init(); 373 imx51_babbage_common_init();
378 374
379 imx51_add_imx_uart(0, &uart_pdata); 375 imx51_add_imx_uart(0, &uart_pdata);
diff --git a/arch/arm/mach-imx/mm-imx1.c b/arch/arm/mach-imx/mm-imx1.c
index 7a146671e65a..3c609c52d3eb 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)
51 51
52void __init imx1_soc_init(void) 52void __init imx1_soc_init(void)
53{ 53{
54 mxc_device_init();
55
54 mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256, 56 mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256,
55 MX1_GPIO_INT_PORTA, 0); 57 MX1_GPIO_INT_PORTA, 0);
56 mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256, 58 mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256,
diff --git a/arch/arm/mach-imx/mx6q.h b/arch/arm/mach-imx/mx6q.h
deleted file mode 100644
index 19d3f54db5af..000000000000
--- a/arch/arm/mach-imx/mx6q.h
+++ /dev/null
@@ -1,31 +0,0 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#ifndef __MACH_MX6Q_H__
14#define __MACH_MX6Q_H__
15
16#define MX6Q_IO_P2V(x) IMX_IO_P2V(x)
17#define MX6Q_IO_ADDRESS(x) IOMEM(MX6Q_IO_P2V(x))
18
19/*
20 * The following are the blocks that need to be statically mapped.
21 * For other blocks, the base address really should be retrieved from
22 * device tree.
23 */
24#define MX6Q_SCU_BASE_ADDR 0x00a00000
25#define MX6Q_SCU_SIZE 0x1000
26#define MX6Q_CCM_BASE_ADDR 0x020c4000
27#define MX6Q_CCM_SIZE 0x4000
28#define MX6Q_ANATOP_BASE_ADDR 0x020c8000
29#define MX6Q_ANATOP_SIZE 0x1000
30
31#endif /* __MACH_MX6Q_H__ */
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h
index 7dce17a9fe6c..8629e5be7ecd 100644
--- a/arch/arm/mach-imx/mxc.h
+++ b/arch/arm/mach-imx/mxc.h
@@ -34,6 +34,8 @@
34#define MXC_CPU_MX35 35 34#define MXC_CPU_MX35 35
35#define MXC_CPU_MX51 51 35#define MXC_CPU_MX51 51
36#define MXC_CPU_MX53 53 36#define MXC_CPU_MX53 53
37#define MXC_CPU_IMX6DL 0x61
38#define MXC_CPU_IMX6Q 0x63
37 39
38#define IMX_CHIP_REVISION_1_0 0x10 40#define IMX_CHIP_REVISION_1_0 0x10
39#define IMX_CHIP_REVISION_1_1 0x11 41#define IMX_CHIP_REVISION_1_1 0x11
@@ -150,6 +152,15 @@ extern unsigned int __mxc_cpu_type;
150#endif 152#endif
151 153
152#ifndef __ASSEMBLY__ 154#ifndef __ASSEMBLY__
155static inline bool cpu_is_imx6dl(void)
156{
157 return __mxc_cpu_type == MXC_CPU_IMX6DL;
158}
159
160static inline bool cpu_is_imx6q(void)
161{
162 return __mxc_cpu_type == MXC_CPU_IMX6Q;
163}
153 164
154struct cpu_op { 165struct cpu_op {
155 u32 cpu_rate; 166 u32 cpu_rate;
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
index 77e9a25ed0f6..4a69305db65e 100644
--- a/arch/arm/mach-imx/platsmp.c
+++ b/arch/arm/mach-imx/platsmp.c
@@ -68,8 +68,8 @@ static void __init imx_smp_init_cpus(void)
68 68
69 ncores = scu_get_core_count(scu_base); 69 ncores = scu_get_core_count(scu_base);
70 70
71 for (i = 0; i < ncores; i++) 71 for (i = ncores; i < NR_CPUS; i++)
72 set_cpu_possible(i, true); 72 set_cpu_possible(i, false);
73} 73}
74 74
75void imx_smp_prepare(void) 75void imx_smp_prepare(void)
diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c
index 5faba7a3c95f..204942749e21 100644
--- a/arch/arm/mach-imx/pm-imx6q.c
+++ b/arch/arm/mach-imx/pm-imx6q.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. 2 * Copyright 2011-2013 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd. 3 * Copyright 2011 Linaro Ltd.
4 * 4 *
5 * The code contained herein is licensed under the GNU General Public 5 * The code contained herein is licensed under the GNU General Public
@@ -34,10 +34,12 @@ static int imx6q_pm_enter(suspend_state_t state)
34 case PM_SUSPEND_MEM: 34 case PM_SUSPEND_MEM:
35 imx6q_set_lpm(STOP_POWER_OFF); 35 imx6q_set_lpm(STOP_POWER_OFF);
36 imx_gpc_pre_suspend(); 36 imx_gpc_pre_suspend();
37 imx_anatop_pre_suspend();
37 imx_set_cpu_jump(0, v7_cpu_resume); 38 imx_set_cpu_jump(0, v7_cpu_resume);
38 /* Zzz ... */ 39 /* Zzz ... */
39 cpu_suspend(0, imx6q_suspend_finish); 40 cpu_suspend(0, imx6q_suspend_finish);
40 imx_smp_prepare(); 41 imx_smp_prepare();
42 imx_anatop_post_resume();
41 imx_gpc_post_resume(); 43 imx_gpc_post_resume();
42 imx6q_set_lpm(WAIT_CLOCKED); 44 imx6q_set_lpm(WAIT_CLOCKED);
43 break; 45 break;
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
index e15f1555c59b..dec641108b54 100644
--- a/arch/arm/mach-imx/src.c
+++ b/arch/arm/mach-imx/src.c
@@ -14,16 +14,72 @@
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_address.h> 16#include <linux/of_address.h>
17#include <linux/reset-controller.h>
17#include <linux/smp.h> 18#include <linux/smp.h>
18#include <asm/smp_plat.h> 19#include <asm/smp_plat.h>
19 20
20#define SRC_SCR 0x000 21#define SRC_SCR 0x000
21#define SRC_GPR1 0x020 22#define SRC_GPR1 0x020
22#define BP_SRC_SCR_WARM_RESET_ENABLE 0 23#define BP_SRC_SCR_WARM_RESET_ENABLE 0
24#define BP_SRC_SCR_SW_GPU_RST 1
25#define BP_SRC_SCR_SW_VPU_RST 2
26#define BP_SRC_SCR_SW_IPU1_RST 3
27#define BP_SRC_SCR_SW_OPEN_VG_RST 4
28#define BP_SRC_SCR_SW_IPU2_RST 12
23#define BP_SRC_SCR_CORE1_RST 14 29#define BP_SRC_SCR_CORE1_RST 14
24#define BP_SRC_SCR_CORE1_ENABLE 22 30#define BP_SRC_SCR_CORE1_ENABLE 22
25 31
26static void __iomem *src_base; 32static void __iomem *src_base;
33static DEFINE_SPINLOCK(scr_lock);
34
35static const int sw_reset_bits[5] = {
36 BP_SRC_SCR_SW_GPU_RST,
37 BP_SRC_SCR_SW_VPU_RST,
38 BP_SRC_SCR_SW_IPU1_RST,
39 BP_SRC_SCR_SW_OPEN_VG_RST,
40 BP_SRC_SCR_SW_IPU2_RST
41};
42
43static int imx_src_reset_module(struct reset_controller_dev *rcdev,
44 unsigned long sw_reset_idx)
45{
46 unsigned long timeout;
47 unsigned long flags;
48 int bit;
49 u32 val;
50
51 if (!src_base)
52 return -ENODEV;
53
54 if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits))
55 return -EINVAL;
56
57 bit = 1 << sw_reset_bits[sw_reset_idx];
58
59 spin_lock_irqsave(&scr_lock, flags);
60 val = readl_relaxed(src_base + SRC_SCR);
61 val |= bit;
62 writel_relaxed(val, src_base + SRC_SCR);
63 spin_unlock_irqrestore(&scr_lock, flags);
64
65 timeout = jiffies + msecs_to_jiffies(1000);
66 while (readl(src_base + SRC_SCR) & bit) {
67 if (time_after(jiffies, timeout))
68 return -ETIME;
69 cpu_relax();
70 }
71
72 return 0;
73}
74
75static struct reset_control_ops imx_src_ops = {
76 .reset = imx_src_reset_module,
77};
78
79static struct reset_controller_dev imx_reset_controller = {
80 .ops = &imx_src_ops,
81 .nr_resets = ARRAY_SIZE(sw_reset_bits),
82};
27 83
28void imx_enable_cpu(int cpu, bool enable) 84void imx_enable_cpu(int cpu, bool enable)
29{ 85{
@@ -31,9 +87,11 @@ void imx_enable_cpu(int cpu, bool enable)
31 87
32 cpu = cpu_logical_map(cpu); 88 cpu = cpu_logical_map(cpu);
33 mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1); 89 mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
90 spin_lock(&scr_lock);
34 val = readl_relaxed(src_base + SRC_SCR); 91 val = readl_relaxed(src_base + SRC_SCR);
35 val = enable ? val | mask : val & ~mask; 92 val = enable ? val | mask : val & ~mask;
36 writel_relaxed(val, src_base + SRC_SCR); 93 writel_relaxed(val, src_base + SRC_SCR);
94 spin_unlock(&scr_lock);
37} 95}
38 96
39void imx_set_cpu_jump(int cpu, void *jump_addr) 97void imx_set_cpu_jump(int cpu, void *jump_addr)
@@ -43,14 +101,28 @@ void imx_set_cpu_jump(int cpu, void *jump_addr)
43 src_base + SRC_GPR1 + cpu * 8); 101 src_base + SRC_GPR1 + cpu * 8);
44} 102}
45 103
104u32 imx_get_cpu_arg(int cpu)
105{
106 cpu = cpu_logical_map(cpu);
107 return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4);
108}
109
110void imx_set_cpu_arg(int cpu, u32 arg)
111{
112 cpu = cpu_logical_map(cpu);
113 writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4);
114}
115
46void imx_src_prepare_restart(void) 116void imx_src_prepare_restart(void)
47{ 117{
48 u32 val; 118 u32 val;
49 119
50 /* clear enable bits of secondary cores */ 120 /* clear enable bits of secondary cores */
121 spin_lock(&scr_lock);
51 val = readl_relaxed(src_base + SRC_SCR); 122 val = readl_relaxed(src_base + SRC_SCR);
52 val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE); 123 val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE);
53 writel_relaxed(val, src_base + SRC_SCR); 124 writel_relaxed(val, src_base + SRC_SCR);
125 spin_unlock(&scr_lock);
54 126
55 /* clear persistent entry register of primary core */ 127 /* clear persistent entry register of primary core */
56 writel_relaxed(0, src_base + SRC_GPR1); 128 writel_relaxed(0, src_base + SRC_GPR1);
@@ -65,11 +137,16 @@ void __init imx_src_init(void)
65 src_base = of_iomap(np, 0); 137 src_base = of_iomap(np, 0);
66 WARN_ON(!src_base); 138 WARN_ON(!src_base);
67 139
140 imx_reset_controller.of_node = np;
141 reset_controller_register(&imx_reset_controller);
142
68 /* 143 /*
69 * force warm reset sources to generate cold reset 144 * force warm reset sources to generate cold reset
70 * for a more reliable restart 145 * for a more reliable restart
71 */ 146 */
147 spin_lock(&scr_lock);
72 val = readl_relaxed(src_base + SRC_SCR); 148 val = readl_relaxed(src_base + SRC_SCR);
73 val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE); 149 val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE);
74 writel_relaxed(val, src_base + SRC_SCR); 150 writel_relaxed(val, src_base + SRC_SCR);
151 spin_unlock(&scr_lock);
75} 152}