aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2013-12-16 05:04:49 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2013-12-16 05:04:49 -0500
commit348324c5b10bcba8d9daabdfb85a6927311be34f (patch)
treed06ca3a264407a14a1f36c1b798d6dc0dc1582d8 /arch/arm/mach-imx
parent1e63bd9cc43db5400a1423a7ec8266b4e7c54bd0 (diff)
parent319e2e3f63c348a9b66db4667efa73178e18b17d (diff)
Merge tag 'v3.13-rc4' into next
Synchronize with mainline to bring in the new keycode definitions and new hwmon API.
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/Kconfig15
-rw-r--r--arch/arm/mach-imx/Makefile2
-rw-r--r--arch/arm/mach-imx/anatop.c33
-rw-r--r--arch/arm/mach-imx/clk-imx51-imx53.c42
-rw-r--r--arch/arm/mach-imx/clk-imx6q.c197
-rw-r--r--arch/arm/mach-imx/clk-imx6sl.c3
-rw-r--r--arch/arm/mach-imx/clk-pllv3.c51
-rw-r--r--arch/arm/mach-imx/common.h185
-rw-r--r--arch/arm/mach-imx/cpu.c95
-rw-r--r--arch/arm/mach-imx/epit.c2
-rw-r--r--arch/arm/mach-imx/gpc.c4
-rw-r--r--arch/arm/mach-imx/hotplug.c4
-rw-r--r--arch/arm/mach-imx/imx51-dt.c6
-rw-r--r--arch/arm/mach-imx/mach-armadillo5x0.c3
-rw-r--r--arch/arm/mach-imx/mach-imx53.c6
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c93
-rw-r--r--arch/arm/mach-imx/mach-imx6sl.c40
-rw-r--r--arch/arm/mach-imx/mach-mx31_3ds.c2
-rw-r--r--arch/arm/mach-imx/mach-pca100.c2
-rw-r--r--arch/arm/mach-imx/mach-pcm037.c5
-rw-r--r--arch/arm/mach-imx/mach-pcm038.c2
-rw-r--r--arch/arm/mach-imx/mach-pcm043.c2
-rw-r--r--arch/arm/mach-imx/mach-vf610.c9
-rw-r--r--arch/arm/mach-imx/mach-vpr200.c2
-rw-r--r--arch/arm/mach-imx/mm-imx5.c19
-rw-r--r--arch/arm/mach-imx/mx31lilly-db.c3
-rw-r--r--arch/arm/mach-imx/mxc.h6
-rw-r--r--arch/arm/mach-imx/pm-imx6q.c176
-rw-r--r--arch/arm/mach-imx/src.c16
-rw-r--r--arch/arm/mach-imx/system.c9
-rw-r--r--arch/arm/mach-imx/time.c2
31 files changed, 585 insertions, 451 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 29a8af6922a8..7a6e6f710068 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -4,13 +4,14 @@ config ARCH_MXC
4 select ARM_CPU_SUSPEND if PM 4 select ARM_CPU_SUSPEND if PM
5 select ARM_PATCH_PHYS_VIRT 5 select ARM_PATCH_PHYS_VIRT
6 select AUTO_ZRELADDR if !ZBOOT_ROM 6 select AUTO_ZRELADDR if !ZBOOT_ROM
7 select CLKDEV_LOOKUP
8 select CLKSRC_MMIO 7 select CLKSRC_MMIO
8 select COMMON_CLK
9 select GENERIC_ALLOCATOR 9 select GENERIC_ALLOCATOR
10 select GENERIC_CLOCKEVENTS 10 select GENERIC_CLOCKEVENTS
11 select GENERIC_IRQ_CHIP 11 select GENERIC_IRQ_CHIP
12 select MIGHT_HAVE_CACHE_L2X0 if ARCH_MULTI_V6_V7 12 select MIGHT_HAVE_CACHE_L2X0 if ARCH_MULTI_V6_V7
13 select MULTI_IRQ_HANDLER 13 select MULTI_IRQ_HANDLER
14 select SOC_BUS
14 select SPARSE_IRQ 15 select SPARSE_IRQ
15 select USE_OF 16 select USE_OF
16 help 17 help
@@ -24,7 +25,7 @@ config MXC_IRQ_PRIOR
24 help 25 help
25 Select this if you want to use prioritized IRQ handling. 26 Select this if you want to use prioritized IRQ handling.
26 This feature prevents higher priority ISR to be interrupted 27 This feature prevents higher priority ISR to be interrupted
27 by lower priority IRQ even IRQF_DISABLED flag is not set. 28 by lower priority IRQ.
28 This may be useful in embedded applications, where are strong 29 This may be useful in embedded applications, where are strong
29 requirements for timing. 30 requirements for timing.
30 Say N here, unless you have a specialized requirement. 31 Say N here, unless you have a specialized requirement.
@@ -92,14 +93,12 @@ config MACH_MX27
92config SOC_IMX1 93config SOC_IMX1
93 bool 94 bool
94 select ARCH_MX1 95 select ARCH_MX1
95 select COMMON_CLK
96 select CPU_ARM920T 96 select CPU_ARM920T
97 select IMX_HAVE_IOMUX_V1 97 select IMX_HAVE_IOMUX_V1
98 select MXC_AVIC 98 select MXC_AVIC
99 99
100config SOC_IMX21 100config SOC_IMX21
101 bool 101 bool
102 select COMMON_CLK
103 select CPU_ARM926T 102 select CPU_ARM926T
104 select IMX_HAVE_IOMUX_V1 103 select IMX_HAVE_IOMUX_V1
105 select MXC_AVIC 104 select MXC_AVIC
@@ -108,7 +107,6 @@ config SOC_IMX25
108 bool 107 bool
109 select ARCH_MX25 108 select ARCH_MX25
110 select ARCH_MXC_IOMUX_V3 109 select ARCH_MXC_IOMUX_V3
111 select COMMON_CLK
112 select CPU_ARM926T 110 select CPU_ARM926T
113 select MXC_AVIC 111 select MXC_AVIC
114 112
@@ -116,7 +114,6 @@ config SOC_IMX27
116 bool 114 bool
117 select ARCH_HAS_CPUFREQ 115 select ARCH_HAS_CPUFREQ
118 select ARCH_HAS_OPP 116 select ARCH_HAS_OPP
119 select COMMON_CLK
120 select CPU_ARM926T 117 select CPU_ARM926T
121 select IMX_HAVE_IOMUX_V1 118 select IMX_HAVE_IOMUX_V1
122 select MACH_MX27 119 select MACH_MX27
@@ -124,7 +121,6 @@ config SOC_IMX27
124 121
125config SOC_IMX31 122config SOC_IMX31
126 bool 123 bool
127 select COMMON_CLK
128 select CPU_V6 124 select CPU_V6
129 select IMX_HAVE_PLATFORM_MXC_RNGA 125 select IMX_HAVE_PLATFORM_MXC_RNGA
130 select MXC_AVIC 126 select MXC_AVIC
@@ -133,7 +129,6 @@ config SOC_IMX31
133config SOC_IMX35 129config SOC_IMX35
134 bool 130 bool
135 select ARCH_MXC_IOMUX_V3 131 select ARCH_MXC_IOMUX_V3
136 select COMMON_CLK
137 select CPU_V6K 132 select CPU_V6K
138 select HAVE_EPIT 133 select HAVE_EPIT
139 select MXC_AVIC 134 select MXC_AVIC
@@ -144,7 +139,6 @@ config SOC_IMX5
144 select ARCH_HAS_CPUFREQ 139 select ARCH_HAS_CPUFREQ
145 select ARCH_HAS_OPP 140 select ARCH_HAS_OPP
146 select ARCH_MXC_IOMUX_V3 141 select ARCH_MXC_IOMUX_V3
147 select COMMON_CLK
148 select CPU_V7 142 select CPU_V7
149 select MXC_TZIC 143 select MXC_TZIC
150 144
@@ -791,7 +785,6 @@ config SOC_IMX6Q
791 select ARM_ERRATA_764369 if SMP 785 select ARM_ERRATA_764369 if SMP
792 select ARM_ERRATA_775420 786 select ARM_ERRATA_775420
793 select ARM_GIC 787 select ARM_GIC
794 select COMMON_CLK
795 select CPU_V7 788 select CPU_V7
796 select HAVE_ARM_SCU if SMP 789 select HAVE_ARM_SCU if SMP
797 select HAVE_ARM_TWD if SMP 790 select HAVE_ARM_TWD if SMP
@@ -801,6 +794,8 @@ config SOC_IMX6Q
801 select HAVE_IMX_SRC 794 select HAVE_IMX_SRC
802 select HAVE_SMP 795 select HAVE_SMP
803 select MFD_SYSCON 796 select MFD_SYSCON
797 select MIGHT_HAVE_PCI
798 select PCI_DOMAINS if PCI
804 select PINCTRL 799 select PINCTRL
805 select PINCTRL_IMX6Q 800 select PINCTRL_IMX6Q
806 select PL310_ERRATA_588369 if CACHE_PL310 801 select PL310_ERRATA_588369 if CACHE_PL310
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 5383c589ad71..1789e2b31903 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -102,6 +102,8 @@ obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
102 102
103ifeq ($(CONFIG_PM),y) 103ifeq ($(CONFIG_PM),y)
104obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o 104obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
105# i.MX6SL reuses i.MX6Q code
106obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o headsmp.o
105endif 107endif
106 108
107# i.MX5 based machines 109# i.MX5 based machines
diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c
index ad3b755abb78..4a40bbb46183 100644
--- a/arch/arm/mach-imx/anatop.c
+++ b/arch/arm/mach-imx/anatop.c
@@ -16,6 +16,7 @@
16#include <linux/mfd/syscon.h> 16#include <linux/mfd/syscon.h>
17#include <linux/regmap.h> 17#include <linux/regmap.h>
18#include "common.h" 18#include "common.h"
19#include "hardware.h"
19 20
20#define REG_SET 0x4 21#define REG_SET 0x4
21#define REG_CLR 0x8 22#define REG_CLR 0x8
@@ -26,6 +27,7 @@
26#define ANADIG_USB1_CHRG_DETECT 0x1b0 27#define ANADIG_USB1_CHRG_DETECT 0x1b0
27#define ANADIG_USB2_CHRG_DETECT 0x210 28#define ANADIG_USB2_CHRG_DETECT 0x210
28#define ANADIG_DIGPROG 0x260 29#define ANADIG_DIGPROG 0x260
30#define ANADIG_DIGPROG_IMX6SL 0x280
29 31
30#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 32#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000
31#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000 33#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000
@@ -76,21 +78,38 @@ static void imx_anatop_usb_chrg_detect_disable(void)
76 BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); 78 BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
77} 79}
78 80
79u32 imx_anatop_get_digprog(void) 81void __init imx_init_revision_from_anatop(void)
80{ 82{
81 struct device_node *np; 83 struct device_node *np;
82 void __iomem *anatop_base; 84 void __iomem *anatop_base;
83 static u32 digprog; 85 unsigned int revision;
84 86 u32 digprog;
85 if (digprog) 87 u16 offset = ANADIG_DIGPROG;
86 return digprog;
87 88
88 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); 89 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
89 anatop_base = of_iomap(np, 0); 90 anatop_base = of_iomap(np, 0);
90 WARN_ON(!anatop_base); 91 WARN_ON(!anatop_base);
91 digprog = readl_relaxed(anatop_base + ANADIG_DIGPROG); 92 if (of_device_is_compatible(np, "fsl,imx6sl-anatop"))
93 offset = ANADIG_DIGPROG_IMX6SL;
94 digprog = readl_relaxed(anatop_base + offset);
95 iounmap(anatop_base);
96
97 switch (digprog & 0xff) {
98 case 0:
99 revision = IMX_CHIP_REVISION_1_0;
100 break;
101 case 1:
102 revision = IMX_CHIP_REVISION_1_1;
103 break;
104 case 2:
105 revision = IMX_CHIP_REVISION_1_2;
106 break;
107 default:
108 revision = IMX_CHIP_REVISION_UNKNOWN;
109 }
92 110
93 return digprog; 111 mxc_set_cpu_type(digprog >> 16 & 0xff);
112 imx_set_soc_revision(revision);
94} 113}
95 114
96void __init imx_anatop_init(void) 115void __init imx_anatop_init(void)
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index 7c0dc4540aa4..ce37af26ff8c 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -11,8 +11,12 @@
11#include <linux/clk.h> 11#include <linux/clk.h>
12#include <linux/io.h> 12#include <linux/io.h>
13#include <linux/clkdev.h> 13#include <linux/clkdev.h>
14#include <linux/clk-provider.h>
14#include <linux/of.h> 15#include <linux/of.h>
15#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/of.h>
18#include <linux/of_address.h>
19#include <linux/of_irq.h>
16 20
17#include "crm-regs-imx5.h" 21#include "crm-regs-imx5.h"
18#include "clk.h" 22#include "clk.h"
@@ -131,8 +135,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
131{ 135{
132 int i; 136 int i;
133 137
134 of_clk_init(NULL);
135
136 clk[dummy] = imx_clk_fixed("dummy", 0); 138 clk[dummy] = imx_clk_fixed("dummy", 0);
137 clk[ckil] = imx_obtain_fixed_clock("ckil", rate_ckil); 139 clk[ckil] = imx_obtain_fixed_clock("ckil", rate_ckil);
138 clk[osc] = imx_obtain_fixed_clock("osc", rate_osc); 140 clk[osc] = imx_obtain_fixed_clock("osc", rate_osc);
@@ -465,12 +467,17 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
465 return 0; 467 return 0;
466} 468}
467 469
468int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, 470static void __init mx51_clocks_init_dt(struct device_node *np)
469 unsigned long rate_ckih1, unsigned long rate_ckih2)
470{ 471{
471 int i; 472 mx51_clocks_init(0, 0, 0, 0);
473}
474CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init_dt);
475
476static void __init mx53_clocks_init(struct device_node *np)
477{
478 int i, irq;
472 unsigned long r; 479 unsigned long r;
473 struct device_node *np; 480 void __iomem *base;
474 481
475 clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE); 482 clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE);
476 clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE); 483 clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE);
@@ -529,12 +536,11 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
529 pr_err("i.MX53 clk %d: register failed with %ld\n", 536 pr_err("i.MX53 clk %d: register failed with %ld\n",
530 i, PTR_ERR(clk[i])); 537 i, PTR_ERR(clk[i]));
531 538
532 np = of_find_compatible_node(NULL, NULL, "fsl,imx53-ccm");
533 clk_data.clks = clk; 539 clk_data.clks = clk;
534 clk_data.clk_num = ARRAY_SIZE(clk); 540 clk_data.clk_num = ARRAY_SIZE(clk);
535 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 541 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
536 542
537 mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2); 543 mx5_clocks_common_init(0, 0, 0, 0);
538 544
539 clk_register_clkdev(clk[vpu_gate], NULL, "imx53-vpu.0"); 545 clk_register_clkdev(clk[vpu_gate], NULL, "imx53-vpu.0");
540 clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2"); 546 clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2");
@@ -557,9 +563,6 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
557 clk_set_rate(clk[esdhc_a_podf], 200000000); 563 clk_set_rate(clk[esdhc_a_podf], 200000000);
558 clk_set_rate(clk[esdhc_b_podf], 200000000); 564 clk_set_rate(clk[esdhc_b_podf], 200000000);
559 565
560 /* System timer */
561 mxc_timer_init(MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), MX53_INT_GPT);
562
563 clk_prepare_enable(clk[iim_gate]); 566 clk_prepare_enable(clk[iim_gate]);
564 imx_print_silicon_rev("i.MX53", mx53_revision()); 567 imx_print_silicon_rev("i.MX53", mx53_revision());
565 clk_disable_unprepare(clk[iim_gate]); 568 clk_disable_unprepare(clk[iim_gate]);
@@ -567,15 +570,10 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
567 r = clk_round_rate(clk[usboh3_per_gate], 54000000); 570 r = clk_round_rate(clk[usboh3_per_gate], 54000000);
568 clk_set_rate(clk[usboh3_per_gate], r); 571 clk_set_rate(clk[usboh3_per_gate], r);
569 572
570 return 0; 573 np = of_find_compatible_node(NULL, NULL, "fsl,imx53-gpt");
571} 574 base = of_iomap(np, 0);
572 575 WARN_ON(!base);
573int __init mx51_clocks_init_dt(void) 576 irq = irq_of_parse_and_map(np, 0);
574{ 577 mxc_timer_init(base, irq);
575 return mx51_clocks_init(0, 0, 0, 0);
576}
577
578int __init mx53_clocks_init_dt(void)
579{
580 return mx53_clocks_init(0, 0, 0, 0);
581} 578}
579CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init);
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 9181a241d3a8..04cfd0fcb0e5 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -14,7 +14,6 @@
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>
18#include <linux/err.h> 17#include <linux/err.h>
19#include <linux/io.h> 18#include <linux/io.h>
20#include <linux/of.h> 19#include <linux/of.h>
@@ -25,155 +24,6 @@
25#include "common.h" 24#include "common.h"
26#include "hardware.h" 25#include "hardware.h"
27 26
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)
32
33#define CCGR0 0x68
34#define CCGR1 0x6c
35#define CCGR2 0x70
36#define CCGR3 0x74
37#define CCGR4 0x78
38#define CCGR5 0x7c
39#define CCGR6 0x80
40#define CCGR7 0x84
41
42#define CLPCR 0x54
43#define BP_CLPCR_LPM 0
44#define BM_CLPCR_LPM (0x3 << 0)
45#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
46#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
47#define BM_CLPCR_SBYOS (0x1 << 6)
48#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
49#define BM_CLPCR_VSTBY (0x1 << 8)
50#define BP_CLPCR_STBY_COUNT 9
51#define BM_CLPCR_STBY_COUNT (0x3 << 9)
52#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
53#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
54#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
55#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
56#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
57#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
58#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
59#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
60#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
61#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
62#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
63
64#define CGPR 0x64
65#define BM_CGPR_CHICKEN_BIT (0x1 << 17)
66
67static void __iomem *ccm_base;
68
69void imx6q_set_chicken_bit(void)
70{
71 u32 val = readl_relaxed(ccm_base + CGPR);
72
73 val |= BM_CGPR_CHICKEN_BIT;
74 writel_relaxed(val, ccm_base + CGPR);
75}
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
138int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
139{
140 u32 val = readl_relaxed(ccm_base + CLPCR);
141
142 val &= ~BM_CLPCR_LPM;
143 switch (mode) {
144 case WAIT_CLOCKED:
145 imx6q_enable_wb(false);
146 imx6q_enable_rbc(false);
147 break;
148 case WAIT_UNCLOCKED:
149 val |= 0x1 << BP_CLPCR_LPM;
150 val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
151 break;
152 case STOP_POWER_ON:
153 val |= 0x2 << BP_CLPCR_LPM;
154 break;
155 case WAIT_UNCLOCKED_POWER_OFF:
156 val |= 0x1 << BP_CLPCR_LPM;
157 val &= ~BM_CLPCR_VSTBY;
158 val &= ~BM_CLPCR_SBYOS;
159 break;
160 case STOP_POWER_OFF:
161 val |= 0x2 << BP_CLPCR_LPM;
162 val |= 0x3 << BP_CLPCR_STBY_COUNT;
163 val |= BM_CLPCR_VSTBY;
164 val |= BM_CLPCR_SBYOS;
165 imx6q_enable_wb(true);
166 imx6q_enable_rbc(true);
167 break;
168 default:
169 return -EINVAL;
170 }
171
172 writel_relaxed(val, ccm_base + CLPCR);
173
174 return 0;
175}
176
177static const char *step_sels[] = { "osc", "pll2_pfd2_396m", }; 27static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
178static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; 28static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
179static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", }; 29static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
@@ -182,7 +32,7 @@ static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
182static const char *periph_sels[] = { "periph_pre", "periph_clk2", }; 32static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
183static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; 33static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
184static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", }; 34static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
185static const char *audio_sels[] = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; 35static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
186static const char *gpu_axi_sels[] = { "axi", "ahb", }; 36static const char *gpu_axi_sels[] = { "axi", "ahb", };
187static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", }; 37static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
188static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; 38static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
@@ -196,7 +46,7 @@ static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di
196static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; 46static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
197static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", }; 47static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", };
198static const char *pcie_axi_sels[] = { "axi", "ahb", }; 48static const char *pcie_axi_sels[] = { "axi", "ahb", };
199static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_post_div", }; 49static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_div", };
200static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; 50static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
201static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", }; 51static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", };
202static const char *emi_sels[] = { "pll2_pfd2_396m", "pll3_usb_otg", "axi", "pll2_pfd0_352m", }; 52static const char *emi_sels[] = { "pll2_pfd2_396m", "pll3_usb_otg", "axi", "pll2_pfd0_352m", };
@@ -205,7 +55,7 @@ static const char *vdo_axi_sels[] = { "axi", "ahb", };
205static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", }; 55static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", };
206static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", 56static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
207 "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", 57 "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
208 "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_post_div", }; 58 "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio_div", };
209static const char *cko2_sels[] = { 59static const char *cko2_sels[] = {
210 "mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1", 60 "mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1",
211 "gpu2d_axi", "dummy", "ecspi_root", "gpu3d_axi", 61 "gpu2d_axi", "dummy", "ecspi_root", "gpu3d_axi",
@@ -217,6 +67,11 @@ static const char *cko2_sels[] = {
217 "uart_serial", "spdif", "asrc", "hsi_tx", 67 "uart_serial", "spdif", "asrc", "hsi_tx",
218}; 68};
219static const char *cko_sels[] = { "cko1", "cko2", }; 69static const char *cko_sels[] = { "cko1", "cko2", };
70static const char *lvds_sels[] = {
71 "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
72 "pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
73 "pcie_ref", "sata_ref",
74};
220 75
221enum mx6q_clks { 76enum mx6q_clks {
222 dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m, 77 dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m,
@@ -251,7 +106,8 @@ enum mx6q_clks {
251 ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5, 106 ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
252 sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate, 107 sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate,
253 usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow, 108 usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow,
254 spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, clk_max 109 spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, pll4_audio_div,
110 lvds1_sel, lvds2_sel, lvds1_gate, lvds2_gate, clk_max
255}; 111};
256 112
257static struct clk *clk[clk_max]; 113static struct clk *clk[clk_max];
@@ -266,13 +122,14 @@ static struct clk_div_table clk_enet_ref_table[] = {
266 { .val = 1, .div = 10, }, 122 { .val = 1, .div = 10, },
267 { .val = 2, .div = 5, }, 123 { .val = 2, .div = 5, },
268 { .val = 3, .div = 4, }, 124 { .val = 3, .div = 4, },
125 { /* sentinel */ }
269}; 126};
270 127
271static struct clk_div_table post_div_table[] = { 128static struct clk_div_table post_div_table[] = {
272 { .val = 2, .div = 1, }, 129 { .val = 2, .div = 1, },
273 { .val = 1, .div = 2, }, 130 { .val = 1, .div = 2, },
274 { .val = 0, .div = 4, }, 131 { .val = 0, .div = 4, },
275 { } 132 { /* sentinel */ }
276}; 133};
277 134
278static struct clk_div_table video_div_table[] = { 135static struct clk_div_table video_div_table[] = {
@@ -280,7 +137,7 @@ static struct clk_div_table video_div_table[] = {
280 { .val = 1, .div = 2, }, 137 { .val = 1, .div = 2, },
281 { .val = 2, .div = 1, }, 138 { .val = 2, .div = 1, },
282 { .val = 3, .div = 4, }, 139 { .val = 3, .div = 4, },
283 { } 140 { /* sentinel */ }
284}; 141};
285 142
286static void __init imx6q_clocks_init(struct device_node *ccm_node) 143static void __init imx6q_clocks_init(struct device_node *ccm_node)
@@ -300,7 +157,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
300 WARN_ON(!base); 157 WARN_ON(!base);
301 158
302 /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */ 159 /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
303 if (cpu_is_imx6q() && imx6q_revision() == IMX_CHIP_REVISION_1_0) { 160 if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) {
304 post_div_table[1].div = 1; 161 post_div_table[1].div = 1;
305 post_div_table[2].div = 1; 162 post_div_table[2].div = 1;
306 video_div_table[1].div = 1; 163 video_div_table[1].div = 1;
@@ -342,6 +199,18 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
342 base + 0xe0, 0, 2, 0, clk_enet_ref_table, 199 base + 0xe0, 0, 2, 0, clk_enet_ref_table,
343 &imx_ccm_lock); 200 &imx_ccm_lock);
344 201
202 clk[lvds1_sel] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
203 clk[lvds2_sel] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
204
205 /*
206 * lvds1_gate and lvds2_gate are pseudo-gates. Both can be
207 * independently configured as clock inputs or outputs. We treat
208 * the "output_enable" bit as a gate, even though it's really just
209 * enabling clock output.
210 */
211 clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "dummy", base + 0x160, 10);
212 clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "dummy", base + 0x160, 11);
213
345 /* name parent_name reg idx */ 214 /* name parent_name reg idx */
346 clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); 215 clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
347 clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); 216 clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
@@ -359,13 +228,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
359 clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2); 228 clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2);
360 229
361 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); 230 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);
231 clk[pll4_audio_div] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
362 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); 232 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);
363 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); 233 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);
364 234
365 np = ccm_node; 235 np = ccm_node;
366 base = of_iomap(np, 0); 236 base = of_iomap(np, 0);
367 WARN_ON(!base); 237 WARN_ON(!base);
368 ccm_base = base; 238
239 imx6q_pm_set_ccm_base(base);
369 240
370 /* name reg shift width parent_names num_parents */ 241 /* name reg shift width parent_names num_parents */
371 clk[step] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); 242 clk[step] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
@@ -428,7 +299,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
428 clk[asrc_podf] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3); 299 clk[asrc_podf] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3);
429 clk[spdif_pred] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); 300 clk[spdif_pred] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3);
430 clk[spdif_podf] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); 301 clk[spdif_podf] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3);
431 clk[can_root] = imx_clk_divider("can_root", "pll3_usb_otg", base + 0x20, 2, 6); 302 clk[can_root] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6);
432 clk[ecspi_root] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); 303 clk[ecspi_root] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6);
433 clk[gpu2d_core_podf] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3); 304 clk[gpu2d_core_podf] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3);
434 clk[gpu3d_core_podf] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3); 305 clk[gpu3d_core_podf] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3);
@@ -573,7 +444,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
573 clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL); 444 clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL);
574 clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL); 445 clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL);
575 446
576 if ((imx6q_revision() != IMX_CHIP_REVISION_1_0) || cpu_is_imx6dl()) { 447 if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
448 cpu_is_imx6dl()) {
577 clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]); 449 clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
578 clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]); 450 clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
579 } 451 }
@@ -603,8 +475,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
603 if (ret) 475 if (ret)
604 pr_warn("failed to set up CLKO: %d\n", ret); 476 pr_warn("failed to set up CLKO: %d\n", ret);
605 477
606 /* Set initial power mode */ 478 /* All existing boards with PCIe use LVDS1 */
607 imx6q_set_lpm(WAIT_CLOCKED); 479 if (IS_ENABLED(CONFIG_PCI_IMX6))
480 clk_set_parent(clk[lvds1_sel], clk[sata_ref]);
608 481
609 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt"); 482 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
610 base = of_iomap(np, 0); 483 base = of_iomap(np, 0);
diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c
index a5c3c5d21aee..c0c4ef55e35b 100644
--- a/arch/arm/mach-imx/clk-imx6sl.c
+++ b/arch/arm/mach-imx/clk-imx6sl.c
@@ -127,6 +127,9 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
127 base = of_iomap(np, 0); 127 base = of_iomap(np, 0);
128 WARN_ON(!base); 128 WARN_ON(!base);
129 129
130 /* Reuse imx6q pm code */
131 imx6q_pm_set_ccm_base(base);
132
130 /* name reg shift width parent_names num_parents */ 133 /* name reg shift width parent_names num_parents */
131 clks[IMX6SL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); 134 clks[IMX6SL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
132 clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); 135 clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c
index f6640b6a7b31..61364050fccd 100644
--- a/arch/arm/mach-imx/clk-pllv3.c
+++ b/arch/arm/mach-imx/clk-pllv3.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/clk-provider.h> 14#include <linux/clk-provider.h>
15#include <linux/delay.h>
15#include <linux/io.h> 16#include <linux/io.h>
16#include <linux/slab.h> 17#include <linux/slab.h>
17#include <linux/jiffies.h> 18#include <linux/jiffies.h>
@@ -45,33 +46,49 @@ struct clk_pllv3 {
45 46
46#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw) 47#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
47 48
49static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
50{
51 unsigned long timeout = jiffies + msecs_to_jiffies(10);
52 u32 val = readl_relaxed(pll->base) & BM_PLL_POWER;
53
54 /* No need to wait for lock when pll is not powered up */
55 if ((pll->powerup_set && !val) || (!pll->powerup_set && val))
56 return 0;
57
58 /* Wait for PLL to lock */
59 do {
60 if (readl_relaxed(pll->base) & BM_PLL_LOCK)
61 break;
62 if (time_after(jiffies, timeout))
63 break;
64 usleep_range(50, 500);
65 } while (1);
66
67 return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT;
68}
69
48static int clk_pllv3_prepare(struct clk_hw *hw) 70static int clk_pllv3_prepare(struct clk_hw *hw)
49{ 71{
50 struct clk_pllv3 *pll = to_clk_pllv3(hw); 72 struct clk_pllv3 *pll = to_clk_pllv3(hw);
51 unsigned long timeout;
52 u32 val; 73 u32 val;
74 int ret;
53 75
54 val = readl_relaxed(pll->base); 76 val = readl_relaxed(pll->base);
55 val &= ~BM_PLL_BYPASS;
56 if (pll->powerup_set) 77 if (pll->powerup_set)
57 val |= BM_PLL_POWER; 78 val |= BM_PLL_POWER;
58 else 79 else
59 val &= ~BM_PLL_POWER; 80 val &= ~BM_PLL_POWER;
60 writel_relaxed(val, pll->base); 81 writel_relaxed(val, pll->base);
61 82
62 timeout = jiffies + msecs_to_jiffies(10); 83 ret = clk_pllv3_wait_lock(pll);
63 /* Wait for PLL to lock */ 84 if (ret)
64 do { 85 return ret;
65 if (readl_relaxed(pll->base) & BM_PLL_LOCK)
66 break;
67 if (time_after(jiffies, timeout))
68 break;
69 } while (1);
70 86
71 if (readl_relaxed(pll->base) & BM_PLL_LOCK) 87 val = readl_relaxed(pll->base);
72 return 0; 88 val &= ~BM_PLL_BYPASS;
73 else 89 writel_relaxed(val, pll->base);
74 return -ETIMEDOUT; 90
91 return 0;
75} 92}
76 93
77static void clk_pllv3_unprepare(struct clk_hw *hw) 94static void clk_pllv3_unprepare(struct clk_hw *hw)
@@ -146,7 +163,7 @@ static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate,
146 val |= div; 163 val |= div;
147 writel_relaxed(val, pll->base); 164 writel_relaxed(val, pll->base);
148 165
149 return 0; 166 return clk_pllv3_wait_lock(pll);
150} 167}
151 168
152static const struct clk_ops clk_pllv3_ops = { 169static const struct clk_ops clk_pllv3_ops = {
@@ -202,7 +219,7 @@ static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate,
202 val |= div; 219 val |= div;
203 writel_relaxed(val, pll->base); 220 writel_relaxed(val, pll->base);
204 221
205 return 0; 222 return clk_pllv3_wait_lock(pll);
206} 223}
207 224
208static const struct clk_ops clk_pllv3_sys_ops = { 225static const struct clk_ops clk_pllv3_sys_ops = {
@@ -276,7 +293,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
276 writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET); 293 writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
277 writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET); 294 writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
278 295
279 return 0; 296 return clk_pllv3_wait_lock(pll);
280} 297}
281 298
282static const struct clk_ops clk_pllv3_av_ops = { 299static const struct clk_ops clk_pllv3_av_ops = {
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 4517fd760bfc..24a7899e36a8 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -13,74 +13,73 @@
13 13
14#include <linux/reboot.h> 14#include <linux/reboot.h>
15 15
16struct irq_data;
16struct platform_device; 17struct platform_device;
17struct pt_regs; 18struct pt_regs;
18struct clk; 19struct clk;
19enum mxc_cpu_pwr_mode; 20enum mxc_cpu_pwr_mode;
20 21
21extern void mx1_map_io(void); 22void mx1_map_io(void);
22extern void mx21_map_io(void); 23void mx21_map_io(void);
23extern void mx25_map_io(void); 24void mx25_map_io(void);
24extern void mx27_map_io(void); 25void mx27_map_io(void);
25extern void mx31_map_io(void); 26void mx31_map_io(void);
26extern void mx35_map_io(void); 27void mx35_map_io(void);
27extern void mx51_map_io(void); 28void mx51_map_io(void);
28extern void mx53_map_io(void); 29void mx53_map_io(void);
29extern void imx1_init_early(void); 30void imx1_init_early(void);
30extern void imx21_init_early(void); 31void imx21_init_early(void);
31extern void imx25_init_early(void); 32void imx25_init_early(void);
32extern void imx27_init_early(void); 33void imx27_init_early(void);
33extern void imx31_init_early(void); 34void imx31_init_early(void);
34extern void imx35_init_early(void); 35void imx35_init_early(void);
35extern void imx51_init_early(void); 36void imx51_init_early(void);
36extern void imx53_init_early(void); 37void imx53_init_early(void);
37extern void mxc_init_irq(void __iomem *); 38void mxc_init_irq(void __iomem *);
38extern void tzic_init_irq(void __iomem *); 39void tzic_init_irq(void __iomem *);
39extern void mx1_init_irq(void); 40void mx1_init_irq(void);
40extern void mx21_init_irq(void); 41void mx21_init_irq(void);
41extern void mx25_init_irq(void); 42void mx25_init_irq(void);
42extern void mx27_init_irq(void); 43void mx27_init_irq(void);
43extern void mx31_init_irq(void); 44void mx31_init_irq(void);
44extern void mx35_init_irq(void); 45void mx35_init_irq(void);
45extern void mx51_init_irq(void); 46void mx51_init_irq(void);
46extern void mx53_init_irq(void); 47void mx53_init_irq(void);
47extern void imx1_soc_init(void); 48void imx1_soc_init(void);
48extern void imx21_soc_init(void); 49void imx21_soc_init(void);
49extern void imx25_soc_init(void); 50void imx25_soc_init(void);
50extern void imx27_soc_init(void); 51void imx27_soc_init(void);
51extern void imx31_soc_init(void); 52void imx31_soc_init(void);
52extern void imx35_soc_init(void); 53void imx35_soc_init(void);
53extern void imx51_soc_init(void); 54void imx51_soc_init(void);
54extern void imx51_init_late(void); 55void imx51_init_late(void);
55extern void imx53_init_late(void); 56void imx53_init_late(void);
56extern void epit_timer_init(void __iomem *base, int irq); 57void epit_timer_init(void __iomem *base, int irq);
57extern void mxc_timer_init(void __iomem *, int); 58void mxc_timer_init(void __iomem *, int);
58extern int mx1_clocks_init(unsigned long fref); 59int mx1_clocks_init(unsigned long fref);
59extern int mx21_clocks_init(unsigned long lref, unsigned long fref); 60int mx21_clocks_init(unsigned long lref, unsigned long fref);
60extern int mx25_clocks_init(void); 61int mx25_clocks_init(void);
61extern int mx27_clocks_init(unsigned long fref); 62int mx27_clocks_init(unsigned long fref);
62extern int mx31_clocks_init(unsigned long fref); 63int mx31_clocks_init(unsigned long fref);
63extern int mx35_clocks_init(void); 64int mx35_clocks_init(void);
64extern int mx51_clocks_init(unsigned long ckil, unsigned long osc, 65int mx51_clocks_init(unsigned long ckil, unsigned long osc,
65 unsigned long ckih1, unsigned long ckih2); 66 unsigned long ckih1, unsigned long ckih2);
66extern int mx53_clocks_init(unsigned long ckil, unsigned long osc, 67int mx25_clocks_init_dt(void);
67 unsigned long ckih1, unsigned long ckih2); 68int mx27_clocks_init_dt(void);
68extern int mx25_clocks_init_dt(void); 69int mx31_clocks_init_dt(void);
69extern int mx27_clocks_init_dt(void); 70struct platform_device *mxc_register_gpio(char *name, int id,
70extern int mx31_clocks_init_dt(void);
71extern int mx51_clocks_init_dt(void);
72extern int mx53_clocks_init_dt(void);
73extern struct platform_device *mxc_register_gpio(char *name, int id,
74 resource_size_t iobase, resource_size_t iosize, int irq, int irq_high); 71 resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
75extern void mxc_set_cpu_type(unsigned int type); 72void mxc_set_cpu_type(unsigned int type);
76extern void mxc_restart(enum reboot_mode, const char *); 73void mxc_restart(enum reboot_mode, const char *);
77extern void mxc_arch_reset_init(void __iomem *); 74void mxc_arch_reset_init(void __iomem *);
78extern void mxc_arch_reset_init_dt(void); 75void mxc_arch_reset_init_dt(void);
79extern int mx53_revision(void); 76int mx53_revision(void);
80extern int imx6q_revision(void); 77void imx_set_aips(void __iomem *);
81extern int mx53_display_revision(void); 78int mxc_device_init(void);
82extern void imx_set_aips(void __iomem *); 79void imx_set_soc_revision(unsigned int rev);
83extern int mxc_device_init(void); 80unsigned int imx_get_soc_revision(void);
81void imx_init_revision_from_anatop(void);
82struct device *imx_soc_device_init(void);
84 83
85enum mxc_cpu_pwr_mode { 84enum mxc_cpu_pwr_mode {
86 WAIT_CLOCKED, /* wfi only */ 85 WAIT_CLOCKED, /* wfi only */
@@ -97,8 +96,8 @@ enum mx3_cpu_pwr_mode {
97 MX3_SLEEP, 96 MX3_SLEEP,
98}; 97};
99 98
100extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); 99void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
101extern void imx_print_silicon_rev(const char *cpu, int srev); 100void imx_print_silicon_rev(const char *cpu, int srev);
102 101
103void avic_handle_irq(struct pt_regs *); 102void avic_handle_irq(struct pt_regs *);
104void tzic_handle_irq(struct pt_regs *); 103void tzic_handle_irq(struct pt_regs *);
@@ -112,54 +111,56 @@ void tzic_handle_irq(struct pt_regs *);
112#define imx51_handle_irq tzic_handle_irq 111#define imx51_handle_irq tzic_handle_irq
113#define imx53_handle_irq tzic_handle_irq 112#define imx53_handle_irq tzic_handle_irq
114 113
115extern void imx_enable_cpu(int cpu, bool enable); 114void imx_enable_cpu(int cpu, bool enable);
116extern void imx_set_cpu_jump(int cpu, void *jump_addr); 115void imx_set_cpu_jump(int cpu, void *jump_addr);
117extern u32 imx_get_cpu_arg(int cpu); 116u32 imx_get_cpu_arg(int cpu);
118extern void imx_set_cpu_arg(int cpu, u32 arg); 117void imx_set_cpu_arg(int cpu, u32 arg);
119extern void v7_cpu_resume(void); 118void v7_cpu_resume(void);
120#ifdef CONFIG_SMP 119#ifdef CONFIG_SMP
121extern void v7_secondary_startup(void); 120void v7_secondary_startup(void);
122extern void imx_scu_map_io(void); 121void imx_scu_map_io(void);
123extern void imx_smp_prepare(void); 122void imx_smp_prepare(void);
124extern void imx_scu_standby_enable(void); 123void imx_scu_standby_enable(void);
125#else 124#else
126static inline void imx_scu_map_io(void) {} 125static inline void imx_scu_map_io(void) {}
127static inline void imx_smp_prepare(void) {} 126static inline void imx_smp_prepare(void) {}
128static inline void imx_scu_standby_enable(void) {} 127static inline void imx_scu_standby_enable(void) {}
129#endif 128#endif
130extern void imx_src_init(void); 129void imx_src_init(void);
131extern void imx_src_prepare_restart(void); 130void imx_gpc_init(void);
132extern void imx_gpc_init(void); 131void imx_gpc_pre_suspend(void);
133extern void imx_gpc_pre_suspend(void); 132void imx_gpc_post_resume(void);
134extern void imx_gpc_post_resume(void); 133void imx_gpc_mask_all(void);
135extern void imx_gpc_mask_all(void); 134void imx_gpc_restore_all(void);
136extern void imx_gpc_restore_all(void); 135void imx_gpc_irq_mask(struct irq_data *d);
137extern void imx_anatop_init(void); 136void imx_gpc_irq_unmask(struct irq_data *d);
138extern void imx_anatop_pre_suspend(void); 137void imx_anatop_init(void);
139extern void imx_anatop_post_resume(void); 138void imx_anatop_pre_suspend(void);
140extern u32 imx_anatop_get_digprog(void); 139void imx_anatop_post_resume(void);
141extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); 140int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
142extern void imx6q_set_chicken_bit(void); 141void imx6q_set_chicken_bit(void);
143 142
144extern void imx_cpu_die(unsigned int cpu); 143void imx_cpu_die(unsigned int cpu);
145extern int imx_cpu_kill(unsigned int cpu); 144int imx_cpu_kill(unsigned int cpu);
146 145
147#ifdef CONFIG_PM 146#ifdef CONFIG_PM
148extern void imx6q_pm_init(void); 147void imx6q_pm_init(void);
149extern void imx5_pm_init(void); 148void imx6q_pm_set_ccm_base(void __iomem *base);
149void imx5_pm_init(void);
150#else 150#else
151static inline void imx6q_pm_init(void) {} 151static inline void imx6q_pm_init(void) {}
152static inline void imx6q_pm_set_ccm_base(void __iomem *base) {}
152static inline void imx5_pm_init(void) {} 153static inline void imx5_pm_init(void) {}
153#endif 154#endif
154 155
155#ifdef CONFIG_NEON 156#ifdef CONFIG_NEON
156extern int mx51_neon_fixup(void); 157int mx51_neon_fixup(void);
157#else 158#else
158static inline int mx51_neon_fixup(void) { return 0; } 159static inline int mx51_neon_fixup(void) { return 0; }
159#endif 160#endif
160 161
161#ifdef CONFIG_CACHE_L2X0 162#ifdef CONFIG_CACHE_L2X0
162extern void imx_init_l2cache(void); 163void imx_init_l2cache(void);
163#else 164#else
164static inline void imx_init_l2cache(void) {} 165static inline void imx_init_l2cache(void) {}
165#endif 166#endif
diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c
index e70e3acbf9bd..ba3b498a67ec 100644
--- a/arch/arm/mach-imx/cpu.c
+++ b/arch/arm/mach-imx/cpu.c
@@ -1,6 +1,9 @@
1 1#include <linux/err.h>
2#include <linux/module.h> 2#include <linux/module.h>
3#include <linux/io.h> 3#include <linux/io.h>
4#include <linux/of.h>
5#include <linux/slab.h>
6#include <linux/sys_soc.h>
4 7
5#include "hardware.h" 8#include "hardware.h"
6#include "common.h" 9#include "common.h"
@@ -8,11 +11,23 @@
8unsigned int __mxc_cpu_type; 11unsigned int __mxc_cpu_type;
9EXPORT_SYMBOL(__mxc_cpu_type); 12EXPORT_SYMBOL(__mxc_cpu_type);
10 13
14static unsigned int imx_soc_revision;
15
11void mxc_set_cpu_type(unsigned int type) 16void mxc_set_cpu_type(unsigned int type)
12{ 17{
13 __mxc_cpu_type = type; 18 __mxc_cpu_type = type;
14} 19}
15 20
21void imx_set_soc_revision(unsigned int rev)
22{
23 imx_soc_revision = rev;
24}
25
26unsigned int imx_get_soc_revision(void)
27{
28 return imx_soc_revision;
29}
30
16void imx_print_silicon_rev(const char *cpu, int srev) 31void imx_print_silicon_rev(const char *cpu, int srev)
17{ 32{
18 if (srev == IMX_CHIP_REVISION_UNKNOWN) 33 if (srev == IMX_CHIP_REVISION_UNKNOWN)
@@ -44,3 +59,81 @@ void __init imx_set_aips(void __iomem *base)
44 reg = __raw_readl(base + 0x50) & 0x00FFFFFF; 59 reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
45 __raw_writel(reg, base + 0x50); 60 __raw_writel(reg, base + 0x50);
46} 61}
62
63struct device * __init imx_soc_device_init(void)
64{
65 struct soc_device_attribute *soc_dev_attr;
66 struct soc_device *soc_dev;
67 struct device_node *root;
68 const char *soc_id;
69 int ret;
70
71 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
72 if (!soc_dev_attr)
73 return NULL;
74
75 soc_dev_attr->family = "Freescale i.MX";
76
77 root = of_find_node_by_path("/");
78 ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
79 of_node_put(root);
80 if (ret)
81 goto free_soc;
82
83 switch (__mxc_cpu_type) {
84 case MXC_CPU_MX1:
85 soc_id = "i.MX1";
86 break;
87 case MXC_CPU_MX21:
88 soc_id = "i.MX21";
89 break;
90 case MXC_CPU_MX25:
91 soc_id = "i.MX25";
92 break;
93 case MXC_CPU_MX27:
94 soc_id = "i.MX27";
95 break;
96 case MXC_CPU_MX31:
97 soc_id = "i.MX31";
98 break;
99 case MXC_CPU_MX35:
100 soc_id = "i.MX35";
101 break;
102 case MXC_CPU_MX51:
103 soc_id = "i.MX51";
104 break;
105 case MXC_CPU_MX53:
106 soc_id = "i.MX53";
107 break;
108 case MXC_CPU_IMX6SL:
109 soc_id = "i.MX6SL";
110 break;
111 case MXC_CPU_IMX6DL:
112 soc_id = "i.MX6DL";
113 break;
114 case MXC_CPU_IMX6Q:
115 soc_id = "i.MX6Q";
116 break;
117 default:
118 soc_id = "Unknown";
119 }
120 soc_dev_attr->soc_id = soc_id;
121
122 soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d.%d",
123 (imx_soc_revision >> 4) & 0xf,
124 imx_soc_revision & 0xf);
125 if (!soc_dev_attr->revision)
126 goto free_soc;
127
128 soc_dev = soc_device_register(soc_dev_attr);
129 if (IS_ERR(soc_dev))
130 goto free_rev;
131
132 return soc_device_to_device(soc_dev);
133
134free_rev:
135 kfree(soc_dev_attr->revision);
136free_soc:
137 kfree(soc_dev_attr);
138 return NULL;
139}
diff --git a/arch/arm/mach-imx/epit.c b/arch/arm/mach-imx/epit.c
index e02de188ae83..074b1a81ba76 100644
--- a/arch/arm/mach-imx/epit.c
+++ b/arch/arm/mach-imx/epit.c
@@ -171,7 +171,7 @@ static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
171 171
172static struct irqaction epit_timer_irq = { 172static struct irqaction epit_timer_irq = {
173 .name = "i.MX EPIT Timer Tick", 173 .name = "i.MX EPIT Timer Tick",
174 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 174 .flags = IRQF_TIMER | IRQF_IRQPOLL,
175 .handler = epit_timer_interrupt, 175 .handler = epit_timer_interrupt,
176}; 176};
177 177
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 44a65e9ff1fc..586e0171a652 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -90,7 +90,7 @@ void imx_gpc_restore_all(void)
90 writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4); 90 writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
91} 91}
92 92
93static void imx_gpc_irq_unmask(struct irq_data *d) 93void imx_gpc_irq_unmask(struct irq_data *d)
94{ 94{
95 void __iomem *reg; 95 void __iomem *reg;
96 u32 val; 96 u32 val;
@@ -105,7 +105,7 @@ static void imx_gpc_irq_unmask(struct irq_data *d)
105 writel_relaxed(val, reg); 105 writel_relaxed(val, reg);
106} 106}
107 107
108static void imx_gpc_irq_mask(struct irq_data *d) 108void imx_gpc_irq_mask(struct irq_data *d)
109{ 109{
110 void __iomem *reg; 110 void __iomem *reg;
111 u32 val; 111 u32 val;
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c
index 3daf1ed90579..b35e99cc5e5b 100644
--- a/arch/arm/mach-imx/hotplug.c
+++ b/arch/arm/mach-imx/hotplug.c
@@ -52,7 +52,9 @@ void imx_cpu_die(unsigned int cpu)
52 * the register being cleared to kill the cpu. 52 * the register being cleared to kill the cpu.
53 */ 53 */
54 imx_set_cpu_arg(cpu, ~0); 54 imx_set_cpu_arg(cpu, ~0);
55 cpu_do_idle(); 55
56 while (1)
57 cpu_do_idle();
56} 58}
57 59
58int imx_cpu_kill(unsigned int cpu) 60int imx_cpu_kill(unsigned int cpu)
diff --git a/arch/arm/mach-imx/imx51-dt.c b/arch/arm/mach-imx/imx51-dt.c
index 53e43e579dd7..bece8a65e6f0 100644
--- a/arch/arm/mach-imx/imx51-dt.c
+++ b/arch/arm/mach-imx/imx51-dt.c
@@ -34,17 +34,11 @@ static const char *imx51_dt_board_compat[] __initdata = {
34 NULL 34 NULL
35}; 35};
36 36
37static void __init imx51_timer_init(void)
38{
39 mx51_clocks_init_dt();
40}
41
42DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)") 37DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)")
43 .map_io = mx51_map_io, 38 .map_io = mx51_map_io,
44 .init_early = imx51_init_early, 39 .init_early = imx51_init_early,
45 .init_irq = mx51_init_irq, 40 .init_irq = mx51_init_irq,
46 .handle_irq = imx51_handle_irq, 41 .handle_irq = imx51_handle_irq,
47 .init_time = imx51_timer_init,
48 .init_machine = imx51_dt_init, 42 .init_machine = imx51_dt_init,
49 .init_late = imx51_init_late, 43 .init_late = imx51_init_late,
50 .dt_compat = imx51_dt_board_compat, 44 .dt_compat = imx51_dt_board_compat,
diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c
index 368a6e3f5926..58b864a3fc20 100644
--- a/arch/arm/mach-imx/mach-armadillo5x0.c
+++ b/arch/arm/mach-imx/mach-armadillo5x0.c
@@ -404,8 +404,7 @@ static int armadillo5x0_sdhc1_init(struct device *dev,
404 404
405 /* When supported the trigger type have to be BOTH */ 405 /* When supported the trigger type have to be BOTH */
406 ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK)), 406 ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK)),
407 detect_irq, 407 detect_irq, IRQF_TRIGGER_FALLING,
408 IRQF_DISABLED | IRQF_TRIGGER_FALLING,
409 "sdhc-detect", data); 408 "sdhc-detect", data);
410 409
411 if (ret) 410 if (ret)
diff --git a/arch/arm/mach-imx/mach-imx53.c b/arch/arm/mach-imx/mach-imx53.c
index 98c58944015a..c9c4d8d96931 100644
--- a/arch/arm/mach-imx/mach-imx53.c
+++ b/arch/arm/mach-imx/mach-imx53.c
@@ -36,17 +36,11 @@ static const char *imx53_dt_board_compat[] __initdata = {
36 NULL 36 NULL
37}; 37};
38 38
39static void __init imx53_timer_init(void)
40{
41 mx53_clocks_init_dt();
42}
43
44DT_MACHINE_START(IMX53_DT, "Freescale i.MX53 (Device Tree Support)") 39DT_MACHINE_START(IMX53_DT, "Freescale i.MX53 (Device Tree Support)")
45 .map_io = mx53_map_io, 40 .map_io = mx53_map_io,
46 .init_early = imx53_init_early, 41 .init_early = imx53_init_early,
47 .init_irq = mx53_init_irq, 42 .init_irq = mx53_init_irq,
48 .handle_irq = imx53_handle_irq, 43 .handle_irq = imx53_handle_irq,
49 .init_time = imx53_timer_init,
50 .init_machine = imx53_dt_init, 44 .init_machine = imx53_dt_init,
51 .init_late = imx53_init_late, 45 .init_late = imx53_init_late,
52 .dt_compat = imx53_dt_board_compat, 46 .dt_compat = imx53_dt_board_compat,
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 90372a21087f..d0cfb225ec9a 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -11,11 +11,8 @@
11 */ 11 */
12 12
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/clk-provider.h>
15#include <linux/clkdev.h> 14#include <linux/clkdev.h>
16#include <linux/clocksource.h>
17#include <linux/cpu.h> 15#include <linux/cpu.h>
18#include <linux/delay.h>
19#include <linux/export.h> 16#include <linux/export.h>
20#include <linux/init.h> 17#include <linux/init.h>
21#include <linux/io.h> 18#include <linux/io.h>
@@ -25,7 +22,7 @@
25#include <linux/of_address.h> 22#include <linux/of_address.h>
26#include <linux/of_irq.h> 23#include <linux/of_irq.h>
27#include <linux/of_platform.h> 24#include <linux/of_platform.h>
28#include <linux/opp.h> 25#include <linux/pm_opp.h>
29#include <linux/phy.h> 26#include <linux/phy.h>
30#include <linux/reboot.h> 27#include <linux/reboot.h>
31#include <linux/regmap.h> 28#include <linux/regmap.h>
@@ -40,64 +37,6 @@
40#include "cpuidle.h" 37#include "cpuidle.h"
41#include "hardware.h" 38#include "hardware.h"
42 39
43static u32 chip_revision;
44
45int imx6q_revision(void)
46{
47 return chip_revision;
48}
49
50static void __init imx6q_init_revision(void)
51{
52 u32 rev = imx_anatop_get_digprog();
53
54 switch (rev & 0xff) {
55 case 0:
56 chip_revision = IMX_CHIP_REVISION_1_0;
57 break;
58 case 1:
59 chip_revision = IMX_CHIP_REVISION_1_1;
60 break;
61 case 2:
62 chip_revision = IMX_CHIP_REVISION_1_2;
63 break;
64 default:
65 chip_revision = IMX_CHIP_REVISION_UNKNOWN;
66 }
67
68 mxc_set_cpu_type(rev >> 16 & 0xff);
69}
70
71static void imx6q_restart(enum reboot_mode mode, const char *cmd)
72{
73 struct device_node *np;
74 void __iomem *wdog_base;
75
76 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-wdt");
77 wdog_base = of_iomap(np, 0);
78 if (!wdog_base)
79 goto soft;
80
81 imx_src_prepare_restart();
82
83 /* enable wdog */
84 writew_relaxed(1 << 2, wdog_base);
85 /* write twice to ensure the request will not get ignored */
86 writew_relaxed(1 << 2, wdog_base);
87
88 /* wait for reset to assert ... */
89 mdelay(500);
90
91 pr_err("Watchdog reset failed to assert reset\n");
92
93 /* delay to allow the serial port to show the message */
94 mdelay(50);
95
96soft:
97 /* we'll take a jump through zero as a poor second */
98 soft_restart(0);
99}
100
101/* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */ 40/* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */
102static int ksz9021rn_phy_fixup(struct phy_device *phydev) 41static int ksz9021rn_phy_fixup(struct phy_device *phydev)
103{ 42{
@@ -192,9 +131,20 @@ static void __init imx6q_1588_init(void)
192 131
193static void __init imx6q_init_machine(void) 132static void __init imx6q_init_machine(void)
194{ 133{
134 struct device *parent;
135
136 imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
137 imx_get_soc_revision());
138
139 mxc_arch_reset_init_dt();
140
141 parent = imx_soc_device_init();
142 if (parent == NULL)
143 pr_warn("failed to initialize soc device\n");
144
195 imx6q_enet_phy_init(); 145 imx6q_enet_phy_init();
196 146
197 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 147 of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
198 148
199 imx_anatop_init(); 149 imx_anatop_init();
200 imx6q_pm_init(); 150 imx6q_pm_init();
@@ -226,7 +176,7 @@ static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev)
226 val = readl_relaxed(base + OCOTP_CFG3); 176 val = readl_relaxed(base + OCOTP_CFG3);
227 val >>= OCOTP_CFG3_SPEED_SHIFT; 177 val >>= OCOTP_CFG3_SPEED_SHIFT;
228 if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ) 178 if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ)
229 if (opp_disable(cpu_dev, 1200000000)) 179 if (dev_pm_opp_disable(cpu_dev, 1200000000))
230 pr_warn("failed to disable 1.2 GHz OPP\n"); 180 pr_warn("failed to disable 1.2 GHz OPP\n");
231 181
232put_node: 182put_node:
@@ -269,7 +219,7 @@ static void __init imx6q_init_late(void)
269 * WAIT mode is broken on TO 1.0 and 1.1, so there is no point 219 * WAIT mode is broken on TO 1.0 and 1.1, so there is no point
270 * to run cpuidle on them. 220 * to run cpuidle on them.
271 */ 221 */
272 if (imx6q_revision() > IMX_CHIP_REVISION_1_1) 222 if (imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
273 imx6q_cpuidle_init(); 223 imx6q_cpuidle_init();
274 224
275 if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) { 225 if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
@@ -286,21 +236,13 @@ static void __init imx6q_map_io(void)
286 236
287static void __init imx6q_init_irq(void) 237static void __init imx6q_init_irq(void)
288{ 238{
289 imx6q_init_revision(); 239 imx_init_revision_from_anatop();
290 imx_init_l2cache(); 240 imx_init_l2cache();
291 imx_src_init(); 241 imx_src_init();
292 imx_gpc_init(); 242 imx_gpc_init();
293 irqchip_init(); 243 irqchip_init();
294} 244}
295 245
296static void __init imx6q_timer_init(void)
297{
298 of_clk_init(NULL);
299 clocksource_of_init();
300 imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
301 imx6q_revision());
302}
303
304static const char *imx6q_dt_compat[] __initdata = { 246static const char *imx6q_dt_compat[] __initdata = {
305 "fsl,imx6dl", 247 "fsl,imx6dl",
306 "fsl,imx6q", 248 "fsl,imx6q",
@@ -311,9 +253,8 @@ DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
311 .smp = smp_ops(imx_smp_ops), 253 .smp = smp_ops(imx_smp_ops),
312 .map_io = imx6q_map_io, 254 .map_io = imx6q_map_io,
313 .init_irq = imx6q_init_irq, 255 .init_irq = imx6q_init_irq,
314 .init_time = imx6q_timer_init,
315 .init_machine = imx6q_init_machine, 256 .init_machine = imx6q_init_machine,
316 .init_late = imx6q_init_late, 257 .init_late = imx6q_init_late,
317 .dt_compat = imx6q_dt_compat, 258 .dt_compat = imx6q_dt_compat,
318 .restart = imx6q_restart, 259 .restart = mxc_restart,
319MACHINE_END 260MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c
index 0d75dc54f715..2f952e3fcf89 100644
--- a/arch/arm/mach-imx/mach-imx6sl.c
+++ b/arch/arm/mach-imx/mach-imx6sl.c
@@ -7,35 +7,60 @@
7 * 7 *
8 */ 8 */
9 9
10#include <linux/clk-provider.h>
11#include <linux/irqchip.h> 10#include <linux/irqchip.h>
12#include <linux/of.h> 11#include <linux/of.h>
13#include <linux/of_platform.h> 12#include <linux/of_platform.h>
13#include <linux/mfd/syscon.h>
14#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
15#include <linux/regmap.h>
14#include <asm/mach/arch.h> 16#include <asm/mach/arch.h>
15#include <asm/mach/map.h> 17#include <asm/mach/map.h>
16 18
17#include "common.h" 19#include "common.h"
18 20
21static void __init imx6sl_fec_init(void)
22{
23 struct regmap *gpr;
24
25 /* set FEC clock from internal PLL clock source */
26 gpr = syscon_regmap_lookup_by_compatible("fsl,imx6sl-iomuxc-gpr");
27 if (!IS_ERR(gpr)) {
28 regmap_update_bits(gpr, IOMUXC_GPR1,
29 IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK, 0);
30 regmap_update_bits(gpr, IOMUXC_GPR1,
31 IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK, 0);
32 } else {
33 pr_err("failed to find fsl,imx6sl-iomux-gpr regmap\n");
34 }
35}
36
19static void __init imx6sl_init_machine(void) 37static void __init imx6sl_init_machine(void)
20{ 38{
39 struct device *parent;
40
21 mxc_arch_reset_init_dt(); 41 mxc_arch_reset_init_dt();
22 42
23 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 43 parent = imx_soc_device_init();
44 if (parent == NULL)
45 pr_warn("failed to initialize soc device\n");
46
47 of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
48
49 imx6sl_fec_init();
50 imx_anatop_init();
51 /* Reuse imx6q pm code */
52 imx6q_pm_init();
24} 53}
25 54
26static void __init imx6sl_init_irq(void) 55static void __init imx6sl_init_irq(void)
27{ 56{
57 imx_init_revision_from_anatop();
28 imx_init_l2cache(); 58 imx_init_l2cache();
29 imx_src_init(); 59 imx_src_init();
30 imx_gpc_init(); 60 imx_gpc_init();
31 irqchip_init(); 61 irqchip_init();
32} 62}
33 63
34static void __init imx6sl_timer_init(void)
35{
36 of_clk_init(NULL);
37}
38
39static const char *imx6sl_dt_compat[] __initdata = { 64static const char *imx6sl_dt_compat[] __initdata = {
40 "fsl,imx6sl", 65 "fsl,imx6sl",
41 NULL, 66 NULL,
@@ -44,7 +69,6 @@ static const char *imx6sl_dt_compat[] __initdata = {
44DT_MACHINE_START(IMX6SL, "Freescale i.MX6 SoloLite (Device Tree)") 69DT_MACHINE_START(IMX6SL, "Freescale i.MX6 SoloLite (Device Tree)")
45 .map_io = debug_ll_io_init, 70 .map_io = debug_ll_io_init,
46 .init_irq = imx6sl_init_irq, 71 .init_irq = imx6sl_init_irq,
47 .init_time = imx6sl_timer_init,
48 .init_machine = imx6sl_init_machine, 72 .init_machine = imx6sl_init_machine,
49 .dt_compat = imx6sl_dt_compat, 73 .dt_compat = imx6sl_dt_compat,
50 .restart = mxc_restart, 74 .restart = mxc_restart,
diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c
index 1ed916175d41..50044a21b388 100644
--- a/arch/arm/mach-imx/mach-mx31_3ds.c
+++ b/arch/arm/mach-imx/mach-mx31_3ds.c
@@ -311,7 +311,7 @@ static int mx31_3ds_sdhc1_init(struct device *dev,
311 } 311 }
312 312
313 ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)), 313 ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)),
314 detect_irq, IRQF_DISABLED | 314 detect_irq,
315 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 315 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
316 "sdhc1-detect", data); 316 "sdhc1-detect", data);
317 if (ret) { 317 if (ret) {
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
index 19bb6441a7d4..c5f95674e9b7 100644
--- a/arch/arm/mach-imx/mach-pca100.c
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -20,7 +20,7 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/i2c.h> 22#include <linux/i2c.h>
23#include <linux/i2c/at24.h> 23#include <linux/platform_data/at24.h>
24#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
25#include <linux/spi/spi.h> 25#include <linux/spi/spi.h>
26#include <linux/spi/eeprom.h> 26#include <linux/spi/eeprom.h>
diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c
index bc0261e99d39..639a3dfb0092 100644
--- a/arch/arm/mach-imx/mach-pcm037.c
+++ b/arch/arm/mach-imx/mach-pcm037.c
@@ -23,7 +23,7 @@
23#include <linux/smsc911x.h> 23#include <linux/smsc911x.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/i2c/at24.h> 26#include <linux/platform_data/at24.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/spi/spi.h> 28#include <linux/spi/spi.h>
29#include <linux/irq.h> 29#include <linux/irq.h>
@@ -371,8 +371,7 @@ static int pcm970_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
371#endif 371#endif
372 372
373 ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SCK6)), detect_irq, 373 ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SCK6)), detect_irq,
374 IRQF_DISABLED | IRQF_TRIGGER_FALLING, 374 IRQF_TRIGGER_FALLING, "sdhc-detect", data);
375 "sdhc-detect", data);
376 if (ret) 375 if (ret)
377 goto err_gpio_free_2; 376 goto err_gpio_free_2;
378 377
diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c
index e805ac273e9c..592ddbe031ac 100644
--- a/arch/arm/mach-imx/mach-pcm038.c
+++ b/arch/arm/mach-imx/mach-pcm038.c
@@ -18,7 +18,7 @@
18 */ 18 */
19 19
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/i2c/at24.h> 21#include <linux/platform_data/at24.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/mtd/plat-ram.h> 23#include <linux/mtd/plat-ram.h>
24#include <linux/mtd/physmap.h> 24#include <linux/mtd/physmap.h>
diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c
index b726cb1c5fdd..ac504b67326b 100644
--- a/arch/arm/mach-imx/mach-pcm043.c
+++ b/arch/arm/mach-imx/mach-pcm043.c
@@ -24,7 +24,7 @@
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/i2c/at24.h> 27#include <linux/platform_data/at24.h>
28#include <linux/usb/otg.h> 28#include <linux/usb/otg.h>
29#include <linux/usb/ulpi.h> 29#include <linux/usb/ulpi.h>
30 30
diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c
index 816991deb9b8..af0cb8a9dc48 100644
--- a/arch/arm/mach-imx/mach-vf610.c
+++ b/arch/arm/mach-imx/mach-vf610.c
@@ -8,9 +8,7 @@
8 */ 8 */
9 9
10#include <linux/of_platform.h> 10#include <linux/of_platform.h>
11#include <linux/clocksource.h>
12#include <linux/irqchip.h> 11#include <linux/irqchip.h>
13#include <linux/clk-provider.h>
14#include <asm/mach/arch.h> 12#include <asm/mach/arch.h>
15#include <asm/hardware/cache-l2x0.h> 13#include <asm/hardware/cache-l2x0.h>
16 14
@@ -28,12 +26,6 @@ static void __init vf610_init_irq(void)
28 irqchip_init(); 26 irqchip_init();
29} 27}
30 28
31static void __init vf610_init_time(void)
32{
33 of_clk_init(NULL);
34 clocksource_of_init();
35}
36
37static const char *vf610_dt_compat[] __initdata = { 29static const char *vf610_dt_compat[] __initdata = {
38 "fsl,vf610", 30 "fsl,vf610",
39 NULL, 31 NULL,
@@ -41,7 +33,6 @@ static const char *vf610_dt_compat[] __initdata = {
41 33
42DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF610 (Device Tree)") 34DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF610 (Device Tree)")
43 .init_irq = vf610_init_irq, 35 .init_irq = vf610_init_irq,
44 .init_time = vf610_init_time,
45 .init_machine = vf610_init_machine, 36 .init_machine = vf610_init_machine,
46 .dt_compat = vf610_dt_compat, 37 .dt_compat = vf610_dt_compat,
47 .restart = mxc_restart, 38 .restart = mxc_restart,
diff --git a/arch/arm/mach-imx/mach-vpr200.c b/arch/arm/mach-imx/mach-vpr200.c
index 0910761e8280..8825d1217d18 100644
--- a/arch/arm/mach-imx/mach-vpr200.c
+++ b/arch/arm/mach-imx/mach-vpr200.c
@@ -29,7 +29,7 @@
29#include <asm/mach/time.h> 29#include <asm/mach/time.h>
30 30
31#include <linux/i2c.h> 31#include <linux/i2c.h>
32#include <linux/i2c/at24.h> 32#include <linux/platform_data/at24.h>
33#include <linux/mfd/mc13xxx.h> 33#include <linux/mfd/mc13xxx.h>
34 34
35#include "common.h" 35#include "common.h"
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c
index eb3cce38c70d..d1d52600f458 100644
--- a/arch/arm/mach-imx/mm-imx5.c
+++ b/arch/arm/mach-imx/mm-imx5.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/pinctrl/machine.h> 17#include <linux/pinctrl/machine.h>
18#include <linux/of_address.h>
18 19
19#include <asm/mach/map.h> 20#include <asm/mach/map.h>
20 21
@@ -88,8 +89,15 @@ void __init imx51_init_early(void)
88 89
89void __init imx53_init_early(void) 90void __init imx53_init_early(void)
90{ 91{
92 struct device_node *np;
93 void __iomem *base;
94
91 mxc_set_cpu_type(MXC_CPU_MX53); 95 mxc_set_cpu_type(MXC_CPU_MX53);
92 mxc_iomux_v3_init(MX53_IO_ADDRESS(MX53_IOMUXC_BASE_ADDR)); 96
97 np = of_find_compatible_node(NULL, NULL, "fsl,imx53-iomuxc");
98 base = of_iomap(np, 0);
99 WARN_ON(!base);
100 mxc_iomux_v3_init(base);
93 imx_src_init(); 101 imx_src_init();
94} 102}
95 103
@@ -100,7 +108,14 @@ void __init mx51_init_irq(void)
100 108
101void __init mx53_init_irq(void) 109void __init mx53_init_irq(void)
102{ 110{
103 tzic_init_irq(MX53_IO_ADDRESS(MX53_TZIC_BASE_ADDR)); 111 struct device_node *np;
112 void __iomem *base;
113
114 np = of_find_compatible_node(NULL, NULL, "fsl,imx53-tzic");
115 base = of_iomap(np, 0);
116 WARN_ON(!base);
117
118 tzic_init_irq(base);
104} 119}
105 120
106static struct sdma_platform_data imx51_sdma_pdata __initdata = { 121static struct sdma_platform_data imx51_sdma_pdata __initdata = {
diff --git a/arch/arm/mach-imx/mx31lilly-db.c b/arch/arm/mach-imx/mx31lilly-db.c
index d4361b80c5fb..649fe49ce85e 100644
--- a/arch/arm/mach-imx/mx31lilly-db.c
+++ b/arch/arm/mach-imx/mx31lilly-db.c
@@ -130,8 +130,7 @@ static int mxc_mmc1_init(struct device *dev,
130 gpio_direction_input(gpio_wp); 130 gpio_direction_input(gpio_wp);
131 131
132 ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)), 132 ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)),
133 detect_irq, 133 detect_irq, IRQF_TRIGGER_FALLING,
134 IRQF_DISABLED | IRQF_TRIGGER_FALLING,
135 "MMC detect", data); 134 "MMC detect", data);
136 if (ret) 135 if (ret)
137 goto exit_free_wp; 136 goto exit_free_wp;
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h
index 8629e5be7ecd..b08ab3ad4a6d 100644
--- a/arch/arm/mach-imx/mxc.h
+++ b/arch/arm/mach-imx/mxc.h
@@ -34,6 +34,7 @@
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_IMX6SL 0x60
37#define MXC_CPU_IMX6DL 0x61 38#define MXC_CPU_IMX6DL 0x61
38#define MXC_CPU_IMX6Q 0x63 39#define MXC_CPU_IMX6Q 0x63
39 40
@@ -152,6 +153,11 @@ extern unsigned int __mxc_cpu_type;
152#endif 153#endif
153 154
154#ifndef __ASSEMBLY__ 155#ifndef __ASSEMBLY__
156static inline bool cpu_is_imx6sl(void)
157{
158 return __mxc_cpu_type == MXC_CPU_IMX6SL;
159}
160
155static inline bool cpu_is_imx6dl(void) 161static inline bool cpu_is_imx6dl(void)
156{ 162{
157 return __mxc_cpu_type == MXC_CPU_IMX6DL; 163 return __mxc_cpu_type == MXC_CPU_IMX6DL;
diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c
index 204942749e21..aecd9f8037e0 100644
--- a/arch/arm/mach-imx/pm-imx6q.c
+++ b/arch/arm/mach-imx/pm-imx6q.c
@@ -10,9 +10,15 @@
10 * http://www.gnu.org/copyleft/gpl.html 10 * http://www.gnu.org/copyleft/gpl.html
11 */ 11 */
12 12
13#include <linux/delay.h>
13#include <linux/init.h> 14#include <linux/init.h>
14#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/irq.h>
17#include <linux/mfd/syscon.h>
18#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
15#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/of_address.h>
21#include <linux/regmap.h>
16#include <linux/suspend.h> 22#include <linux/suspend.h>
17#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
18#include <asm/proc-fns.h> 24#include <asm/proc-fns.h>
@@ -22,6 +28,147 @@
22#include "common.h" 28#include "common.h"
23#include "hardware.h" 29#include "hardware.h"
24 30
31#define CCR 0x0
32#define BM_CCR_WB_COUNT (0x7 << 16)
33#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21)
34#define BM_CCR_RBC_EN (0x1 << 27)
35
36#define CLPCR 0x54
37#define BP_CLPCR_LPM 0
38#define BM_CLPCR_LPM (0x3 << 0)
39#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
40#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
41#define BM_CLPCR_SBYOS (0x1 << 6)
42#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
43#define BM_CLPCR_VSTBY (0x1 << 8)
44#define BP_CLPCR_STBY_COUNT 9
45#define BM_CLPCR_STBY_COUNT (0x3 << 9)
46#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
47#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
48#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
49#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
50#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
51#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
52#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
53#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
54#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
55#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
56#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
57
58#define CGPR 0x64
59#define BM_CGPR_CHICKEN_BIT (0x1 << 17)
60
61static void __iomem *ccm_base;
62
63void imx6q_set_chicken_bit(void)
64{
65 u32 val = readl_relaxed(ccm_base + CGPR);
66
67 val |= BM_CGPR_CHICKEN_BIT;
68 writel_relaxed(val, ccm_base + CGPR);
69}
70
71static void imx6q_enable_rbc(bool enable)
72{
73 u32 val;
74
75 /*
76 * need to mask all interrupts in GPC before
77 * operating RBC configurations
78 */
79 imx_gpc_mask_all();
80
81 /* configure RBC enable bit */
82 val = readl_relaxed(ccm_base + CCR);
83 val &= ~BM_CCR_RBC_EN;
84 val |= enable ? BM_CCR_RBC_EN : 0;
85 writel_relaxed(val, ccm_base + CCR);
86
87 /* configure RBC count */
88 val = readl_relaxed(ccm_base + CCR);
89 val &= ~BM_CCR_RBC_BYPASS_COUNT;
90 val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
91 writel(val, ccm_base + CCR);
92
93 /*
94 * need to delay at least 2 cycles of CKIL(32K)
95 * due to hardware design requirement, which is
96 * ~61us, here we use 65us for safe
97 */
98 udelay(65);
99
100 /* restore GPC interrupt mask settings */
101 imx_gpc_restore_all();
102}
103
104static void imx6q_enable_wb(bool enable)
105{
106 u32 val;
107
108 /* configure well bias enable bit */
109 val = readl_relaxed(ccm_base + CLPCR);
110 val &= ~BM_CLPCR_WB_PER_AT_LPM;
111 val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
112 writel_relaxed(val, ccm_base + CLPCR);
113
114 /* configure well bias count */
115 val = readl_relaxed(ccm_base + CCR);
116 val &= ~BM_CCR_WB_COUNT;
117 val |= enable ? BM_CCR_WB_COUNT : 0;
118 writel_relaxed(val, ccm_base + CCR);
119}
120
121int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
122{
123 struct irq_desc *iomuxc_irq_desc;
124 u32 val = readl_relaxed(ccm_base + CLPCR);
125
126 val &= ~BM_CLPCR_LPM;
127 switch (mode) {
128 case WAIT_CLOCKED:
129 break;
130 case WAIT_UNCLOCKED:
131 val |= 0x1 << BP_CLPCR_LPM;
132 val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
133 break;
134 case STOP_POWER_ON:
135 val |= 0x2 << BP_CLPCR_LPM;
136 break;
137 case WAIT_UNCLOCKED_POWER_OFF:
138 val |= 0x1 << BP_CLPCR_LPM;
139 val &= ~BM_CLPCR_VSTBY;
140 val &= ~BM_CLPCR_SBYOS;
141 break;
142 case STOP_POWER_OFF:
143 val |= 0x2 << BP_CLPCR_LPM;
144 val |= 0x3 << BP_CLPCR_STBY_COUNT;
145 val |= BM_CLPCR_VSTBY;
146 val |= BM_CLPCR_SBYOS;
147 if (cpu_is_imx6sl()) {
148 val |= BM_CLPCR_BYPASS_PMIC_READY;
149 val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
150 } else {
151 val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
152 }
153 break;
154 default:
155 return -EINVAL;
156 }
157
158 /*
159 * Unmask the always pending IOMUXC interrupt #32 as wakeup source to
160 * deassert dsm_request signal, so that we can ensure dsm_request
161 * is not asserted when we're going to write CLPCR register to set LPM.
162 * After setting up LPM bits, we need to mask this wakeup source.
163 */
164 iomuxc_irq_desc = irq_to_desc(32);
165 imx_gpc_irq_unmask(&iomuxc_irq_desc->irq_data);
166 writel_relaxed(val, ccm_base + CLPCR);
167 imx_gpc_irq_mask(&iomuxc_irq_desc->irq_data);
168
169 return 0;
170}
171
25static int imx6q_suspend_finish(unsigned long val) 172static int imx6q_suspend_finish(unsigned long val)
26{ 173{
27 cpu_do_idle(); 174 cpu_do_idle();
@@ -33,14 +180,19 @@ static int imx6q_pm_enter(suspend_state_t state)
33 switch (state) { 180 switch (state) {
34 case PM_SUSPEND_MEM: 181 case PM_SUSPEND_MEM:
35 imx6q_set_lpm(STOP_POWER_OFF); 182 imx6q_set_lpm(STOP_POWER_OFF);
183 imx6q_enable_wb(true);
184 imx6q_enable_rbc(true);
36 imx_gpc_pre_suspend(); 185 imx_gpc_pre_suspend();
37 imx_anatop_pre_suspend(); 186 imx_anatop_pre_suspend();
38 imx_set_cpu_jump(0, v7_cpu_resume); 187 imx_set_cpu_jump(0, v7_cpu_resume);
39 /* Zzz ... */ 188 /* Zzz ... */
40 cpu_suspend(0, imx6q_suspend_finish); 189 cpu_suspend(0, imx6q_suspend_finish);
41 imx_smp_prepare(); 190 if (cpu_is_imx6q() || cpu_is_imx6dl())
191 imx_smp_prepare();
42 imx_anatop_post_resume(); 192 imx_anatop_post_resume();
43 imx_gpc_post_resume(); 193 imx_gpc_post_resume();
194 imx6q_enable_rbc(false);
195 imx6q_enable_wb(false);
44 imx6q_set_lpm(WAIT_CLOCKED); 196 imx6q_set_lpm(WAIT_CLOCKED);
45 break; 197 break;
46 default: 198 default:
@@ -55,7 +207,29 @@ static const struct platform_suspend_ops imx6q_pm_ops = {
55 .valid = suspend_valid_only_mem, 207 .valid = suspend_valid_only_mem,
56}; 208};
57 209
210void __init imx6q_pm_set_ccm_base(void __iomem *base)
211{
212 ccm_base = base;
213}
214
58void __init imx6q_pm_init(void) 215void __init imx6q_pm_init(void)
59{ 216{
217 struct regmap *gpr;
218
219 WARN_ON(!ccm_base);
220
221 /*
222 * Force IOMUXC irq pending, so that the interrupt to GPC can be
223 * used to deassert dsm_request signal when the signal gets
224 * asserted unexpectedly.
225 */
226 gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
227 if (!IS_ERR(gpr))
228 regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT,
229 IMX6Q_GPR1_GINT);
230
231 /* Set initial power mode */
232 imx6q_set_lpm(WAIT_CLOCKED);
233
60 suspend_set_ops(&imx6q_pm_ops); 234 suspend_set_ops(&imx6q_pm_ops);
61} 235}
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
index 10a6b1a8c5ac..45f7f4e0a447 100644
--- a/arch/arm/mach-imx/src.c
+++ b/arch/arm/mach-imx/src.c
@@ -91,6 +91,7 @@ void imx_enable_cpu(int cpu, bool enable)
91 spin_lock(&scr_lock); 91 spin_lock(&scr_lock);
92 val = readl_relaxed(src_base + SRC_SCR); 92 val = readl_relaxed(src_base + SRC_SCR);
93 val = enable ? val | mask : val & ~mask; 93 val = enable ? val | mask : val & ~mask;
94 val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1);
94 writel_relaxed(val, src_base + SRC_SCR); 95 writel_relaxed(val, src_base + SRC_SCR);
95 spin_unlock(&scr_lock); 96 spin_unlock(&scr_lock);
96} 97}
@@ -114,21 +115,6 @@ void imx_set_cpu_arg(int cpu, u32 arg)
114 writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); 115 writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4);
115} 116}
116 117
117void imx_src_prepare_restart(void)
118{
119 u32 val;
120
121 /* clear enable bits of secondary cores */
122 spin_lock(&scr_lock);
123 val = readl_relaxed(src_base + SRC_SCR);
124 val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE);
125 writel_relaxed(val, src_base + SRC_SCR);
126 spin_unlock(&scr_lock);
127
128 /* clear persistent entry register of primary core */
129 writel_relaxed(0, src_base + SRC_GPR1);
130}
131
132void __init imx_src_init(void) 118void __init imx_src_init(void)
133{ 119{
134 struct device_node *np; 120 struct device_node *np;
diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c
index 80c177c36c5f..5e3027d3692f 100644
--- a/arch/arm/mach-imx/system.c
+++ b/arch/arm/mach-imx/system.c
@@ -52,6 +52,15 @@ void mxc_restart(enum reboot_mode mode, const char *cmd)
52 52
53 /* Assert SRS signal */ 53 /* Assert SRS signal */
54 __raw_writew(wcr_enable, wdog_base); 54 __raw_writew(wcr_enable, wdog_base);
55 /*
56 * Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be
57 * written twice), we add another two writes to ensure there must be at
58 * least two writes happen in the same one 32kHz clock period. We save
59 * the target check here, since the writes shouldn't be a huge burden
60 * for other platforms.
61 */
62 __raw_writew(wcr_enable, wdog_base);
63 __raw_writew(wcr_enable, wdog_base);
55 64
56 /* wait for reset to assert... */ 65 /* wait for reset to assert... */
57 mdelay(500); 66 mdelay(500);
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index cd46529e9eaa..9b6638aadeaa 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -250,7 +250,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
250 250
251static struct irqaction mxc_timer_irq = { 251static struct irqaction mxc_timer_irq = {
252 .name = "i.MX Timer Tick", 252 .name = "i.MX Timer Tick",
253 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 253 .flags = IRQF_TIMER | IRQF_IRQPOLL,
254 .handler = mxc_timer_interrupt, 254 .handler = mxc_timer_interrupt,
255}; 255};
256 256