diff options
author | Olof Johansson <olof@lixom.net> | 2013-10-28 13:37:52 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-10-28 13:37:52 -0400 |
commit | b6fb5474af552779c9900c961698f60db3b65023 (patch) | |
tree | 065a0c4be9342816d685a8b3c723c4b1a50133c3 | |
parent | 826f57b497c265702422770afda59893ac476817 (diff) | |
parent | 9ba64fe3eb461b95bf11436a13db0d9c79465514 (diff) |
Merge tag 'imx-soc-3.13' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/soc
From Shawn Guo:
The imx/mxs soc changes for 3.13:
* Low-level debug support for Vybrid
* Support soc bus/device for imx6
* Suspend support for imx6dl and imx6sl
* The imx6q clock updates for PCIe and audio PLL support
* IOMUXC GPR update for fec support
* Some random cleanup
* A few defconfig updates
* tag 'imx-soc-3.13' of git://git.linaro.org/people/shawnguo/linux-2.6: (31 commits)
ARM: imx: enable suspend for imx6sl
ARM: imx: ensure dsm_request signal is not asserted when setting LPM
ARM: imx6q: call WB and RBC configuration from imx6q_pm_enter()
ARM: imx6q: move low-power code out of clock driver
ARM: imx: drop extern with function prototypes in common.h
ARM: imx: reset core along with enable/disable operation
ARM: imx: do not return from imx_cpu_die() call
ARM: imx_v6_v7_defconfig: Select CONFIG_PROVE_LOCKING
ARM: imx_v6_v7_defconfig: Enable LEDS_GPIO related options
ARM: mxs_defconfig: Turn off CONFIG_DEBUG_GPIO
ARM: imx: replace imx6q_restart() with mxc_restart()
ARM: mach-imx: mm-imx5: Retrieve iomuxc base address from dt
ARM: mach-imx: mm-imx5: Retrieve tzic base address from dt
ARM: mach-imx: clk-imx51-imx53: Retrieve base address and irq from dt
ARM: mxs_defconfig: Add CHIPIDEA_UDC support
ARM: imx: Include linux/err.h
ARM: imx_v6_v7_defconfig: Add CHIPIDEA_UDC support
ARM: imx_v6_v7_defconfig: Add SPDIF support
ARM: imx6q: clock and Kconfig update for PCIe support
ARM: imx: Add LVDS general-purpose clocks to i.MX6Q
...
Signed-off-by: Olof Johansson <olof@lixom.net>
30 files changed, 593 insertions, 347 deletions
diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt index 5a90a724b520..6aab72bf67ea 100644 --- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt | |||
@@ -215,6 +215,11 @@ clocks and IDs. | |||
215 | cko2 200 | 215 | cko2 200 |
216 | cko 201 | 216 | cko 201 |
217 | vdoa 202 | 217 | vdoa 202 |
218 | pll4_audio_div 203 | ||
219 | lvds1_sel 204 | ||
220 | lvds2_sel 205 | ||
221 | lvds1_gate 206 | ||
222 | lvds2_gate 207 | ||
218 | 223 | ||
219 | Examples: | 224 | Examples: |
220 | 225 | ||
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 9762c84b4198..d597c6b8488b 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -386,6 +386,13 @@ choice | |||
386 | when u-boot hands over to the kernel, the system | 386 | when u-boot hands over to the kernel, the system |
387 | silently crashes, with no serial output at all. | 387 | silently crashes, with no serial output at all. |
388 | 388 | ||
389 | config DEBUG_VF_UART | ||
390 | bool "Vybrid UART" | ||
391 | depends on SOC_VF610 | ||
392 | help | ||
393 | Say Y here if you want kernel low-level debugging support | ||
394 | on Vybrid based platforms. | ||
395 | |||
389 | config DEBUG_NOMADIK_UART | 396 | config DEBUG_NOMADIK_UART |
390 | bool "Kernel low-level debugging messages via NOMADIK UART" | 397 | bool "Kernel low-level debugging messages via NOMADIK UART" |
391 | depends on ARCH_NOMADIK | 398 | depends on ARCH_NOMADIK |
@@ -906,6 +913,7 @@ config DEBUG_LL_INCLUDE | |||
906 | default "debug/tegra.S" if DEBUG_TEGRA_UART | 913 | default "debug/tegra.S" if DEBUG_TEGRA_UART |
907 | default "debug/ux500.S" if DEBUG_UX500_UART | 914 | default "debug/ux500.S" if DEBUG_UX500_UART |
908 | default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT | 915 | default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT |
916 | default "debug/vf.S" if DEBUG_VF_UART | ||
909 | default "debug/vt8500.S" if DEBUG_VT8500_UART0 | 917 | default "debug/vt8500.S" if DEBUG_VT8500_UART0 |
910 | default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1 | 918 | default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1 |
911 | default "mach/debug-macro.S" | 919 | default "mach/debug-macro.S" |
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index c46651e4d966..177d9e791a01 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi | |||
@@ -380,7 +380,9 @@ | |||
380 | }; | 380 | }; |
381 | 381 | ||
382 | anatop: anatop@020c8000 { | 382 | anatop: anatop@020c8000 { |
383 | compatible = "fsl,imx6sl-anatop", "syscon", "simple-bus"; | 383 | compatible = "fsl,imx6sl-anatop", |
384 | "fsl,imx6q-anatop", | ||
385 | "syscon", "simple-bus"; | ||
384 | reg = <0x020c8000 0x1000>; | 386 | reg = <0x020c8000 0x1000>; |
385 | interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>; | 387 | interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>; |
386 | 388 | ||
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 5d488c24b132..8d0c5a018ed7 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig | |||
@@ -132,7 +132,6 @@ CONFIG_TOUCHSCREEN_MC13783=y | |||
132 | CONFIG_INPUT_MISC=y | 132 | CONFIG_INPUT_MISC=y |
133 | CONFIG_INPUT_MMA8450=y | 133 | CONFIG_INPUT_MMA8450=y |
134 | CONFIG_SERIO_SERPORT=m | 134 | CONFIG_SERIO_SERPORT=m |
135 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
136 | # CONFIG_LEGACY_PTYS is not set | 135 | # CONFIG_LEGACY_PTYS is not set |
137 | # CONFIG_DEVKMEM is not set | 136 | # CONFIG_DEVKMEM is not set |
138 | CONFIG_SERIAL_IMX=y | 137 | CONFIG_SERIAL_IMX=y |
@@ -188,22 +187,33 @@ CONFIG_SND_SOC_PHYCORE_AC97=y | |||
188 | CONFIG_SND_SOC_EUKREA_TLV320=y | 187 | CONFIG_SND_SOC_EUKREA_TLV320=y |
189 | CONFIG_SND_SOC_IMX_WM8962=y | 188 | CONFIG_SND_SOC_IMX_WM8962=y |
190 | CONFIG_SND_SOC_IMX_SGTL5000=y | 189 | CONFIG_SND_SOC_IMX_SGTL5000=y |
190 | CONFIG_SND_SOC_IMX_SPDIF=y | ||
191 | CONFIG_SND_SOC_IMX_MC13783=y | 191 | CONFIG_SND_SOC_IMX_MC13783=y |
192 | CONFIG_USB=y | 192 | CONFIG_USB=y |
193 | CONFIG_USB_EHCI_HCD=y | 193 | CONFIG_USB_EHCI_HCD=y |
194 | CONFIG_USB_EHCI_MXC=y | 194 | CONFIG_USB_EHCI_MXC=y |
195 | CONFIG_USB_STORAGE=y | 195 | CONFIG_USB_STORAGE=y |
196 | CONFIG_USB_CHIPIDEA=y | 196 | CONFIG_USB_CHIPIDEA=y |
197 | CONFIG_USB_CHIPIDEA_UDC=y | ||
197 | CONFIG_USB_CHIPIDEA_HOST=y | 198 | CONFIG_USB_CHIPIDEA_HOST=y |
198 | CONFIG_USB_PHY=y | ||
199 | CONFIG_NOP_USB_XCEIV=y | 199 | CONFIG_NOP_USB_XCEIV=y |
200 | CONFIG_USB_MXS_PHY=y | 200 | CONFIG_USB_MXS_PHY=y |
201 | CONFIG_USB_GADGET=y | ||
202 | CONFIG_USB_ETH=m | ||
203 | CONFIG_USB_MASS_STORAGE=m | ||
201 | CONFIG_MMC=y | 204 | CONFIG_MMC=y |
202 | CONFIG_MMC_SDHCI=y | 205 | CONFIG_MMC_SDHCI=y |
203 | CONFIG_MMC_SDHCI_PLTFM=y | 206 | CONFIG_MMC_SDHCI_PLTFM=y |
204 | CONFIG_MMC_SDHCI_ESDHC_IMX=y | 207 | CONFIG_MMC_SDHCI_ESDHC_IMX=y |
205 | CONFIG_NEW_LEDS=y | 208 | CONFIG_NEW_LEDS=y |
206 | CONFIG_LEDS_CLASS=y | 209 | CONFIG_LEDS_CLASS=y |
210 | CONFIG_LEDS_GPIO=y | ||
211 | CONFIG_LEDS_TRIGGERS=y | ||
212 | CONFIG_LEDS_TRIGGER_TIMER=y | ||
213 | CONFIG_LEDS_TRIGGER_ONESHOT=y | ||
214 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
215 | CONFIG_LEDS_TRIGGER_BACKLIGHT=y | ||
216 | CONFIG_LEDS_TRIGGER_GPIO=y | ||
207 | CONFIG_RTC_CLASS=y | 217 | CONFIG_RTC_CLASS=y |
208 | CONFIG_RTC_INTF_DEV_UIE_EMUL=y | 218 | CONFIG_RTC_INTF_DEV_UIE_EMUL=y |
209 | CONFIG_RTC_DRV_MC13XXX=y | 219 | CONFIG_RTC_DRV_MC13XXX=y |
@@ -246,7 +256,6 @@ CONFIG_UDF_FS=m | |||
246 | CONFIG_MSDOS_FS=m | 256 | CONFIG_MSDOS_FS=m |
247 | CONFIG_VFAT_FS=y | 257 | CONFIG_VFAT_FS=y |
248 | CONFIG_TMPFS=y | 258 | CONFIG_TMPFS=y |
249 | CONFIG_CONFIGFS_FS=m | ||
250 | CONFIG_JFFS2_FS=y | 259 | CONFIG_JFFS2_FS=y |
251 | CONFIG_UBIFS_FS=y | 260 | CONFIG_UBIFS_FS=y |
252 | CONFIG_NFS_FS=y | 261 | CONFIG_NFS_FS=y |
@@ -261,6 +270,7 @@ CONFIG_NLS_ISO8859_15=m | |||
261 | CONFIG_NLS_UTF8=y | 270 | CONFIG_NLS_UTF8=y |
262 | CONFIG_MAGIC_SYSRQ=y | 271 | CONFIG_MAGIC_SYSRQ=y |
263 | # CONFIG_SCHED_DEBUG is not set | 272 | # CONFIG_SCHED_DEBUG is not set |
273 | CONFIG_PROVE_LOCKING=y | ||
264 | # CONFIG_DEBUG_BUGVERBOSE is not set | 274 | # CONFIG_DEBUG_BUGVERBOSE is not set |
265 | # CONFIG_FTRACE is not set | 275 | # CONFIG_FTRACE is not set |
266 | # CONFIG_ARM_UNWIND is not set | 276 | # CONFIG_ARM_UNWIND is not set |
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index 4555c025629a..6150108e15de 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig | |||
@@ -76,7 +76,6 @@ CONFIG_INPUT_EVDEV=y | |||
76 | CONFIG_INPUT_TOUCHSCREEN=y | 76 | CONFIG_INPUT_TOUCHSCREEN=y |
77 | CONFIG_TOUCHSCREEN_TSC2007=m | 77 | CONFIG_TOUCHSCREEN_TSC2007=m |
78 | # CONFIG_SERIO is not set | 78 | # CONFIG_SERIO is not set |
79 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
80 | CONFIG_DEVPTS_MULTIPLE_INSTANCES=y | 79 | CONFIG_DEVPTS_MULTIPLE_INSTANCES=y |
81 | # CONFIG_LEGACY_PTYS is not set | 80 | # CONFIG_LEGACY_PTYS is not set |
82 | # CONFIG_DEVKMEM is not set | 81 | # CONFIG_DEVKMEM is not set |
@@ -91,7 +90,6 @@ CONFIG_I2C_MXS=y | |||
91 | CONFIG_SPI=y | 90 | CONFIG_SPI=y |
92 | CONFIG_SPI_GPIO=m | 91 | CONFIG_SPI_GPIO=m |
93 | CONFIG_SPI_MXS=y | 92 | CONFIG_SPI_MXS=y |
94 | CONFIG_DEBUG_GPIO=y | ||
95 | CONFIG_GPIO_SYSFS=y | 93 | CONFIG_GPIO_SYSFS=y |
96 | # CONFIG_HWMON is not set | 94 | # CONFIG_HWMON is not set |
97 | CONFIG_WATCHDOG=y | 95 | CONFIG_WATCHDOG=y |
@@ -115,9 +113,12 @@ CONFIG_USB=y | |||
115 | CONFIG_USB_EHCI_HCD=y | 113 | CONFIG_USB_EHCI_HCD=y |
116 | CONFIG_USB_STORAGE=y | 114 | CONFIG_USB_STORAGE=y |
117 | CONFIG_USB_CHIPIDEA=y | 115 | CONFIG_USB_CHIPIDEA=y |
116 | CONFIG_USB_CHIPIDEA_UDC=y | ||
118 | CONFIG_USB_CHIPIDEA_HOST=y | 117 | CONFIG_USB_CHIPIDEA_HOST=y |
119 | CONFIG_USB_PHY=y | ||
120 | CONFIG_USB_MXS_PHY=y | 118 | CONFIG_USB_MXS_PHY=y |
119 | CONFIG_USB_GADGET=y | ||
120 | CONFIG_USB_ETH=m | ||
121 | CONFIG_USB_MASS_STORAGE=m | ||
121 | CONFIG_MMC=y | 122 | CONFIG_MMC=y |
122 | CONFIG_MMC_UNSAFE_RESUME=y | 123 | CONFIG_MMC_UNSAFE_RESUME=y |
123 | CONFIG_MMC_MXS=y | 124 | CONFIG_MMC_MXS=y |
diff --git a/arch/arm/include/debug/vf.S b/arch/arm/include/debug/vf.S new file mode 100644 index 000000000000..ba12cc44b2cb --- /dev/null +++ b/arch/arm/include/debug/vf.S | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Freescale Semiconductor, Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | .macro addruart, rp, rv, tmp | ||
11 | ldr \rp, =0x40028000 @ physical | ||
12 | ldr \rv, =0xfe028000 @ virtual | ||
13 | .endm | ||
14 | |||
15 | .macro senduart, rd, rx | ||
16 | strb \rd, [\rx, #0x7] @ Data Register | ||
17 | .endm | ||
18 | |||
19 | .macro busyuart, rd, rx | ||
20 | 1001: ldrb \rd, [\rx, #0x4] @ Status Register 1 | ||
21 | tst \rd, #1 << 6 @ TC | ||
22 | beq 1001b @ wait until transmit done | ||
23 | .endm | ||
24 | |||
25 | .macro waituart,rd,rx | ||
26 | .endm | ||
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 29a8af6922a8..270f78667dc6 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig | |||
@@ -11,6 +11,7 @@ config ARCH_MXC | |||
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. |
@@ -801,6 +802,8 @@ config SOC_IMX6Q | |||
801 | select HAVE_IMX_SRC | 802 | select HAVE_IMX_SRC |
802 | select HAVE_SMP | 803 | select HAVE_SMP |
803 | select MFD_SYSCON | 804 | select MFD_SYSCON |
805 | select MIGHT_HAVE_PCI | ||
806 | select PCI_DOMAINS if PCI | ||
804 | select PINCTRL | 807 | select PINCTRL |
805 | select PINCTRL_IMX6Q | 808 | select PINCTRL_IMX6Q |
806 | select PL310_ERRATA_588369 if CACHE_PL310 | 809 | select PL310_ERRATA_588369 if CACHE_PL310 |
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 5383c589ad71..bbe1f5bb799c 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 pm-imx6q.c | ||
106 | obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.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 ceaac9cd7b42..ce37af26ff8c 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c | |||
@@ -14,6 +14,9 @@ | |||
14 | #include <linux/clk-provider.h> | 14 | #include <linux/clk-provider.h> |
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #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> | ||
17 | 20 | ||
18 | #include "crm-regs-imx5.h" | 21 | #include "crm-regs-imx5.h" |
19 | #include "clk.h" | 22 | #include "clk.h" |
@@ -472,8 +475,9 @@ CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init_dt); | |||
472 | 475 | ||
473 | static void __init mx53_clocks_init(struct device_node *np) | 476 | static void __init mx53_clocks_init(struct device_node *np) |
474 | { | 477 | { |
475 | int i; | 478 | int i, irq; |
476 | unsigned long r; | 479 | unsigned long r; |
480 | void __iomem *base; | ||
477 | 481 | ||
478 | 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); |
479 | 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); |
@@ -559,14 +563,17 @@ static void __init mx53_clocks_init(struct device_node *np) | |||
559 | clk_set_rate(clk[esdhc_a_podf], 200000000); | 563 | clk_set_rate(clk[esdhc_a_podf], 200000000); |
560 | clk_set_rate(clk[esdhc_b_podf], 200000000); | 564 | clk_set_rate(clk[esdhc_b_podf], 200000000); |
561 | 565 | ||
562 | /* System timer */ | ||
563 | mxc_timer_init(MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), MX53_INT_GPT); | ||
564 | |||
565 | clk_prepare_enable(clk[iim_gate]); | 566 | clk_prepare_enable(clk[iim_gate]); |
566 | imx_print_silicon_rev("i.MX53", mx53_revision()); | 567 | imx_print_silicon_rev("i.MX53", mx53_revision()); |
567 | clk_disable_unprepare(clk[iim_gate]); | 568 | clk_disable_unprepare(clk[iim_gate]); |
568 | 569 | ||
569 | r = clk_round_rate(clk[usboh3_per_gate], 54000000); | 570 | r = clk_round_rate(clk[usboh3_per_gate], 54000000); |
570 | clk_set_rate(clk[usboh3_per_gate], r); | 571 | clk_set_rate(clk[usboh3_per_gate], r); |
572 | |||
573 | np = of_find_compatible_node(NULL, NULL, "fsl,imx53-gpt"); | ||
574 | base = of_iomap(np, 0); | ||
575 | WARN_ON(!base); | ||
576 | irq = irq_of_parse_and_map(np, 0); | ||
577 | mxc_timer_init(base, irq); | ||
571 | } | 578 | } |
572 | CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init); | 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..d756d91fd741 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]; |
@@ -300,7 +156,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
300 | WARN_ON(!base); | 156 | WARN_ON(!base); |
301 | 157 | ||
302 | /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */ | 158 | /* 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) { | 159 | if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) { |
304 | post_div_table[1].div = 1; | 160 | post_div_table[1].div = 1; |
305 | post_div_table[2].div = 1; | 161 | post_div_table[2].div = 1; |
306 | video_div_table[1].div = 1; | 162 | video_div_table[1].div = 1; |
@@ -342,6 +198,18 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
342 | base + 0xe0, 0, 2, 0, clk_enet_ref_table, | 198 | base + 0xe0, 0, 2, 0, clk_enet_ref_table, |
343 | &imx_ccm_lock); | 199 | &imx_ccm_lock); |
344 | 200 | ||
201 | clk[lvds1_sel] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); | ||
202 | clk[lvds2_sel] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); | ||
203 | |||
204 | /* | ||
205 | * lvds1_gate and lvds2_gate are pseudo-gates. Both can be | ||
206 | * independently configured as clock inputs or outputs. We treat | ||
207 | * the "output_enable" bit as a gate, even though it's really just | ||
208 | * enabling clock output. | ||
209 | */ | ||
210 | clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "dummy", base + 0x160, 10); | ||
211 | clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "dummy", base + 0x160, 11); | ||
212 | |||
345 | /* name parent_name reg idx */ | 213 | /* name parent_name reg idx */ |
346 | clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); | 214 | 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); | 215 | clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); |
@@ -359,13 +227,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
359 | clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2); | 227 | clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2); |
360 | 228 | ||
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); | 229 | 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_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); | 231 | 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); | 232 | 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 | 233 | ||
365 | np = ccm_node; | 234 | np = ccm_node; |
366 | base = of_iomap(np, 0); | 235 | base = of_iomap(np, 0); |
367 | WARN_ON(!base); | 236 | WARN_ON(!base); |
368 | ccm_base = base; | 237 | |
238 | imx6q_pm_set_ccm_base(base); | ||
369 | 239 | ||
370 | /* name reg shift width parent_names num_parents */ | 240 | /* 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)); | 241 | clk[step] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); |
@@ -573,7 +443,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
573 | clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL); | 443 | clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL); |
574 | clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL); | 444 | clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL); |
575 | 445 | ||
576 | if ((imx6q_revision() != IMX_CHIP_REVISION_1_0) || cpu_is_imx6dl()) { | 446 | if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) || |
447 | cpu_is_imx6dl()) { | ||
577 | clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]); | 448 | clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]); |
578 | clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]); | 449 | clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]); |
579 | } | 450 | } |
@@ -603,8 +474,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
603 | if (ret) | 474 | if (ret) |
604 | pr_warn("failed to set up CLKO: %d\n", ret); | 475 | pr_warn("failed to set up CLKO: %d\n", ret); |
605 | 476 | ||
606 | /* Set initial power mode */ | 477 | /* All existing boards with PCIe use LVDS1 */ |
607 | imx6q_set_lpm(WAIT_CLOCKED); | 478 | if (IS_ENABLED(CONFIG_PCI_IMX6)) |
479 | clk_set_parent(clk[lvds1_sel], clk[sata_ref]); | ||
608 | 480 | ||
609 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt"); | 481 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt"); |
610 | base = of_iomap(np, 0); | 482 | 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/common.h b/arch/arm/mach-imx/common.h index 28e8ca0871e8..7cbe22d0c6e9 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h | |||
@@ -13,70 +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 mx25_clocks_init_dt(void); | 67 | int mx25_clocks_init_dt(void); |
67 | extern int mx27_clocks_init_dt(void); | 68 | int mx27_clocks_init_dt(void); |
68 | extern int mx31_clocks_init_dt(void); | 69 | int mx31_clocks_init_dt(void); |
69 | extern struct platform_device *mxc_register_gpio(char *name, int id, | 70 | struct platform_device *mxc_register_gpio(char *name, int id, |
70 | 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); |
71 | extern void mxc_set_cpu_type(unsigned int type); | 72 | void mxc_set_cpu_type(unsigned int type); |
72 | extern void mxc_restart(enum reboot_mode, const char *); | 73 | void mxc_restart(enum reboot_mode, const char *); |
73 | extern void mxc_arch_reset_init(void __iomem *); | 74 | void mxc_arch_reset_init(void __iomem *); |
74 | extern void mxc_arch_reset_init_dt(void); | 75 | void mxc_arch_reset_init_dt(void); |
75 | extern int mx53_revision(void); | 76 | int mx53_revision(void); |
76 | extern int imx6q_revision(void); | 77 | void imx_set_aips(void __iomem *); |
77 | extern int mx53_display_revision(void); | 78 | int mxc_device_init(void); |
78 | extern void imx_set_aips(void __iomem *); | 79 | void imx_set_soc_revision(unsigned int rev); |
79 | 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); | ||
80 | 83 | ||
81 | enum mxc_cpu_pwr_mode { | 84 | enum mxc_cpu_pwr_mode { |
82 | WAIT_CLOCKED, /* wfi only */ | 85 | WAIT_CLOCKED, /* wfi only */ |
@@ -93,8 +96,8 @@ enum mx3_cpu_pwr_mode { | |||
93 | MX3_SLEEP, | 96 | MX3_SLEEP, |
94 | }; | 97 | }; |
95 | 98 | ||
96 | extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); | 99 | void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); |
97 | extern void imx_print_silicon_rev(const char *cpu, int srev); | 100 | void imx_print_silicon_rev(const char *cpu, int srev); |
98 | 101 | ||
99 | void avic_handle_irq(struct pt_regs *); | 102 | void avic_handle_irq(struct pt_regs *); |
100 | void tzic_handle_irq(struct pt_regs *); | 103 | void tzic_handle_irq(struct pt_regs *); |
@@ -108,54 +111,61 @@ void tzic_handle_irq(struct pt_regs *); | |||
108 | #define imx51_handle_irq tzic_handle_irq | 111 | #define imx51_handle_irq tzic_handle_irq |
109 | #define imx53_handle_irq tzic_handle_irq | 112 | #define imx53_handle_irq tzic_handle_irq |
110 | 113 | ||
111 | extern void imx_enable_cpu(int cpu, bool enable); | 114 | void imx_enable_cpu(int cpu, bool enable); |
112 | extern void imx_set_cpu_jump(int cpu, void *jump_addr); | 115 | void imx_set_cpu_jump(int cpu, void *jump_addr); |
113 | extern u32 imx_get_cpu_arg(int cpu); | 116 | u32 imx_get_cpu_arg(int cpu); |
114 | extern void imx_set_cpu_arg(int cpu, u32 arg); | 117 | void imx_set_cpu_arg(int cpu, u32 arg); |
115 | extern void v7_cpu_resume(void); | 118 | void v7_cpu_resume(void); |
116 | #ifdef CONFIG_SMP | 119 | #ifdef CONFIG_SMP |
117 | extern void v7_secondary_startup(void); | 120 | void v7_secondary_startup(void); |
118 | extern void imx_scu_map_io(void); | 121 | void imx_scu_map_io(void); |
119 | extern void imx_smp_prepare(void); | 122 | void imx_smp_prepare(void); |
120 | extern void imx_scu_standby_enable(void); | 123 | void imx_scu_standby_enable(void); |
121 | #else | 124 | #else |
122 | static inline void imx_scu_map_io(void) {} | 125 | static inline void imx_scu_map_io(void) {} |
123 | static inline void imx_smp_prepare(void) {} | 126 | static inline void imx_smp_prepare(void) {} |
124 | static inline void imx_scu_standby_enable(void) {} | 127 | static inline void imx_scu_standby_enable(void) {} |
125 | #endif | 128 | #endif |
126 | extern void imx_src_init(void); | 129 | void imx_src_init(void); |
127 | extern void imx_src_prepare_restart(void); | 130 | #ifdef CONFIG_HAVE_IMX_SRC |
128 | extern void imx_gpc_init(void); | 131 | void imx_src_prepare_restart(void); |
129 | extern void imx_gpc_pre_suspend(void); | 132 | #else |
130 | extern void imx_gpc_post_resume(void); | 133 | static inline void imx_src_prepare_restart(void) {} |
131 | extern void imx_gpc_mask_all(void); | 134 | #endif |
132 | extern void imx_gpc_restore_all(void); | 135 | void imx_gpc_init(void); |
133 | extern void imx_anatop_init(void); | 136 | void imx_gpc_pre_suspend(void); |
134 | extern void imx_anatop_pre_suspend(void); | 137 | void imx_gpc_post_resume(void); |
135 | extern void imx_anatop_post_resume(void); | 138 | void imx_gpc_mask_all(void); |
136 | extern u32 imx_anatop_get_digprog(void); | 139 | void imx_gpc_restore_all(void); |
137 | extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); | 140 | void imx_gpc_irq_mask(struct irq_data *d); |
138 | extern void imx6q_set_chicken_bit(void); | 141 | void imx_gpc_irq_unmask(struct irq_data *d); |
139 | 142 | void imx_anatop_init(void); | |
140 | extern void imx_cpu_die(unsigned int cpu); | 143 | void imx_anatop_pre_suspend(void); |
141 | extern int imx_cpu_kill(unsigned int cpu); | 144 | void imx_anatop_post_resume(void); |
145 | int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); | ||
146 | void imx6q_set_chicken_bit(void); | ||
147 | |||
148 | void imx_cpu_die(unsigned int cpu); | ||
149 | int imx_cpu_kill(unsigned int cpu); | ||
142 | 150 | ||
143 | #ifdef CONFIG_PM | 151 | #ifdef CONFIG_PM |
144 | extern void imx6q_pm_init(void); | 152 | void imx6q_pm_init(void); |
145 | extern void imx5_pm_init(void); | 153 | void imx6q_pm_set_ccm_base(void __iomem *base); |
154 | void imx5_pm_init(void); | ||
146 | #else | 155 | #else |
147 | static inline void imx6q_pm_init(void) {} | 156 | static inline void imx6q_pm_init(void) {} |
157 | static inline void imx6q_pm_set_ccm_base(void __iomem *base) {} | ||
148 | static inline void imx5_pm_init(void) {} | 158 | static inline void imx5_pm_init(void) {} |
149 | #endif | 159 | #endif |
150 | 160 | ||
151 | #ifdef CONFIG_NEON | 161 | #ifdef CONFIG_NEON |
152 | extern int mx51_neon_fixup(void); | 162 | int mx51_neon_fixup(void); |
153 | #else | 163 | #else |
154 | static inline int mx51_neon_fixup(void) { return 0; } | 164 | static inline int mx51_neon_fixup(void) { return 0; } |
155 | #endif | 165 | #endif |
156 | 166 | ||
157 | #ifdef CONFIG_CACHE_L2X0 | 167 | #ifdef CONFIG_CACHE_L2X0 |
158 | extern void imx_init_l2cache(void); | 168 | void imx_init_l2cache(void); |
159 | #else | 169 | #else |
160 | static inline void imx_init_l2cache(void) {} | 170 | static inline void imx_init_l2cache(void) {} |
161 | #endif | 171 | #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/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-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 3be0fa0e9796..0f9f24116daa 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
14 | #include <linux/clkdev.h> | 14 | #include <linux/clkdev.h> |
15 | #include <linux/cpu.h> | 15 | #include <linux/cpu.h> |
16 | #include <linux/delay.h> | ||
17 | #include <linux/export.h> | 16 | #include <linux/export.h> |
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
19 | #include <linux/io.h> | 18 | #include <linux/io.h> |
@@ -38,64 +37,6 @@ | |||
38 | #include "cpuidle.h" | 37 | #include "cpuidle.h" |
39 | #include "hardware.h" | 38 | #include "hardware.h" |
40 | 39 | ||
41 | static u32 chip_revision; | ||
42 | |||
43 | int imx6q_revision(void) | ||
44 | { | ||
45 | return chip_revision; | ||
46 | } | ||
47 | |||
48 | static void __init imx6q_init_revision(void) | ||
49 | { | ||
50 | u32 rev = imx_anatop_get_digprog(); | ||
51 | |||
52 | switch (rev & 0xff) { | ||
53 | case 0: | ||
54 | chip_revision = IMX_CHIP_REVISION_1_0; | ||
55 | break; | ||
56 | case 1: | ||
57 | chip_revision = IMX_CHIP_REVISION_1_1; | ||
58 | break; | ||
59 | case 2: | ||
60 | chip_revision = IMX_CHIP_REVISION_1_2; | ||
61 | break; | ||
62 | default: | ||
63 | chip_revision = IMX_CHIP_REVISION_UNKNOWN; | ||
64 | } | ||
65 | |||
66 | mxc_set_cpu_type(rev >> 16 & 0xff); | ||
67 | } | ||
68 | |||
69 | static void imx6q_restart(enum reboot_mode mode, const char *cmd) | ||
70 | { | ||
71 | struct device_node *np; | ||
72 | void __iomem *wdog_base; | ||
73 | |||
74 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-wdt"); | ||
75 | wdog_base = of_iomap(np, 0); | ||
76 | if (!wdog_base) | ||
77 | goto soft; | ||
78 | |||
79 | imx_src_prepare_restart(); | ||
80 | |||
81 | /* enable wdog */ | ||
82 | writew_relaxed(1 << 2, wdog_base); | ||
83 | /* write twice to ensure the request will not get ignored */ | ||
84 | writew_relaxed(1 << 2, wdog_base); | ||
85 | |||
86 | /* wait for reset to assert ... */ | ||
87 | mdelay(500); | ||
88 | |||
89 | pr_err("Watchdog reset failed to assert reset\n"); | ||
90 | |||
91 | /* delay to allow the serial port to show the message */ | ||
92 | mdelay(50); | ||
93 | |||
94 | soft: | ||
95 | /* we'll take a jump through zero as a poor second */ | ||
96 | soft_restart(0); | ||
97 | } | ||
98 | |||
99 | /* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */ | 40 | /* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */ |
100 | static int ksz9021rn_phy_fixup(struct phy_device *phydev) | 41 | static int ksz9021rn_phy_fixup(struct phy_device *phydev) |
101 | { | 42 | { |
@@ -190,12 +131,20 @@ static void __init imx6q_1588_init(void) | |||
190 | 131 | ||
191 | static void __init imx6q_init_machine(void) | 132 | static void __init imx6q_init_machine(void) |
192 | { | 133 | { |
134 | struct device *parent; | ||
135 | |||
193 | imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", | 136 | imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", |
194 | imx6q_revision()); | 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"); | ||
195 | 144 | ||
196 | imx6q_enet_phy_init(); | 145 | imx6q_enet_phy_init(); |
197 | 146 | ||
198 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 147 | of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); |
199 | 148 | ||
200 | imx_anatop_init(); | 149 | imx_anatop_init(); |
201 | imx6q_pm_init(); | 150 | imx6q_pm_init(); |
@@ -270,7 +219,7 @@ static void __init imx6q_init_late(void) | |||
270 | * 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 |
271 | * to run cpuidle on them. | 220 | * to run cpuidle on them. |
272 | */ | 221 | */ |
273 | if (imx6q_revision() > IMX_CHIP_REVISION_1_1) | 222 | if (imx_get_soc_revision() > IMX_CHIP_REVISION_1_1) |
274 | imx6q_cpuidle_init(); | 223 | imx6q_cpuidle_init(); |
275 | 224 | ||
276 | if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) { | 225 | if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) { |
@@ -287,7 +236,7 @@ static void __init imx6q_map_io(void) | |||
287 | 236 | ||
288 | static void __init imx6q_init_irq(void) | 237 | static void __init imx6q_init_irq(void) |
289 | { | 238 | { |
290 | imx6q_init_revision(); | 239 | imx_init_revision_from_anatop(); |
291 | imx_init_l2cache(); | 240 | imx_init_l2cache(); |
292 | imx_src_init(); | 241 | imx_src_init(); |
293 | imx_gpc_init(); | 242 | imx_gpc_init(); |
@@ -307,5 +256,5 @@ DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)") | |||
307 | .init_machine = imx6q_init_machine, | 256 | .init_machine = imx6q_init_machine, |
308 | .init_late = imx6q_init_late, | 257 | .init_late = imx6q_init_late, |
309 | .dt_compat = imx6q_dt_compat, | 258 | .dt_compat = imx6q_dt_compat, |
310 | .restart = imx6q_restart, | 259 | .restart = mxc_restart, |
311 | MACHINE_END | 260 | MACHINE_END |
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c index c70bd7c64974..2f952e3fcf89 100644 --- a/arch/arm/mach-imx/mach-imx6sl.c +++ b/arch/arm/mach-imx/mach-imx6sl.c | |||
@@ -10,20 +10,51 @@ | |||
10 | #include <linux/irqchip.h> | 10 | #include <linux/irqchip.h> |
11 | #include <linux/of.h> | 11 | #include <linux/of.h> |
12 | #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> | ||
13 | #include <asm/mach/arch.h> | 16 | #include <asm/mach/arch.h> |
14 | #include <asm/mach/map.h> | 17 | #include <asm/mach/map.h> |
15 | 18 | ||
16 | #include "common.h" | 19 | #include "common.h" |
17 | 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 | |||
18 | static void __init imx6sl_init_machine(void) | 37 | static void __init imx6sl_init_machine(void) |
19 | { | 38 | { |
39 | struct device *parent; | ||
40 | |||
20 | mxc_arch_reset_init_dt(); | 41 | mxc_arch_reset_init_dt(); |
21 | 42 | ||
22 | 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(); | ||
23 | } | 53 | } |
24 | 54 | ||
25 | static void __init imx6sl_init_irq(void) | 55 | static void __init imx6sl_init_irq(void) |
26 | { | 56 | { |
57 | imx_init_revision_from_anatop(); | ||
27 | imx_init_l2cache(); | 58 | imx_init_l2cache(); |
28 | imx_src_init(); | 59 | imx_src_init(); |
29 | imx_gpc_init(); | 60 | imx_gpc_init(); |
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-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c index bc0261e99d39..45303bd62902 100644 --- a/arch/arm/mach-imx/mach-pcm037.c +++ b/arch/arm/mach-imx/mach-pcm037.c | |||
@@ -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/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..4754373e7e7d 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 | } |
diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c index 80c177c36c5f..e6edcd38b282 100644 --- a/arch/arm/mach-imx/system.c +++ b/arch/arm/mach-imx/system.c | |||
@@ -42,6 +42,9 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) | |||
42 | { | 42 | { |
43 | unsigned int wcr_enable; | 43 | unsigned int wcr_enable; |
44 | 44 | ||
45 | if (cpu_is_imx6q() || cpu_is_imx6dl()) | ||
46 | imx_src_prepare_restart(); | ||
47 | |||
45 | if (wdog_clk) | 48 | if (wdog_clk) |
46 | clk_enable(wdog_clk); | 49 | clk_enable(wdog_clk); |
47 | 50 | ||
@@ -52,6 +55,8 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) | |||
52 | 55 | ||
53 | /* Assert SRS signal */ | 56 | /* Assert SRS signal */ |
54 | __raw_writew(wcr_enable, wdog_base); | 57 | __raw_writew(wcr_enable, wdog_base); |
58 | /* write twice to ensure the request will not get ignored */ | ||
59 | __raw_writew(wcr_enable, wdog_base); | ||
55 | 60 | ||
56 | /* wait for reset to assert... */ | 61 | /* wait for reset to assert... */ |
57 | mdelay(500); | 62 | 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 | ||
diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h index b6bdcd66c07d..7086b2248c8f 100644 --- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h +++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h | |||
@@ -363,4 +363,9 @@ | |||
363 | #define IMX6Q_GPR13_SATA_TX_LVL_1_240_V (0x1f << 2) | 363 | #define IMX6Q_GPR13_SATA_TX_LVL_1_240_V (0x1f << 2) |
364 | #define IMX6Q_GPR13_SATA_MPLL_CLK_EN BIT(1) | 364 | #define IMX6Q_GPR13_SATA_MPLL_CLK_EN BIT(1) |
365 | #define IMX6Q_GPR13_SATA_TX_EDGE_RATE BIT(0) | 365 | #define IMX6Q_GPR13_SATA_TX_EDGE_RATE BIT(0) |
366 | |||
367 | /* For imx6sl iomux gpr register field define */ | ||
368 | #define IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK (0x3 << 17) | ||
369 | #define IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK (0x1 << 14) | ||
370 | |||
366 | #endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */ | 371 | #endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */ |