diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-12-16 05:04:49 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-12-16 05:04:49 -0500 |
commit | 348324c5b10bcba8d9daabdfb85a6927311be34f (patch) | |
tree | d06ca3a264407a14a1f36c1b798d6dc0dc1582d8 /arch/arm/mach-imx | |
parent | 1e63bd9cc43db5400a1423a7ec8266b4e7c54bd0 (diff) | |
parent | 319e2e3f63c348a9b66db4667efa73178e18b17d (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')
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 | |||
92 | config SOC_IMX1 | 93 | config 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 | ||
100 | config SOC_IMX21 | 100 | config 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 | ||
125 | config SOC_IMX31 | 122 | config 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 | |||
133 | config SOC_IMX35 | 129 | config 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 | ||
103 | ifeq ($(CONFIG_PM),y) | 103 | ifeq ($(CONFIG_PM),y) |
104 | obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o | 104 | obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o |
105 | # i.MX6SL reuses i.MX6Q code | ||
106 | obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o headsmp.o | ||
105 | endif | 107 | endif |
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 | ||
79 | u32 imx_anatop_get_digprog(void) | 81 | void __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 | ||
96 | void __init imx_anatop_init(void) | 115 | void __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 | ||
468 | int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, | 470 | static 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 | } | ||
474 | CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init_dt); | ||
475 | |||
476 | static 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); | |
573 | int __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 | |||
578 | int __init mx53_clocks_init_dt(void) | ||
579 | { | ||
580 | return mx53_clocks_init(0, 0, 0, 0); | ||
581 | } | 578 | } |
579 | CLK_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 | |||
67 | static void __iomem *ccm_base; | ||
68 | |||
69 | void 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 | |||
77 | static 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 | |||
115 | static 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 | |||
138 | int 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 | |||
177 | static const char *step_sels[] = { "osc", "pll2_pfd2_396m", }; | 27 | static const char *step_sels[] = { "osc", "pll2_pfd2_396m", }; |
178 | static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; | 28 | static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; |
179 | static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", }; | 29 | static 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", }; | |||
182 | static const char *periph_sels[] = { "periph_pre", "periph_clk2", }; | 32 | static const char *periph_sels[] = { "periph_pre", "periph_clk2", }; |
183 | static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; | 33 | static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; |
184 | static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", }; | 34 | static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", }; |
185 | static const char *audio_sels[] = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; | 35 | static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; |
186 | static const char *gpu_axi_sels[] = { "axi", "ahb", }; | 36 | static const char *gpu_axi_sels[] = { "axi", "ahb", }; |
187 | static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", }; | 37 | static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", }; |
188 | static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; | 38 | static 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 | |||
196 | static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; | 46 | static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; |
197 | static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", }; | 47 | static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", }; |
198 | static const char *pcie_axi_sels[] = { "axi", "ahb", }; | 48 | static const char *pcie_axi_sels[] = { "axi", "ahb", }; |
199 | static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_post_div", }; | 49 | static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_div", }; |
200 | static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; | 50 | static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; |
201 | static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", }; | 51 | static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", }; |
202 | static const char *emi_sels[] = { "pll2_pfd2_396m", "pll3_usb_otg", "axi", "pll2_pfd0_352m", }; | 52 | static 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", }; | |||
205 | static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", }; | 55 | static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", }; |
206 | static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", | 56 | static 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", }; |
209 | static const char *cko2_sels[] = { | 59 | static 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 | }; |
219 | static const char *cko_sels[] = { "cko1", "cko2", }; | 69 | static const char *cko_sels[] = { "cko1", "cko2", }; |
70 | static 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 | ||
221 | enum mx6q_clks { | 76 | enum 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 | ||
257 | static struct clk *clk[clk_max]; | 113 | static 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 | ||
271 | static struct clk_div_table post_div_table[] = { | 128 | static 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 | ||
278 | static struct clk_div_table video_div_table[] = { | 135 | static 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 | ||
286 | static void __init imx6q_clocks_init(struct device_node *ccm_node) | 143 | static 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 | ||
49 | static 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 | |||
48 | static int clk_pllv3_prepare(struct clk_hw *hw) | 70 | static 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 | ||
77 | static void clk_pllv3_unprepare(struct clk_hw *hw) | 94 | static 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 | ||
152 | static const struct clk_ops clk_pllv3_ops = { | 169 | static 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 | ||
208 | static const struct clk_ops clk_pllv3_sys_ops = { | 225 | static 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 | ||
282 | static const struct clk_ops clk_pllv3_av_ops = { | 299 | static 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 | ||
16 | struct irq_data; | ||
16 | struct platform_device; | 17 | struct platform_device; |
17 | struct pt_regs; | 18 | struct pt_regs; |
18 | struct clk; | 19 | struct clk; |
19 | enum mxc_cpu_pwr_mode; | 20 | enum mxc_cpu_pwr_mode; |
20 | 21 | ||
21 | extern void mx1_map_io(void); | 22 | void mx1_map_io(void); |
22 | extern void mx21_map_io(void); | 23 | void mx21_map_io(void); |
23 | extern void mx25_map_io(void); | 24 | void mx25_map_io(void); |
24 | extern void mx27_map_io(void); | 25 | void mx27_map_io(void); |
25 | extern void mx31_map_io(void); | 26 | void mx31_map_io(void); |
26 | extern void mx35_map_io(void); | 27 | void mx35_map_io(void); |
27 | extern void mx51_map_io(void); | 28 | void mx51_map_io(void); |
28 | extern void mx53_map_io(void); | 29 | void mx53_map_io(void); |
29 | extern void imx1_init_early(void); | 30 | void imx1_init_early(void); |
30 | extern void imx21_init_early(void); | 31 | void imx21_init_early(void); |
31 | extern void imx25_init_early(void); | 32 | void imx25_init_early(void); |
32 | extern void imx27_init_early(void); | 33 | void imx27_init_early(void); |
33 | extern void imx31_init_early(void); | 34 | void imx31_init_early(void); |
34 | extern void imx35_init_early(void); | 35 | void imx35_init_early(void); |
35 | extern void imx51_init_early(void); | 36 | void imx51_init_early(void); |
36 | extern void imx53_init_early(void); | 37 | void imx53_init_early(void); |
37 | extern void mxc_init_irq(void __iomem *); | 38 | void mxc_init_irq(void __iomem *); |
38 | extern void tzic_init_irq(void __iomem *); | 39 | void tzic_init_irq(void __iomem *); |
39 | extern void mx1_init_irq(void); | 40 | void mx1_init_irq(void); |
40 | extern void mx21_init_irq(void); | 41 | void mx21_init_irq(void); |
41 | extern void mx25_init_irq(void); | 42 | void mx25_init_irq(void); |
42 | extern void mx27_init_irq(void); | 43 | void mx27_init_irq(void); |
43 | extern void mx31_init_irq(void); | 44 | void mx31_init_irq(void); |
44 | extern void mx35_init_irq(void); | 45 | void mx35_init_irq(void); |
45 | extern void mx51_init_irq(void); | 46 | void mx51_init_irq(void); |
46 | extern void mx53_init_irq(void); | 47 | void mx53_init_irq(void); |
47 | extern void imx1_soc_init(void); | 48 | void imx1_soc_init(void); |
48 | extern void imx21_soc_init(void); | 49 | void imx21_soc_init(void); |
49 | extern void imx25_soc_init(void); | 50 | void imx25_soc_init(void); |
50 | extern void imx27_soc_init(void); | 51 | void imx27_soc_init(void); |
51 | extern void imx31_soc_init(void); | 52 | void imx31_soc_init(void); |
52 | extern void imx35_soc_init(void); | 53 | void imx35_soc_init(void); |
53 | extern void imx51_soc_init(void); | 54 | void imx51_soc_init(void); |
54 | extern void imx51_init_late(void); | 55 | void imx51_init_late(void); |
55 | extern void imx53_init_late(void); | 56 | void imx53_init_late(void); |
56 | extern void epit_timer_init(void __iomem *base, int irq); | 57 | void epit_timer_init(void __iomem *base, int irq); |
57 | extern void mxc_timer_init(void __iomem *, int); | 58 | void mxc_timer_init(void __iomem *, int); |
58 | extern int mx1_clocks_init(unsigned long fref); | 59 | int mx1_clocks_init(unsigned long fref); |
59 | extern int mx21_clocks_init(unsigned long lref, unsigned long fref); | 60 | int mx21_clocks_init(unsigned long lref, unsigned long fref); |
60 | extern int mx25_clocks_init(void); | 61 | int mx25_clocks_init(void); |
61 | extern int mx27_clocks_init(unsigned long fref); | 62 | int mx27_clocks_init(unsigned long fref); |
62 | extern int mx31_clocks_init(unsigned long fref); | 63 | int mx31_clocks_init(unsigned long fref); |
63 | extern int mx35_clocks_init(void); | 64 | int mx35_clocks_init(void); |
64 | extern int mx51_clocks_init(unsigned long ckil, unsigned long osc, | 65 | int mx51_clocks_init(unsigned long ckil, unsigned long osc, |
65 | unsigned long ckih1, unsigned long ckih2); | 66 | unsigned long ckih1, unsigned long ckih2); |
66 | extern int mx53_clocks_init(unsigned long ckil, unsigned long osc, | 67 | int mx25_clocks_init_dt(void); |
67 | unsigned long ckih1, unsigned long ckih2); | 68 | int mx27_clocks_init_dt(void); |
68 | extern int mx25_clocks_init_dt(void); | 69 | int mx31_clocks_init_dt(void); |
69 | extern int mx27_clocks_init_dt(void); | 70 | struct platform_device *mxc_register_gpio(char *name, int id, |
70 | extern int mx31_clocks_init_dt(void); | ||
71 | extern int mx51_clocks_init_dt(void); | ||
72 | extern int mx53_clocks_init_dt(void); | ||
73 | extern 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); |
75 | extern void mxc_set_cpu_type(unsigned int type); | 72 | void mxc_set_cpu_type(unsigned int type); |
76 | extern void mxc_restart(enum reboot_mode, const char *); | 73 | void mxc_restart(enum reboot_mode, const char *); |
77 | extern void mxc_arch_reset_init(void __iomem *); | 74 | void mxc_arch_reset_init(void __iomem *); |
78 | extern void mxc_arch_reset_init_dt(void); | 75 | void mxc_arch_reset_init_dt(void); |
79 | extern int mx53_revision(void); | 76 | int mx53_revision(void); |
80 | extern int imx6q_revision(void); | 77 | void imx_set_aips(void __iomem *); |
81 | extern int mx53_display_revision(void); | 78 | int mxc_device_init(void); |
82 | extern void imx_set_aips(void __iomem *); | 79 | void imx_set_soc_revision(unsigned int rev); |
83 | extern int mxc_device_init(void); | 80 | unsigned int imx_get_soc_revision(void); |
81 | void imx_init_revision_from_anatop(void); | ||
82 | struct device *imx_soc_device_init(void); | ||
84 | 83 | ||
85 | enum mxc_cpu_pwr_mode { | 84 | enum 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 | ||
100 | extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); | 99 | void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); |
101 | extern void imx_print_silicon_rev(const char *cpu, int srev); | 100 | void imx_print_silicon_rev(const char *cpu, int srev); |
102 | 101 | ||
103 | void avic_handle_irq(struct pt_regs *); | 102 | void avic_handle_irq(struct pt_regs *); |
104 | void tzic_handle_irq(struct pt_regs *); | 103 | void 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 | ||
115 | extern void imx_enable_cpu(int cpu, bool enable); | 114 | void imx_enable_cpu(int cpu, bool enable); |
116 | extern void imx_set_cpu_jump(int cpu, void *jump_addr); | 115 | void imx_set_cpu_jump(int cpu, void *jump_addr); |
117 | extern u32 imx_get_cpu_arg(int cpu); | 116 | u32 imx_get_cpu_arg(int cpu); |
118 | extern void imx_set_cpu_arg(int cpu, u32 arg); | 117 | void imx_set_cpu_arg(int cpu, u32 arg); |
119 | extern void v7_cpu_resume(void); | 118 | void v7_cpu_resume(void); |
120 | #ifdef CONFIG_SMP | 119 | #ifdef CONFIG_SMP |
121 | extern void v7_secondary_startup(void); | 120 | void v7_secondary_startup(void); |
122 | extern void imx_scu_map_io(void); | 121 | void imx_scu_map_io(void); |
123 | extern void imx_smp_prepare(void); | 122 | void imx_smp_prepare(void); |
124 | extern void imx_scu_standby_enable(void); | 123 | void imx_scu_standby_enable(void); |
125 | #else | 124 | #else |
126 | static inline void imx_scu_map_io(void) {} | 125 | static inline void imx_scu_map_io(void) {} |
127 | static inline void imx_smp_prepare(void) {} | 126 | static inline void imx_smp_prepare(void) {} |
128 | static inline void imx_scu_standby_enable(void) {} | 127 | static inline void imx_scu_standby_enable(void) {} |
129 | #endif | 128 | #endif |
130 | extern void imx_src_init(void); | 129 | void imx_src_init(void); |
131 | extern void imx_src_prepare_restart(void); | 130 | void imx_gpc_init(void); |
132 | extern void imx_gpc_init(void); | 131 | void imx_gpc_pre_suspend(void); |
133 | extern void imx_gpc_pre_suspend(void); | 132 | void imx_gpc_post_resume(void); |
134 | extern void imx_gpc_post_resume(void); | 133 | void imx_gpc_mask_all(void); |
135 | extern void imx_gpc_mask_all(void); | 134 | void imx_gpc_restore_all(void); |
136 | extern void imx_gpc_restore_all(void); | 135 | void imx_gpc_irq_mask(struct irq_data *d); |
137 | extern void imx_anatop_init(void); | 136 | void imx_gpc_irq_unmask(struct irq_data *d); |
138 | extern void imx_anatop_pre_suspend(void); | 137 | void imx_anatop_init(void); |
139 | extern void imx_anatop_post_resume(void); | 138 | void imx_anatop_pre_suspend(void); |
140 | extern u32 imx_anatop_get_digprog(void); | 139 | void imx_anatop_post_resume(void); |
141 | extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); | 140 | int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); |
142 | extern void imx6q_set_chicken_bit(void); | 141 | void imx6q_set_chicken_bit(void); |
143 | 142 | ||
144 | extern void imx_cpu_die(unsigned int cpu); | 143 | void imx_cpu_die(unsigned int cpu); |
145 | extern int imx_cpu_kill(unsigned int cpu); | 144 | int imx_cpu_kill(unsigned int cpu); |
146 | 145 | ||
147 | #ifdef CONFIG_PM | 146 | #ifdef CONFIG_PM |
148 | extern void imx6q_pm_init(void); | 147 | void imx6q_pm_init(void); |
149 | extern void imx5_pm_init(void); | 148 | void imx6q_pm_set_ccm_base(void __iomem *base); |
149 | void imx5_pm_init(void); | ||
150 | #else | 150 | #else |
151 | static inline void imx6q_pm_init(void) {} | 151 | static inline void imx6q_pm_init(void) {} |
152 | static inline void imx6q_pm_set_ccm_base(void __iomem *base) {} | ||
152 | static inline void imx5_pm_init(void) {} | 153 | static inline void imx5_pm_init(void) {} |
153 | #endif | 154 | #endif |
154 | 155 | ||
155 | #ifdef CONFIG_NEON | 156 | #ifdef CONFIG_NEON |
156 | extern int mx51_neon_fixup(void); | 157 | int mx51_neon_fixup(void); |
157 | #else | 158 | #else |
158 | static inline int mx51_neon_fixup(void) { return 0; } | 159 | static inline int mx51_neon_fixup(void) { return 0; } |
159 | #endif | 160 | #endif |
160 | 161 | ||
161 | #ifdef CONFIG_CACHE_L2X0 | 162 | #ifdef CONFIG_CACHE_L2X0 |
162 | extern void imx_init_l2cache(void); | 163 | void imx_init_l2cache(void); |
163 | #else | 164 | #else |
164 | static inline void imx_init_l2cache(void) {} | 165 | static 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 @@ | |||
8 | unsigned int __mxc_cpu_type; | 11 | unsigned int __mxc_cpu_type; |
9 | EXPORT_SYMBOL(__mxc_cpu_type); | 12 | EXPORT_SYMBOL(__mxc_cpu_type); |
10 | 13 | ||
14 | static unsigned int imx_soc_revision; | ||
15 | |||
11 | void mxc_set_cpu_type(unsigned int type) | 16 | void mxc_set_cpu_type(unsigned int type) |
12 | { | 17 | { |
13 | __mxc_cpu_type = type; | 18 | __mxc_cpu_type = type; |
14 | } | 19 | } |
15 | 20 | ||
21 | void imx_set_soc_revision(unsigned int rev) | ||
22 | { | ||
23 | imx_soc_revision = rev; | ||
24 | } | ||
25 | |||
26 | unsigned int imx_get_soc_revision(void) | ||
27 | { | ||
28 | return imx_soc_revision; | ||
29 | } | ||
30 | |||
16 | void imx_print_silicon_rev(const char *cpu, int srev) | 31 | void 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 | |||
63 | struct 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 | |||
134 | free_rev: | ||
135 | kfree(soc_dev_attr->revision); | ||
136 | free_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 | ||
172 | static struct irqaction epit_timer_irq = { | 172 | static 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 | ||
93 | static void imx_gpc_irq_unmask(struct irq_data *d) | 93 | void 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 | ||
108 | static void imx_gpc_irq_mask(struct irq_data *d) | 108 | void 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 | ||
58 | int imx_cpu_kill(unsigned int cpu) | 60 | int 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 | ||
37 | static void __init imx51_timer_init(void) | ||
38 | { | ||
39 | mx51_clocks_init_dt(); | ||
40 | } | ||
41 | |||
42 | DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)") | 37 | DT_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 | ||
39 | static void __init imx53_timer_init(void) | ||
40 | { | ||
41 | mx53_clocks_init_dt(); | ||
42 | } | ||
43 | |||
44 | DT_MACHINE_START(IMX53_DT, "Freescale i.MX53 (Device Tree Support)") | 39 | DT_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 | ||
43 | static u32 chip_revision; | ||
44 | |||
45 | int imx6q_revision(void) | ||
46 | { | ||
47 | return chip_revision; | ||
48 | } | ||
49 | |||
50 | static 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 | |||
71 | static 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 | |||
96 | soft: | ||
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 */ |
102 | static int ksz9021rn_phy_fixup(struct phy_device *phydev) | 41 | static int ksz9021rn_phy_fixup(struct phy_device *phydev) |
103 | { | 42 | { |
@@ -192,9 +131,20 @@ static void __init imx6q_1588_init(void) | |||
192 | 131 | ||
193 | static void __init imx6q_init_machine(void) | 132 | static 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 | ||
232 | put_node: | 182 | put_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 | ||
287 | static void __init imx6q_init_irq(void) | 237 | static 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 | ||
296 | static 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 | |||
304 | static const char *imx6q_dt_compat[] __initdata = { | 246 | static 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, |
319 | MACHINE_END | 260 | MACHINE_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 | ||
21 | static 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 | |||
19 | static void __init imx6sl_init_machine(void) | 37 | static 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 | ||
26 | static void __init imx6sl_init_irq(void) | 55 | static 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 | ||
34 | static void __init imx6sl_timer_init(void) | ||
35 | { | ||
36 | of_clk_init(NULL); | ||
37 | } | ||
38 | |||
39 | static const char *imx6sl_dt_compat[] __initdata = { | 64 | static 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 = { | |||
44 | DT_MACHINE_START(IMX6SL, "Freescale i.MX6 SoloLite (Device Tree)") | 69 | DT_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 | ||
31 | static void __init vf610_init_time(void) | ||
32 | { | ||
33 | of_clk_init(NULL); | ||
34 | clocksource_of_init(); | ||
35 | } | ||
36 | |||
37 | static const char *vf610_dt_compat[] __initdata = { | 29 | static 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 | ||
42 | DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF610 (Device Tree)") | 34 | DT_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 | ||
89 | void __init imx53_init_early(void) | 90 | void __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 | ||
101 | void __init mx53_init_irq(void) | 109 | void __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 | ||
106 | static struct sdma_platform_data imx51_sdma_pdata __initdata = { | 121 | static 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__ |
156 | static inline bool cpu_is_imx6sl(void) | ||
157 | { | ||
158 | return __mxc_cpu_type == MXC_CPU_IMX6SL; | ||
159 | } | ||
160 | |||
155 | static inline bool cpu_is_imx6dl(void) | 161 | static 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 | |||
61 | static void __iomem *ccm_base; | ||
62 | |||
63 | void 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 | |||
71 | static 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 | |||
104 | static 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 | |||
121 | int 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 | |||
25 | static int imx6q_suspend_finish(unsigned long val) | 172 | static 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 | ||
210 | void __init imx6q_pm_set_ccm_base(void __iomem *base) | ||
211 | { | ||
212 | ccm_base = base; | ||
213 | } | ||
214 | |||
58 | void __init imx6q_pm_init(void) | 215 | void __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 | ||
117 | void 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 | |||
132 | void __init imx_src_init(void) | 118 | void __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 | ||
251 | static struct irqaction mxc_timer_irq = { | 251 | static 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 | ||