diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-09 17:38:28 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-09 17:38:28 -0500 |
commit | 6cd94d5e57ab97ddd672b707ab4bb639672c1727 (patch) | |
tree | b1b301b16433d4deab6bd52e81d04a7b58c239d3 | |
parent | 6c9e92476bc924ede6d6d2f0bfed2c06ae148d29 (diff) | |
parent | 842f7d2c4d392c0571cf72e3eaca26742bebbd1e (diff) |
Merge tag 'soc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform changes from Arnd Bergmann:
"New and updated SoC support, notable changes include:
- bcm:
brcmstb SMP support
initial iproc/cygnus support
- exynos:
Exynos4415 SoC support
PMU and suspend support for Exynos5420
PMU support for Exynos3250
pm related maintenance
- imx:
new LS1021A SoC support
vybrid 610 global timer support
- integrator:
convert to using multiplatform configuration
- mediatek:
earlyprintk support for mt8127/mt8135
- meson:
meson8 soc and l2 cache controller support
- mvebu:
Armada 38x CPU hotplug support
drop support for prerelease Armada 375 Z1 stepping
extended suspend support, now works on Armada 370/XP
- omap:
hwmod related maintenance
prcm cleanup
- pxa:
initial pxa27x DT handling
- rockchip:
SMP support for rk3288
add cpu frequency scaling support
- shmobile:
r8a7740 power domain support
various small restart, timer, pci apmu changes
- sunxi:
Allwinner A80 (sun9i) earlyprintk support
- ux500:
power domain support
Overall, a significant chunk of changes, coming mostly from the usual
suspects: omap, shmobile, samsung and mvebu, all of which already
contain a lot of platform specific code in arch/arm"
* tag 'soc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (187 commits)
ARM: mvebu: use the cpufreq-dt platform_data for independent clocks
soc: integrator: Add terminating entry for integrator_cm_match
ARM: mvebu: add SDRAM controller description for Armada XP
ARM: mvebu: adjust mbus controller description on Armada 370/XP
ARM: mvebu: add suspend/resume DT information for Armada XP GP
ARM: mvebu: synchronize secondary CPU clocks on resume
ARM: mvebu: make sure MMU is disabled in armada_370_xp_cpu_resume
ARM: mvebu: Armada XP GP specific suspend/resume code
ARM: mvebu: reserve the first 10 KB of each memory bank for suspend/resume
ARM: mvebu: implement suspend/resume support for Armada XP
clk: mvebu: add suspend/resume for gatable clocks
bus: mvebu-mbus: provide a mechanism to save SDRAM window configuration
bus: mvebu-mbus: suspend/resume support
clocksource: time-armada-370-xp: add suspend/resume support
irqchip: armada-370-xp: Add suspend/resume support
ARM: add lolevel debug support for asm9260
ARM: add mach-asm9260
ARM: EXYNOS: use u8 for val[] in struct exynos_pmu_conf
power: reset: imx-snvs-poweroff: add power off driver for i.mx6
ARM: imx: temporarily remove CONFIG_SOC_FSL from LS1021A
...
214 files changed, 6329 insertions, 2353 deletions
diff --git a/Documentation/arm/firmware.txt b/Documentation/arm/firmware.txt index c2e468fe7b0b..da6713adac8a 100644 --- a/Documentation/arm/firmware.txt +++ b/Documentation/arm/firmware.txt | |||
@@ -7,32 +7,14 @@ world, which changes the way some things have to be initialized. This makes | |||
7 | a need to provide an interface for such platforms to specify available firmware | 7 | a need to provide an interface for such platforms to specify available firmware |
8 | operations and call them when needed. | 8 | operations and call them when needed. |
9 | 9 | ||
10 | Firmware operations can be specified using struct firmware_ops | 10 | Firmware operations can be specified by filling in a struct firmware_ops |
11 | 11 | with appropriate callbacks and then registering it with register_firmware_ops() | |
12 | struct firmware_ops { | 12 | function. |
13 | /* | ||
14 | * Enters CPU idle mode | ||
15 | */ | ||
16 | int (*do_idle)(void); | ||
17 | /* | ||
18 | * Sets boot address of specified physical CPU | ||
19 | */ | ||
20 | int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr); | ||
21 | /* | ||
22 | * Boots specified physical CPU | ||
23 | */ | ||
24 | int (*cpu_boot)(int cpu); | ||
25 | /* | ||
26 | * Initializes L2 cache | ||
27 | */ | ||
28 | int (*l2x0_init)(void); | ||
29 | }; | ||
30 | |||
31 | and then registered with register_firmware_ops function | ||
32 | 13 | ||
33 | void register_firmware_ops(const struct firmware_ops *ops) | 14 | void register_firmware_ops(const struct firmware_ops *ops) |
34 | 15 | ||
35 | the ops pointer must be non-NULL. | 16 | The ops pointer must be non-NULL. More information about struct firmware_ops |
17 | and its members can be found in arch/arm/include/asm/firmware.h header. | ||
36 | 18 | ||
37 | There is a default, empty set of operations provided, so there is no need to | 19 | There is a default, empty set of operations provided, so there is no need to |
38 | set anything if platform does not require firmware operations. | 20 | set anything if platform does not require firmware operations. |
diff --git a/Documentation/arm/sunxi/README b/Documentation/arm/sunxi/README index 7945238453ed..e68d163df33d 100644 --- a/Documentation/arm/sunxi/README +++ b/Documentation/arm/sunxi/README | |||
@@ -37,16 +37,26 @@ SunXi family | |||
37 | http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf | 37 | http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf |
38 | 38 | ||
39 | - Allwinner A23 | 39 | - Allwinner A23 |
40 | + Not Supported | 40 | + Datasheet |
41 | http://dl.linux-sunxi.org/A23/A23%20Datasheet%20V1.0%2020130830.pdf | ||
42 | + User Manual | ||
43 | http://dl.linux-sunxi.org/A23/A23%20User%20Manual%20V1.0%2020130830.pdf | ||
41 | 44 | ||
42 | * Quad ARM Cortex-A7 based SoCs | 45 | * Quad ARM Cortex-A7 based SoCs |
43 | - Allwinner A31 (sun6i) | 46 | - Allwinner A31 (sun6i) |
44 | + Datasheet | 47 | + Datasheet |
45 | http://dl.linux-sunxi.org/A31/A31%20Datasheet%20-%20v1.00%20(2012-12-24).pdf | 48 | http://dl.linux-sunxi.org/A31/A3x_release_document/A31/IC/A31%20datasheet%20V1.3%2020131106.pdf |
49 | + User Manual | ||
50 | http://dl.linux-sunxi.org/A31/A3x_release_document/A31/IC/A31%20user%20manual%20V1.1%2020130630.pdf | ||
46 | 51 | ||
47 | - Allwinner A31s (sun6i) | 52 | - Allwinner A31s (sun6i) |
48 | + Not Supported | 53 | + Not Supported |
54 | + Datasheet | ||
55 | http://dl.linux-sunxi.org/A31/A3x_release_document/A31s/IC/A31s%20datasheet%20V1.3%2020131106.pdf | ||
56 | + User Manual | ||
57 | http://dl.linux-sunxi.org/A31/A3x_release_document/A31s/IC/A31s%20User%20Manual%20%20V1.0%2020130322.pdf | ||
49 | 58 | ||
50 | * Quad ARM Cortex-A15, Quad ARM Cortex-A7 based SoCs | 59 | * Quad ARM Cortex-A15, Quad ARM Cortex-A7 based SoCs |
51 | - Allwinner A80 | 60 | - Allwinner A80 |
52 | + Not Supported \ No newline at end of file | 61 | + Datasheet |
62 | http://dl.linux-sunxi.org/A80/A80_Datasheet_Revision_1.0_0404.pdf | ||
diff --git a/Documentation/devicetree/bindings/arm/amlogic.txt b/Documentation/devicetree/bindings/arm/amlogic.txt index 7eece72b1a35..8fe815046140 100644 --- a/Documentation/devicetree/bindings/arm/amlogic.txt +++ b/Documentation/devicetree/bindings/arm/amlogic.txt | |||
@@ -2,7 +2,9 @@ Amlogic MesonX device tree bindings | |||
2 | ------------------------------------------- | 2 | ------------------------------------------- |
3 | 3 | ||
4 | Boards with the Amlogic Meson6 SoC shall have the following properties: | 4 | Boards with the Amlogic Meson6 SoC shall have the following properties: |
5 | Required root node property: | ||
6 | compatible: "amlogic,meson6" | ||
5 | 7 | ||
6 | Required root node property: | 8 | Boards with the Amlogic Meson8 SoC shall have the following properties: |
7 | 9 | Required root node property: | |
8 | compatible = "amlogic,meson6"; | 10 | compatible: "amlogic,meson8"; |
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index fc446347ab6d..b2aacbe16ed9 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt | |||
@@ -227,6 +227,15 @@ nodes to be present and contain the properties described below. | |||
227 | # List of phandles to idle state nodes supported | 227 | # List of phandles to idle state nodes supported |
228 | by this cpu [3]. | 228 | by this cpu [3]. |
229 | 229 | ||
230 | - rockchip,pmu | ||
231 | Usage: optional for systems that have an "enable-method" | ||
232 | property value of "rockchip,rk3066-smp" | ||
233 | While optional, it is the preferred way to get access to | ||
234 | the cpu-core power-domains. | ||
235 | Value type: <phandle> | ||
236 | Definition: Specifies the syscon node controlling the cpu core | ||
237 | power domains. | ||
238 | |||
230 | Example 1 (dual-cluster big.LITTLE system 32-bit): | 239 | Example 1 (dual-cluster big.LITTLE system 32-bit): |
231 | 240 | ||
232 | cpus { | 241 | cpus { |
diff --git a/Documentation/devicetree/bindings/arm/sunxi.txt b/Documentation/devicetree/bindings/arm/sunxi.txt new file mode 100644 index 000000000000..42941fdefb11 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/sunxi.txt | |||
@@ -0,0 +1,12 @@ | |||
1 | Allwinner sunXi Platforms Device Tree Bindings | ||
2 | |||
3 | Each device tree must specify which Allwinner SoC it uses, | ||
4 | using one of the following compatible strings: | ||
5 | |||
6 | allwinner,sun4i-a10 | ||
7 | allwinner,sun5i-a10s | ||
8 | allwinner,sun5i-a13 | ||
9 | allwinner,sun6i-a31 | ||
10 | allwinner,sun7i-a20 | ||
11 | allwinner,sun8i-a23 | ||
12 | allwinner,sun9i-a80 | ||
diff --git a/Documentation/devicetree/bindings/arm/ux500/power_domain.txt b/Documentation/devicetree/bindings/arm/ux500/power_domain.txt new file mode 100644 index 000000000000..5679d1742d3e --- /dev/null +++ b/Documentation/devicetree/bindings/arm/ux500/power_domain.txt | |||
@@ -0,0 +1,35 @@ | |||
1 | * ST-Ericsson UX500 PM Domains | ||
2 | |||
3 | UX500 supports multiple PM domains which are used to gate power to one or | ||
4 | more peripherals on the SOC. | ||
5 | |||
6 | The implementation of PM domains for UX500 are based upon the generic PM domain | ||
7 | and use the corresponding DT bindings. | ||
8 | |||
9 | ==PM domain providers== | ||
10 | |||
11 | Required properties: | ||
12 | - compatible: Must be "stericsson,ux500-pm-domains". | ||
13 | - #power-domain-cells : Number of cells in a power domain specifier, must be 1. | ||
14 | |||
15 | Example: | ||
16 | pm_domains: pm_domains0 { | ||
17 | compatible = "stericsson,ux500-pm-domains"; | ||
18 | #power-domain-cells = <1>; | ||
19 | }; | ||
20 | |||
21 | ==PM domain consumers== | ||
22 | |||
23 | Required properties: | ||
24 | - power-domains: A phandle and PM domain specifier. Below are the list of | ||
25 | valid specifiers: | ||
26 | |||
27 | Index Specifier | ||
28 | ----- --------- | ||
29 | 0 DOMAIN_VAPE | ||
30 | |||
31 | Example: | ||
32 | sdi0_per1@80126000 { | ||
33 | compatible = "arm,pl18x", "arm,primecell"; | ||
34 | power-domains = <&pm_domains DOMAIN_VAPE> | ||
35 | }; | ||
diff --git a/Documentation/devicetree/bindings/bus/mvebu-mbus.txt b/Documentation/devicetree/bindings/bus/mvebu-mbus.txt index 5fa44f52a0b8..5e16c3ccb061 100644 --- a/Documentation/devicetree/bindings/bus/mvebu-mbus.txt +++ b/Documentation/devicetree/bindings/bus/mvebu-mbus.txt | |||
@@ -48,9 +48,12 @@ Required properties: | |||
48 | - compatible: Should be set to "marvell,mbus-controller". | 48 | - compatible: Should be set to "marvell,mbus-controller". |
49 | 49 | ||
50 | - reg: Device's register space. | 50 | - reg: Device's register space. |
51 | Two entries are expected (see the examples below): | 51 | Two or three entries are expected (see the examples below): |
52 | the first one controls the devices decoding window and | 52 | the first one controls the devices decoding window, |
53 | the second one controls the SDRAM decoding window. | 53 | the second one controls the SDRAM decoding window and |
54 | the third controls the MBus bridge (only with the | ||
55 | marvell,armada370-mbus and marvell,armadaxp-mbus | ||
56 | compatible strings) | ||
54 | 57 | ||
55 | Example: | 58 | Example: |
56 | 59 | ||
@@ -67,7 +70,7 @@ Example: | |||
67 | 70 | ||
68 | mbusc: mbus-controller@20000 { | 71 | mbusc: mbus-controller@20000 { |
69 | compatible = "marvell,mbus-controller"; | 72 | compatible = "marvell,mbus-controller"; |
70 | reg = <0x20000 0x100>, <0x20180 0x20>; | 73 | reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>; |
71 | }; | 74 | }; |
72 | 75 | ||
73 | /* more children ...*/ | 76 | /* more children ...*/ |
@@ -126,7 +129,7 @@ are skipped. | |||
126 | 129 | ||
127 | mbusc: mbus-controller@20000 { | 130 | mbusc: mbus-controller@20000 { |
128 | compatible = "marvell,mbus-controller"; | 131 | compatible = "marvell,mbus-controller"; |
129 | reg = <0x20000 0x100>, <0x20180 0x20>; | 132 | reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>; |
130 | }; | 133 | }; |
131 | 134 | ||
132 | /* more children ...*/ | 135 | /* more children ...*/ |
@@ -170,7 +173,7 @@ Using this macro, the above example would be: | |||
170 | 173 | ||
171 | mbusc: mbus-controller@20000 { | 174 | mbusc: mbus-controller@20000 { |
172 | compatible = "marvell,mbus-controller"; | 175 | compatible = "marvell,mbus-controller"; |
173 | reg = <0x20000 0x100>, <0x20180 0x20>; | 176 | reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>; |
174 | }; | 177 | }; |
175 | 178 | ||
176 | /* other children */ | 179 | /* other children */ |
@@ -266,7 +269,7 @@ See the example below, where a more complete device tree is shown: | |||
266 | ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>; | 269 | ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>; |
267 | 270 | ||
268 | mbusc: mbus-controller@20000 { | 271 | mbusc: mbus-controller@20000 { |
269 | reg = <0x20000 0x100>, <0x20180 0x20>; | 272 | reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>; |
270 | }; | 273 | }; |
271 | 274 | ||
272 | interrupt-controller@20000 { | 275 | interrupt-controller@20000 { |
diff --git a/Documentation/devicetree/bindings/memory-controllers/mvebu-sdram-controller.txt b/Documentation/devicetree/bindings/memory-controllers/mvebu-sdram-controller.txt new file mode 100644 index 000000000000..89657d1d4cd4 --- /dev/null +++ b/Documentation/devicetree/bindings/memory-controllers/mvebu-sdram-controller.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | Device Tree bindings for MVEBU SDRAM controllers | ||
2 | |||
3 | The Marvell EBU SoCs all have a SDRAM controller. The SDRAM controller | ||
4 | differs from one SoC variant to another, but they also share a number | ||
5 | of commonalities. | ||
6 | |||
7 | For now, this Device Tree binding documentation only documents the | ||
8 | Armada XP SDRAM controller. | ||
9 | |||
10 | Required properties: | ||
11 | |||
12 | - compatible: for Armada XP, "marvell,armada-xp-sdram-controller" | ||
13 | - reg: a resource specifier for the register space, which should | ||
14 | include all SDRAM controller registers as per the datasheet. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | sdramc@1400 { | ||
19 | compatible = "marvell,armada-xp-sdram-controller"; | ||
20 | reg = <0x1400 0x500>; | ||
21 | }; | ||
diff --git a/Documentation/devicetree/bindings/power_supply/imx-snvs-poweroff.txt b/Documentation/devicetree/bindings/power_supply/imx-snvs-poweroff.txt new file mode 100644 index 000000000000..dc7c9bad63ea --- /dev/null +++ b/Documentation/devicetree/bindings/power_supply/imx-snvs-poweroff.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | i.mx6 Poweroff Driver | ||
2 | |||
3 | SNVS_LPCR in SNVS module can power off the whole system by pull | ||
4 | PMIC_ON_REQ low if PMIC_ON_REQ is connected with external PMIC. | ||
5 | If you don't want to use PMIC_ON_REQ as power on/off control, | ||
6 | please set status='disabled' to disable this driver. | ||
7 | |||
8 | Required Properties: | ||
9 | -compatible: "fsl,sec-v4.0-poweroff" | ||
10 | -reg: Specifies the physical address of the SNVS_LPCR register | ||
11 | |||
12 | Example: | ||
13 | snvs@020cc000 { | ||
14 | compatible = "fsl,sec-v4.0-mon", "simple-bus"; | ||
15 | #address-cells = <1>; | ||
16 | #size-cells = <1>; | ||
17 | ranges = <0 0x020cc000 0x4000>; | ||
18 | ..... | ||
19 | snvs_poweroff: snvs-poweroff@38 { | ||
20 | compatible = "fsl,sec-v4.0-poweroff"; | ||
21 | reg = <0x38 0x4>; | ||
22 | }; | ||
23 | } | ||
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index a344ec2713a5..ecaf2035c2fe 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
@@ -91,6 +91,7 @@ lltc Linear Technology Corporation | |||
91 | marvell Marvell Technology Group Ltd. | 91 | marvell Marvell Technology Group Ltd. |
92 | maxim Maxim Integrated Products | 92 | maxim Maxim Integrated Products |
93 | mediatek MediaTek Inc. | 93 | mediatek MediaTek Inc. |
94 | merrii Merrii Technology Co., Ltd. | ||
94 | micrel Micrel Inc. | 95 | micrel Micrel Inc. |
95 | microchip Microchip Technology Inc. | 96 | microchip Microchip Technology Inc. |
96 | micron Micron Technology Inc. | 97 | micron Micron Technology Inc. |
diff --git a/MAINTAINERS b/MAINTAINERS index 79ccbdf57723..e3a96e42193c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1379,6 +1379,7 @@ F: arch/arm/configs/lager_defconfig | |||
1379 | F: arch/arm/configs/mackerel_defconfig | 1379 | F: arch/arm/configs/mackerel_defconfig |
1380 | F: arch/arm/configs/marzen_defconfig | 1380 | F: arch/arm/configs/marzen_defconfig |
1381 | F: arch/arm/configs/shmobile_defconfig | 1381 | F: arch/arm/configs/shmobile_defconfig |
1382 | F: arch/arm/include/debug/renesas-scif.S | ||
1382 | F: arch/arm/mach-shmobile/ | 1383 | F: arch/arm/mach-shmobile/ |
1383 | F: drivers/sh/ | 1384 | F: drivers/sh/ |
1384 | 1385 | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fd4515ca8358..8db9dc07f8ac 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -320,24 +320,6 @@ config ARCH_MULTIPLATFORM | |||
320 | select SPARSE_IRQ | 320 | select SPARSE_IRQ |
321 | select USE_OF | 321 | select USE_OF |
322 | 322 | ||
323 | config ARCH_INTEGRATOR | ||
324 | bool "ARM Ltd. Integrator family" | ||
325 | select ARM_AMBA | ||
326 | select ARM_PATCH_PHYS_VIRT if MMU | ||
327 | select AUTO_ZRELADDR | ||
328 | select COMMON_CLK | ||
329 | select COMMON_CLK_VERSATILE | ||
330 | select GENERIC_CLOCKEVENTS | ||
331 | select HAVE_TCM | ||
332 | select ICST | ||
333 | select MULTI_IRQ_HANDLER | ||
334 | select PLAT_VERSATILE | ||
335 | select SPARSE_IRQ | ||
336 | select USE_OF | ||
337 | select VERSATILE_FPGA_IRQ | ||
338 | help | ||
339 | Support for ARM's Integrator platform. | ||
340 | |||
341 | config ARCH_REALVIEW | 323 | config ARCH_REALVIEW |
342 | bool "ARM Ltd. RealView family" | 324 | bool "ARM Ltd. RealView family" |
343 | select ARCH_WANT_OPTIONAL_GPIOLIB | 325 | select ARCH_WANT_OPTIONAL_GPIOLIB |
@@ -857,6 +839,8 @@ config ARCH_VIRT | |||
857 | # | 839 | # |
858 | source "arch/arm/mach-mvebu/Kconfig" | 840 | source "arch/arm/mach-mvebu/Kconfig" |
859 | 841 | ||
842 | source "arch/arm/mach-asm9260/Kconfig" | ||
843 | |||
860 | source "arch/arm/mach-at91/Kconfig" | 844 | source "arch/arm/mach-at91/Kconfig" |
861 | 845 | ||
862 | source "arch/arm/mach-axxia/Kconfig" | 846 | source "arch/arm/mach-axxia/Kconfig" |
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index d8f6a2ec3d4e..f9295a4e1036 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -93,6 +93,27 @@ choice | |||
93 | prompt "Kernel low-level debugging port" | 93 | prompt "Kernel low-level debugging port" |
94 | depends on DEBUG_LL | 94 | depends on DEBUG_LL |
95 | 95 | ||
96 | config DEBUG_ASM9260_UART | ||
97 | bool "Kernel low-level debugging via asm9260 UART" | ||
98 | depends on MACH_ASM9260 | ||
99 | help | ||
100 | Say Y here if you want the debug print routines to direct | ||
101 | their output to an UART or USART port on asm9260 based | ||
102 | machines. | ||
103 | |||
104 | DEBUG_UART_PHYS | DEBUG_UART_VIRT | ||
105 | |||
106 | 0x80000000 | 0xf0000000 | UART0 | ||
107 | 0x80004000 | 0xf0004000 | UART1 | ||
108 | 0x80008000 | 0xf0008000 | UART2 | ||
109 | 0x8000c000 | 0xf000c000 | UART3 | ||
110 | 0x80010000 | 0xf0010000 | UART4 | ||
111 | 0x80014000 | 0xf0014000 | UART5 | ||
112 | 0x80018000 | 0xf0018000 | UART6 | ||
113 | 0x8001c000 | 0xf001c000 | UART7 | ||
114 | 0x80020000 | 0xf0020000 | UART8 | ||
115 | 0x80024000 | 0xf0024000 | UART9 | ||
116 | |||
96 | config AT91_DEBUG_LL_DBGU0 | 117 | config AT91_DEBUG_LL_DBGU0 |
97 | bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl" | 118 | bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl" |
98 | depends on HAVE_AT91_DBGU0 | 119 | depends on HAVE_AT91_DBGU0 |
@@ -113,7 +134,7 @@ choice | |||
113 | config DEBUG_BCM_5301X | 134 | config DEBUG_BCM_5301X |
114 | bool "Kernel low-level debugging on BCM5301X UART1" | 135 | bool "Kernel low-level debugging on BCM5301X UART1" |
115 | depends on ARCH_BCM_5301X | 136 | depends on ARCH_BCM_5301X |
116 | select DEBUG_UART_PL01X | 137 | select DEBUG_UART_8250 |
117 | 138 | ||
118 | config DEBUG_BCM_KONA_UART | 139 | config DEBUG_BCM_KONA_UART |
119 | bool "Kernel low-level debugging messages via BCM KONA UART" | 140 | bool "Kernel low-level debugging messages via BCM KONA UART" |
@@ -139,6 +160,17 @@ choice | |||
139 | Say Y here if you want kernel low-level debugging support | 160 | Say Y here if you want kernel low-level debugging support |
140 | on Marvell Berlin SoC based platforms. | 161 | on Marvell Berlin SoC based platforms. |
141 | 162 | ||
163 | config DEBUG_BRCMSTB_UART | ||
164 | bool "Use BRCMSTB UART for low-level debug" | ||
165 | depends on ARCH_BRCMSTB | ||
166 | select DEBUG_UART_8250 | ||
167 | help | ||
168 | Say Y here if you want the debug print routines to direct | ||
169 | their output to the first serial port on these devices. | ||
170 | |||
171 | If you have a Broadcom STB chip and would like early print | ||
172 | messages to appear over the UART, select this option. | ||
173 | |||
142 | config DEBUG_CLPS711X_UART1 | 174 | config DEBUG_CLPS711X_UART1 |
143 | bool "Kernel low-level debugging messages via UART1" | 175 | bool "Kernel low-level debugging messages via UART1" |
144 | depends on ARCH_CLPS711X | 176 | depends on ARCH_CLPS711X |
@@ -653,6 +685,64 @@ choice | |||
653 | Say Y here if you want kernel low-level debugging support | 685 | Say Y here if you want kernel low-level debugging support |
654 | on Rockchip RK32xx based platforms. | 686 | on Rockchip RK32xx based platforms. |
655 | 687 | ||
688 | config DEBUG_R7S72100_SCIF2 | ||
689 | bool "Kernel low-level debugging messages via SCIF2 on R7S72100" | ||
690 | depends on ARCH_R7S72100 | ||
691 | help | ||
692 | Say Y here if you want kernel low-level debugging support | ||
693 | via SCIF2 on Renesas RZ/A1H (R7S72100). | ||
694 | |||
695 | config DEBUG_RCAR_GEN1_SCIF0 | ||
696 | bool "Kernel low-level debugging messages via SCIF0 on R8A7778" | ||
697 | depends on ARCH_R8A7778 | ||
698 | help | ||
699 | Say Y here if you want kernel low-level debugging support | ||
700 | via SCIF0 on Renesas R-Car M1A (R8A7778). | ||
701 | |||
702 | config DEBUG_RCAR_GEN1_SCIF2 | ||
703 | bool "Kernel low-level debugging messages via SCIF2 on R8A7779" | ||
704 | depends on ARCH_R8A7779 | ||
705 | help | ||
706 | Say Y here if you want kernel low-level debugging support | ||
707 | via SCIF2 on Renesas R-Car H1 (R8A7779). | ||
708 | |||
709 | config DEBUG_RCAR_GEN2_SCIF0 | ||
710 | bool "Kernel low-level debugging messages via SCIF0 on R8A7790/R8A7791/R8A7793)" | ||
711 | depends on ARCH_R8A7790 || ARCH_R8A7791 || ARCH_R8A7793 | ||
712 | help | ||
713 | Say Y here if you want kernel low-level debugging support | ||
714 | via SCIF0 on Renesas R-Car H2 (R8A7790), M2-W (R8A7791), or | ||
715 | M2-N (R8A7793). | ||
716 | |||
717 | config DEBUG_RCAR_GEN2_SCIF2 | ||
718 | bool "Kernel low-level debugging messages via SCIF2 on R8A7794" | ||
719 | depends on ARCH_R8A7794 | ||
720 | help | ||
721 | Say Y here if you want kernel low-level debugging support | ||
722 | via SCIF2 on Renesas R-Car E2 (R8A7794). | ||
723 | |||
724 | config DEBUG_RMOBILE_SCIFA0 | ||
725 | bool "Kernel low-level debugging messages via SCIFA0 on R8A73A4/SH7372" | ||
726 | depends on ARCH_R8A73A4 || ARCH_SH7372 | ||
727 | help | ||
728 | Say Y here if you want kernel low-level debugging support | ||
729 | via SCIFA0 on Renesas R-Mobile APE6 (R8A73A4) or SH-Mobile | ||
730 | AP4 (SH7372). | ||
731 | |||
732 | config DEBUG_RMOBILE_SCIFA1 | ||
733 | bool "Kernel low-level debugging messages via SCIFA1 on R8A7740" | ||
734 | depends on ARCH_R8A7740 | ||
735 | help | ||
736 | Say Y here if you want kernel low-level debugging support | ||
737 | via SCIFA1 on Renesas R-Mobile A1 (R8A7740). | ||
738 | |||
739 | config DEBUG_RMOBILE_SCIFA4 | ||
740 | bool "Kernel low-level debugging messages via SCIFA4 on SH73A0" | ||
741 | depends on ARCH_SH73A0 | ||
742 | help | ||
743 | Say Y here if you want kernel low-level debugging support | ||
744 | via SCIFA4 on Renesas SH-Mobile AG5 (SH73A0). | ||
745 | |||
656 | config DEBUG_S3C_UART0 | 746 | config DEBUG_S3C_UART0 |
657 | depends on PLAT_SAMSUNG | 747 | depends on PLAT_SAMSUNG |
658 | select DEBUG_EXYNOS_UART if ARCH_EXYNOS | 748 | select DEBUG_EXYNOS_UART if ARCH_EXYNOS |
@@ -723,6 +813,14 @@ choice | |||
723 | their output to UART 2. The port must have been initialised | 813 | their output to UART 2. The port must have been initialised |
724 | by the boot-loader before use. | 814 | by the boot-loader before use. |
725 | 815 | ||
816 | config DEBUG_SA1100 | ||
817 | depends on ARCH_SA1100 | ||
818 | bool "Use SA1100 UARTs for low-level debug" | ||
819 | help | ||
820 | Say Y here if you want kernel low-level debugging support | ||
821 | on SA-11x0 UART ports. The kernel will check for the first | ||
822 | enabled UART in a sequence 3-1-2. | ||
823 | |||
726 | config DEBUG_SOCFPGA_UART | 824 | config DEBUG_SOCFPGA_UART |
727 | depends on ARCH_SOCFPGA | 825 | depends on ARCH_SOCFPGA |
728 | bool "Use SOCFPGA UART for low-level debug" | 826 | bool "Use SOCFPGA UART for low-level debug" |
@@ -731,6 +829,14 @@ choice | |||
731 | Say Y here if you want kernel low-level debugging support | 829 | Say Y here if you want kernel low-level debugging support |
732 | on SOCFPGA based platforms. | 830 | on SOCFPGA based platforms. |
733 | 831 | ||
832 | config DEBUG_SUN9I_UART0 | ||
833 | bool "Kernel low-level debugging messages via sun9i UART0" | ||
834 | depends on MACH_SUN9I | ||
835 | select DEBUG_UART_8250 | ||
836 | help | ||
837 | Say Y here if you want kernel low-level debugging support | ||
838 | on Allwinner A80 based platforms on the UART0. | ||
839 | |||
734 | config DEBUG_SUNXI_UART0 | 840 | config DEBUG_SUNXI_UART0 |
735 | bool "Kernel low-level debugging messages via sunXi UART0" | 841 | bool "Kernel low-level debugging messages via sunXi UART0" |
736 | depends on ARCH_SUNXI | 842 | depends on ARCH_SUNXI |
@@ -866,6 +972,22 @@ choice | |||
866 | Say Y here if you want kernel low-level debugging support | 972 | Say Y here if you want kernel low-level debugging support |
867 | for Mediatek mt6589 based platforms on UART0. | 973 | for Mediatek mt6589 based platforms on UART0. |
868 | 974 | ||
975 | config DEBUG_MT8127_UART0 | ||
976 | bool "Mediatek mt8127 UART0" | ||
977 | depends on ARCH_MEDIATEK | ||
978 | select DEBUG_UART_8250 | ||
979 | help | ||
980 | Say Y here if you want kernel low-level debugging support | ||
981 | for Mediatek mt8127 based platforms on UART0. | ||
982 | |||
983 | config DEBUG_MT8135_UART3 | ||
984 | bool "Mediatek mt8135 UART3" | ||
985 | depends on ARCH_MEDIATEK | ||
986 | select DEBUG_UART_8250 | ||
987 | help | ||
988 | Say Y here if you want kernel low-level debugging support | ||
989 | for Mediatek mt8135 based platforms on UART3. | ||
990 | |||
869 | config DEBUG_VEXPRESS_UART0_DETECT | 991 | config DEBUG_VEXPRESS_UART0_DETECT |
870 | bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" | 992 | bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" |
871 | depends on ARCH_VEXPRESS && CPU_CP15_MMU | 993 | depends on ARCH_VEXPRESS && CPU_CP15_MMU |
@@ -1041,7 +1163,9 @@ config DEBUG_STI_UART | |||
1041 | 1163 | ||
1042 | config DEBUG_LL_INCLUDE | 1164 | config DEBUG_LL_INCLUDE |
1043 | string | 1165 | string |
1166 | default "debug/sa1100.S" if DEBUG_SA1100 | ||
1044 | default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250 | 1167 | default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250 |
1168 | default "debug/asm9260.S" if DEBUG_ASM9260_UART | ||
1045 | default "debug/clps711x.S" if DEBUG_CLPS711X_UART1 || DEBUG_CLPS711X_UART2 | 1169 | default "debug/clps711x.S" if DEBUG_CLPS711X_UART1 || DEBUG_CLPS711X_UART2 |
1046 | default "debug/meson.S" if DEBUG_MESON_UARTAO | 1170 | default "debug/meson.S" if DEBUG_MESON_UARTAO |
1047 | default "debug/pl01x.S" if DEBUG_LL_UART_PL01X || DEBUG_UART_PL01X | 1171 | default "debug/pl01x.S" if DEBUG_LL_UART_PL01X || DEBUG_UART_PL01X |
@@ -1061,6 +1185,14 @@ config DEBUG_LL_INCLUDE | |||
1061 | DEBUG_IMX6SX_UART | 1185 | DEBUG_IMX6SX_UART |
1062 | default "debug/msm.S" if DEBUG_MSM_UART || DEBUG_QCOM_UARTDM | 1186 | default "debug/msm.S" if DEBUG_MSM_UART || DEBUG_QCOM_UARTDM |
1063 | default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART | 1187 | default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART |
1188 | default "debug/renesas-scif.S" if DEBUG_R7S72100_SCIF2 | ||
1189 | default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF0 | ||
1190 | default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF2 | ||
1191 | default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF0 | ||
1192 | default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF2 | ||
1193 | default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA0 | ||
1194 | default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA1 | ||
1195 | default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA4 | ||
1064 | default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART | 1196 | default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART |
1065 | default "debug/s5pv210.S" if DEBUG_S5PV210_UART | 1197 | default "debug/s5pv210.S" if DEBUG_S5PV210_UART |
1066 | default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1 | 1198 | default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1 |
@@ -1106,6 +1238,7 @@ config DEBUG_UART_PHYS | |||
1106 | default 0x02530c00 if DEBUG_KEYSTONE_UART0 | 1238 | default 0x02530c00 if DEBUG_KEYSTONE_UART0 |
1107 | default 0x02531000 if DEBUG_KEYSTONE_UART1 | 1239 | default 0x02531000 if DEBUG_KEYSTONE_UART1 |
1108 | default 0x03010fe0 if ARCH_RPC | 1240 | default 0x03010fe0 if ARCH_RPC |
1241 | default 0x07000000 if DEBUG_SUN9I_UART0 | ||
1109 | default 0x10009000 if DEBUG_REALVIEW_STD_PORT || \ | 1242 | default 0x10009000 if DEBUG_REALVIEW_STD_PORT || \ |
1110 | DEBUG_VEXPRESS_UART0_CA9 | 1243 | DEBUG_VEXPRESS_UART0_CA9 |
1111 | default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT | 1244 | default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT |
@@ -1113,7 +1246,9 @@ config DEBUG_UART_PHYS | |||
1113 | default 0x10126000 if DEBUG_RK3X_UART1 | 1246 | default 0x10126000 if DEBUG_RK3X_UART1 |
1114 | default 0x101f1000 if ARCH_VERSATILE | 1247 | default 0x101f1000 if ARCH_VERSATILE |
1115 | default 0x101fb000 if DEBUG_NOMADIK_UART | 1248 | default 0x101fb000 if DEBUG_NOMADIK_UART |
1249 | default 0x11002000 if DEBUG_MT8127_UART0 | ||
1116 | default 0x11006000 if DEBUG_MT6589_UART0 | 1250 | default 0x11006000 if DEBUG_MT6589_UART0 |
1251 | default 0x11009000 if DEBUG_MT8135_UART3 | ||
1117 | default 0x16000000 if ARCH_INTEGRATOR | 1252 | default 0x16000000 if ARCH_INTEGRATOR |
1118 | default 0x18000300 if DEBUG_BCM_5301X | 1253 | default 0x18000300 if DEBUG_BCM_5301X |
1119 | default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1 | 1254 | default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1 |
@@ -1135,6 +1270,7 @@ config DEBUG_UART_PHYS | |||
1135 | default 0x78000000 if DEBUG_CNS3XXX | 1270 | default 0x78000000 if DEBUG_CNS3XXX |
1136 | default 0x7c0003f8 if FOOTBRIDGE | 1271 | default 0x7c0003f8 if FOOTBRIDGE |
1137 | default 0x78000000 if DEBUG_CNS3XXX | 1272 | default 0x78000000 if DEBUG_CNS3XXX |
1273 | default 0x80010000 if DEBUG_ASM9260_UART | ||
1138 | default 0x80070000 if DEBUG_IMX23_UART | 1274 | default 0x80070000 if DEBUG_IMX23_UART |
1139 | default 0x80074000 if DEBUG_IMX28_UART | 1275 | default 0x80074000 if DEBUG_IMX28_UART |
1140 | default 0x80230000 if DEBUG_PICOXCELL_UART | 1276 | default 0x80230000 if DEBUG_PICOXCELL_UART |
@@ -1152,7 +1288,14 @@ config DEBUG_UART_PHYS | |||
1152 | default 0xd4018000 if DEBUG_MMP_UART3 | 1288 | default 0xd4018000 if DEBUG_MMP_UART3 |
1153 | default 0xe0000000 if ARCH_SPEAR13XX | 1289 | default 0xe0000000 if ARCH_SPEAR13XX |
1154 | default 0xe4007000 if DEBUG_HIP04_UART | 1290 | default 0xe4007000 if DEBUG_HIP04_UART |
1291 | default 0xe6c40000 if DEBUG_RMOBILE_SCIFA0 | ||
1292 | default 0xe6c50000 if DEBUG_RMOBILE_SCIFA1 | ||
1293 | default 0xe6c80000 if DEBUG_RMOBILE_SCIFA4 | ||
1294 | default 0xe6e58000 if DEBUG_RCAR_GEN2_SCIF2 | ||
1295 | default 0xe6e60000 if DEBUG_RCAR_GEN2_SCIF0 | ||
1296 | default 0xe8008000 if DEBUG_R7S72100_SCIF2 | ||
1155 | default 0xf0000be0 if ARCH_EBSA110 | 1297 | default 0xf0000be0 if ARCH_EBSA110 |
1298 | default 0xf040ab00 if DEBUG_BRCMSTB_UART | ||
1156 | default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE | 1299 | default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE |
1157 | default 0xf1012000 if ARCH_DOVE || ARCH_MV78XX0 || \ | 1300 | default 0xf1012000 if ARCH_DOVE || ARCH_MV78XX0 || \ |
1158 | ARCH_ORION5X | 1301 | ARCH_ORION5X |
@@ -1164,24 +1307,33 @@ config DEBUG_UART_PHYS | |||
1164 | default 0xff690000 if DEBUG_RK32_UART2 | 1307 | default 0xff690000 if DEBUG_RK32_UART2 |
1165 | default 0xffc02000 if DEBUG_SOCFPGA_UART | 1308 | default 0xffc02000 if DEBUG_SOCFPGA_UART |
1166 | default 0xffd82340 if ARCH_IOP13XX | 1309 | default 0xffd82340 if ARCH_IOP13XX |
1310 | default 0xffe40000 if DEBUG_RCAR_GEN1_SCIF0 | ||
1311 | default 0xffe42000 if DEBUG_RCAR_GEN1_SCIF2 | ||
1167 | default 0xfff36000 if DEBUG_HIGHBANK_UART | 1312 | default 0xfff36000 if DEBUG_HIGHBANK_UART |
1168 | default 0xfffe8600 if DEBUG_UART_BCM63XX | 1313 | default 0xfffe8600 if DEBUG_UART_BCM63XX |
1169 | default 0xfffff700 if ARCH_IOP33X | 1314 | default 0xfffff700 if ARCH_IOP33X |
1170 | depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ | 1315 | depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ |
1171 | DEBUG_LL_UART_EFM32 || \ | 1316 | DEBUG_LL_UART_EFM32 || \ |
1172 | DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \ | 1317 | DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \ |
1173 | DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \ | 1318 | DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \ |
1174 | DEBUG_UART_BCM63XX | 1319 | DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \ |
1320 | DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \ | ||
1321 | DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \ | ||
1322 | DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \ | ||
1323 | DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART | ||
1175 | 1324 | ||
1176 | config DEBUG_UART_VIRT | 1325 | config DEBUG_UART_VIRT |
1177 | hex "Virtual base address of debug UART" | 1326 | hex "Virtual base address of debug UART" |
1178 | default 0xe0010fe0 if ARCH_RPC | 1327 | default 0xe0010fe0 if ARCH_RPC |
1179 | default 0xe1000000 if DEBUG_MSM_UART | 1328 | default 0xe1000000 if DEBUG_MSM_UART |
1180 | default 0xf0000be0 if ARCH_EBSA110 | 1329 | default 0xf0000be0 if ARCH_EBSA110 |
1330 | default 0xf0010000 if DEBUG_ASM9260_UART | ||
1181 | default 0xf01fb000 if DEBUG_NOMADIK_UART | 1331 | default 0xf01fb000 if DEBUG_NOMADIK_UART |
1182 | default 0xf0201000 if DEBUG_BCM2835 | 1332 | default 0xf0201000 if DEBUG_BCM2835 |
1183 | default 0xf1000300 if DEBUG_BCM_5301X | 1333 | default 0xf1000300 if DEBUG_BCM_5301X |
1334 | default 0xf1002000 if DEBUG_MT8127_UART0 | ||
1184 | default 0xf1006000 if DEBUG_MT6589_UART0 | 1335 | default 0xf1006000 if DEBUG_MT6589_UART0 |
1336 | default 0xf1009000 if DEBUG_MT8135_UART3 | ||
1185 | default 0xf11f1000 if ARCH_VERSATILE | 1337 | default 0xf11f1000 if ARCH_VERSATILE |
1186 | default 0xf1600000 if ARCH_INTEGRATOR | 1338 | default 0xf1600000 if ARCH_INTEGRATOR |
1187 | default 0xf1c28000 if DEBUG_SUNXI_UART0 | 1339 | default 0xf1c28000 if DEBUG_SUNXI_UART0 |
@@ -1190,6 +1342,7 @@ config DEBUG_UART_VIRT | |||
1190 | default 0xf6200000 if DEBUG_PXA_UART1 | 1342 | default 0xf6200000 if DEBUG_PXA_UART1 |
1191 | default 0xf4090000 if ARCH_LPC32XX | 1343 | default 0xf4090000 if ARCH_LPC32XX |
1192 | default 0xf4200000 if ARCH_GEMINI | 1344 | default 0xf4200000 if ARCH_GEMINI |
1345 | default 0xf7000000 if DEBUG_SUN9I_UART0 | ||
1193 | default 0xf7000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \ | 1346 | default 0xf7000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \ |
1194 | DEBUG_S3C2410_UART0) | 1347 | DEBUG_S3C2410_UART0) |
1195 | default 0xf7004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \ | 1348 | default 0xf7004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \ |
@@ -1204,6 +1357,7 @@ config DEBUG_UART_VIRT | |||
1204 | default 0xfb002000 if DEBUG_CNS3XXX | 1357 | default 0xfb002000 if DEBUG_CNS3XXX |
1205 | default 0xfb009000 if DEBUG_REALVIEW_STD_PORT | 1358 | default 0xfb009000 if DEBUG_REALVIEW_STD_PORT |
1206 | default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT | 1359 | default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT |
1360 | default 0xfc40ab00 if DEBUG_BRCMSTB_UART | ||
1207 | default 0xfcfe8600 if DEBUG_UART_BCM63XX | 1361 | default 0xfcfe8600 if DEBUG_UART_BCM63XX |
1208 | default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX | 1362 | default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX |
1209 | default 0xfd000000 if ARCH_SPEAR13XX | 1363 | default 0xfd000000 if ARCH_SPEAR13XX |
@@ -1244,12 +1398,12 @@ config DEBUG_UART_VIRT | |||
1244 | depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ | 1398 | depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ |
1245 | DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \ | 1399 | DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \ |
1246 | DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \ | 1400 | DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \ |
1247 | DEBUG_UART_BCM63XX | 1401 | DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART |
1248 | 1402 | ||
1249 | config DEBUG_UART_8250_SHIFT | 1403 | config DEBUG_UART_8250_SHIFT |
1250 | int "Register offset shift for the 8250 debug UART" | 1404 | int "Register offset shift for the 8250 debug UART" |
1251 | depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 | 1405 | depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 |
1252 | default 0 if FOOTBRIDGE || ARCH_IOP32X | 1406 | default 0 if FOOTBRIDGE || ARCH_IOP32X || DEBUG_BCM_5301X |
1253 | default 2 | 1407 | default 2 |
1254 | 1408 | ||
1255 | config DEBUG_UART_8250_WORD | 1409 | config DEBUG_UART_8250_WORD |
@@ -1260,7 +1414,8 @@ config DEBUG_UART_8250_WORD | |||
1260 | ARCH_KEYSTONE || \ | 1414 | ARCH_KEYSTONE || \ |
1261 | DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \ | 1415 | DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \ |
1262 | DEBUG_DAVINCI_DA8XX_UART2 || \ | 1416 | DEBUG_DAVINCI_DA8XX_UART2 || \ |
1263 | DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 | 1417 | DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 || \ |
1418 | DEBUG_BRCMSTB_UART | ||
1264 | 1419 | ||
1265 | config DEBUG_UART_8250_FLOW_CONTROL | 1420 | config DEBUG_UART_8250_FLOW_CONTROL |
1266 | bool "Enable flow control for 8250 UART" | 1421 | bool "Enable flow control for 8250 UART" |
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi index 83286ec9702c..90dba78554c8 100644 --- a/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/arch/arm/boot/dts/armada-370-xp.dtsi | |||
@@ -180,7 +180,8 @@ | |||
180 | 180 | ||
181 | mbusc: mbus-controller@20000 { | 181 | mbusc: mbus-controller@20000 { |
182 | compatible = "marvell,mbus-controller"; | 182 | compatible = "marvell,mbus-controller"; |
183 | reg = <0x20000 0x100>, <0x20180 0x20>; | 183 | reg = <0x20000 0x100>, <0x20180 0x20>, |
184 | <0x20250 0x8>; | ||
184 | }; | 185 | }; |
185 | 186 | ||
186 | mpic: interrupt-controller@20000 { | 187 | mpic: interrupt-controller@20000 { |
diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts index 0478c55ca656..ea8673647494 100644 --- a/arch/arm/boot/dts/armada-xp-gp.dts +++ b/arch/arm/boot/dts/armada-xp-gp.dts | |||
@@ -23,6 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | /dts-v1/; | 25 | /dts-v1/; |
26 | #include <dt-bindings/gpio/gpio.h> | ||
26 | #include "armada-xp-mv78460.dtsi" | 27 | #include "armada-xp-mv78460.dtsi" |
27 | 28 | ||
28 | / { | 29 | / { |
@@ -48,6 +49,14 @@ | |||
48 | <0x00000001 0x00000000 0x00000001 0x00000000>; | 49 | <0x00000001 0x00000000 0x00000001 0x00000000>; |
49 | }; | 50 | }; |
50 | 51 | ||
52 | cpus { | ||
53 | pm_pic { | ||
54 | ctrl-gpios = <&gpio0 16 GPIO_ACTIVE_LOW>, | ||
55 | <&gpio0 17 GPIO_ACTIVE_LOW>, | ||
56 | <&gpio0 18 GPIO_ACTIVE_LOW>; | ||
57 | }; | ||
58 | }; | ||
59 | |||
51 | soc { | 60 | soc { |
52 | ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000 | 61 | ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000 |
53 | MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000 | 62 | MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000 |
@@ -115,7 +124,15 @@ | |||
115 | serial@12300 { | 124 | serial@12300 { |
116 | status = "okay"; | 125 | status = "okay"; |
117 | }; | 126 | }; |
118 | 127 | pinctrl { | |
128 | pinctrl-0 = <&pic_pins>; | ||
129 | pinctrl-names = "default"; | ||
130 | pic_pins: pic-pins-0 { | ||
131 | marvell,pins = "mpp16", "mpp17", | ||
132 | "mpp18"; | ||
133 | marvell,function = "gpio"; | ||
134 | }; | ||
135 | }; | ||
119 | sata@a0000 { | 136 | sata@a0000 { |
120 | nr-ports = <2>; | 137 | nr-ports = <2>; |
121 | status = "okay"; | 138 | status = "okay"; |
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi index bff9f6c18db1..2be244a96edf 100644 --- a/arch/arm/boot/dts/armada-xp.dtsi +++ b/arch/arm/boot/dts/armada-xp.dtsi | |||
@@ -35,6 +35,11 @@ | |||
35 | }; | 35 | }; |
36 | 36 | ||
37 | internal-regs { | 37 | internal-regs { |
38 | sdramc@1400 { | ||
39 | compatible = "marvell,armada-xp-sdram-controller"; | ||
40 | reg = <0x1400 0x500>; | ||
41 | }; | ||
42 | |||
38 | L2: l2-cache { | 43 | L2: l2-cache { |
39 | compatible = "marvell,aurora-system-cache"; | 44 | compatible = "marvell,aurora-system-cache"; |
40 | reg = <0x08000 0x1000>; | 45 | reg = <0x08000 0x1000>; |
diff --git a/arch/arm/boot/dts/integrator.dtsi b/arch/arm/boot/dts/integrator.dtsi index 88e3d477bf16..28e38f8c6b0f 100644 --- a/arch/arm/boot/dts/integrator.dtsi +++ b/arch/arm/boot/dts/integrator.dtsi | |||
@@ -6,8 +6,18 @@ | |||
6 | 6 | ||
7 | / { | 7 | / { |
8 | core-module@10000000 { | 8 | core-module@10000000 { |
9 | compatible = "arm,core-module-integrator"; | 9 | compatible = "arm,core-module-integrator", "syscon"; |
10 | reg = <0x10000000 0x200>; | 10 | reg = <0x10000000 0x200>; |
11 | |||
12 | /* Use core module LED to indicate CPU load */ | ||
13 | led@0c.0 { | ||
14 | compatible = "register-bit-led"; | ||
15 | offset = <0x0c>; | ||
16 | mask = <0x01>; | ||
17 | label = "integrator:core_module"; | ||
18 | linux,default-trigger = "cpu0"; | ||
19 | default-state = "on"; | ||
20 | }; | ||
11 | }; | 21 | }; |
12 | 22 | ||
13 | ebi@12000000 { | 23 | ebi@12000000 { |
@@ -82,5 +92,41 @@ | |||
82 | reg = <0x19000000 0x1000>; | 92 | reg = <0x19000000 0x1000>; |
83 | interrupts = <4>; | 93 | interrupts = <4>; |
84 | }; | 94 | }; |
95 | |||
96 | syscon { | ||
97 | /* Debug registers mapped as syscon */ | ||
98 | compatible = "syscon"; | ||
99 | reg = <0x1a000000 0x10>; | ||
100 | |||
101 | led@04.0 { | ||
102 | compatible = "register-bit-led"; | ||
103 | offset = <0x04>; | ||
104 | mask = <0x01>; | ||
105 | label = "integrator:green0"; | ||
106 | linux,default-trigger = "heartbeat"; | ||
107 | default-state = "on"; | ||
108 | }; | ||
109 | led@04.1 { | ||
110 | compatible = "register-bit-led"; | ||
111 | offset = <0x04>; | ||
112 | mask = <0x02>; | ||
113 | label = "integrator:yellow"; | ||
114 | default-state = "off"; | ||
115 | }; | ||
116 | led@04.2 { | ||
117 | compatible = "register-bit-led"; | ||
118 | offset = <0x04>; | ||
119 | mask = <0x04>; | ||
120 | label = "integrator:red"; | ||
121 | default-state = "off"; | ||
122 | }; | ||
123 | led@04.3 { | ||
124 | compatible = "register-bit-led"; | ||
125 | offset = <0x04>; | ||
126 | mask = <0x08>; | ||
127 | label = "integrator:green1"; | ||
128 | default-state = "off"; | ||
129 | }; | ||
130 | }; | ||
85 | }; | 131 | }; |
86 | }; | 132 | }; |
diff --git a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi index 25ba08331d88..3cbaf98c1372 100644 --- a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi +++ b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi | |||
@@ -64,6 +64,7 @@ | |||
64 | 64 | ||
65 | #include "twl4030.dtsi" | 65 | #include "twl4030.dtsi" |
66 | #include "twl4030_omap3.dtsi" | 66 | #include "twl4030_omap3.dtsi" |
67 | #include <dt-bindings/input/input.h> | ||
67 | 68 | ||
68 | &mmc1 { | 69 | &mmc1 { |
69 | vmmc-supply = <&vmmc1>; | 70 | vmmc-supply = <&vmmc1>; |
@@ -75,6 +76,22 @@ | |||
75 | ti,pullups = <0x000001>; | 76 | ti,pullups = <0x000001>; |
76 | }; | 77 | }; |
77 | 78 | ||
79 | &twl_keypad { | ||
80 | linux,keymap = < | ||
81 | MATRIX_KEY(0x00, 0x01, KEY_A) | ||
82 | MATRIX_KEY(0x00, 0x02, KEY_B) | ||
83 | MATRIX_KEY(0x00, 0x03, KEY_LEFT) | ||
84 | |||
85 | MATRIX_KEY(0x01, 0x01, KEY_UP) | ||
86 | MATRIX_KEY(0x01, 0x02, KEY_ENTER) | ||
87 | MATRIX_KEY(0x01, 0x03, KEY_DOWN) | ||
88 | |||
89 | MATRIX_KEY(0x02, 0x01, KEY_RIGHT) | ||
90 | MATRIX_KEY(0x02, 0x02, KEY_C) | ||
91 | MATRIX_KEY(0x02, 0x03, KEY_D) | ||
92 | >; | ||
93 | }; | ||
94 | |||
78 | &hsusb1_phy { | 95 | &hsusb1_phy { |
79 | reset-gpios = <&twl_gpio 6 GPIO_ACTIVE_LOW>; | 96 | reset-gpios = <&twl_gpio 6 GPIO_ACTIVE_LOW>; |
80 | }; | 97 | }; |
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 878c979203d0..84045a5c3ce8 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi | |||
@@ -895,7 +895,7 @@ | |||
895 | reg = <0x58002000 0x1000>; | 895 | reg = <0x58002000 0x1000>; |
896 | status = "disabled"; | 896 | status = "disabled"; |
897 | ti,hwmods = "dss_rfbi"; | 897 | ti,hwmods = "dss_rfbi"; |
898 | clocks = <&dss_dss_clk>, <&dss_fck>; | 898 | clocks = <&dss_dss_clk>, <&l3_div_ck>; |
899 | clock-names = "fck", "ick"; | 899 | clock-names = "fck", "ick"; |
900 | }; | 900 | }; |
901 | 901 | ||
diff --git a/arch/arm/boot/dts/omap44xx-clocks.dtsi b/arch/arm/boot/dts/omap44xx-clocks.dtsi index c821ff5e9b8d..f2c48f09824e 100644 --- a/arch/arm/boot/dts/omap44xx-clocks.dtsi +++ b/arch/arm/boot/dts/omap44xx-clocks.dtsi | |||
@@ -1018,14 +1018,6 @@ | |||
1018 | reg = <0x1120>; | 1018 | reg = <0x1120>; |
1019 | }; | 1019 | }; |
1020 | 1020 | ||
1021 | dss_fck: dss_fck { | ||
1022 | #clock-cells = <0>; | ||
1023 | compatible = "ti,gate-clock"; | ||
1024 | clocks = <&l3_div_ck>; | ||
1025 | ti,bit-shift = <1>; | ||
1026 | reg = <0x1120>; | ||
1027 | }; | ||
1028 | |||
1029 | fdif_fck: fdif_fck { | 1021 | fdif_fck: fdif_fck { |
1030 | #clock-cells = <0>; | 1022 | #clock-cells = <0>; |
1031 | compatible = "ti,divider-clock"; | 1023 | compatible = "ti,divider-clock"; |
diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi index 9d2323020d34..bfd3f1c734b8 100644 --- a/arch/arm/boot/dts/ste-dbx5x0.dtsi +++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <dt-bindings/interrupt-controller/irq.h> | 12 | #include <dt-bindings/interrupt-controller/irq.h> |
13 | #include <dt-bindings/mfd/dbx500-prcmu.h> | 13 | #include <dt-bindings/mfd/dbx500-prcmu.h> |
14 | #include <dt-bindings/arm/ux500_pm_domains.h> | ||
14 | #include "skeleton.dtsi" | 15 | #include "skeleton.dtsi" |
15 | 16 | ||
16 | / { | 17 | / { |
@@ -43,6 +44,10 @@ | |||
43 | interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; | 44 | interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; |
44 | }; | 45 | }; |
45 | 46 | ||
47 | pm_domains: pm_domains0 { | ||
48 | compatible = "stericsson,ux500-pm-domains"; | ||
49 | #power-domain-cells = <1>; | ||
50 | }; | ||
46 | 51 | ||
47 | clocks { | 52 | clocks { |
48 | compatible = "stericsson,u8500-clks"; | 53 | compatible = "stericsson,u8500-clks"; |
@@ -636,6 +641,7 @@ | |||
636 | clock-frequency = <400000>; | 641 | clock-frequency = <400000>; |
637 | clocks = <&prcc_kclk 3 3>, <&prcc_pclk 3 3>; | 642 | clocks = <&prcc_kclk 3 3>, <&prcc_pclk 3 3>; |
638 | clock-names = "i2cclk", "apb_pclk"; | 643 | clock-names = "i2cclk", "apb_pclk"; |
644 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
639 | }; | 645 | }; |
640 | 646 | ||
641 | i2c@80122000 { | 647 | i2c@80122000 { |
@@ -651,6 +657,7 @@ | |||
651 | 657 | ||
652 | clocks = <&prcc_kclk 1 2>, <&prcc_pclk 1 2>; | 658 | clocks = <&prcc_kclk 1 2>, <&prcc_pclk 1 2>; |
653 | clock-names = "i2cclk", "apb_pclk"; | 659 | clock-names = "i2cclk", "apb_pclk"; |
660 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
654 | }; | 661 | }; |
655 | 662 | ||
656 | i2c@80128000 { | 663 | i2c@80128000 { |
@@ -666,6 +673,7 @@ | |||
666 | 673 | ||
667 | clocks = <&prcc_kclk 1 6>, <&prcc_pclk 1 6>; | 674 | clocks = <&prcc_kclk 1 6>, <&prcc_pclk 1 6>; |
668 | clock-names = "i2cclk", "apb_pclk"; | 675 | clock-names = "i2cclk", "apb_pclk"; |
676 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
669 | }; | 677 | }; |
670 | 678 | ||
671 | i2c@80110000 { | 679 | i2c@80110000 { |
@@ -681,6 +689,7 @@ | |||
681 | 689 | ||
682 | clocks = <&prcc_kclk 2 0>, <&prcc_pclk 2 0>; | 690 | clocks = <&prcc_kclk 2 0>, <&prcc_pclk 2 0>; |
683 | clock-names = "i2cclk", "apb_pclk"; | 691 | clock-names = "i2cclk", "apb_pclk"; |
692 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
684 | }; | 693 | }; |
685 | 694 | ||
686 | i2c@8012a000 { | 695 | i2c@8012a000 { |
@@ -696,6 +705,7 @@ | |||
696 | 705 | ||
697 | clocks = <&prcc_kclk 1 9>, <&prcc_pclk 1 10>; | 706 | clocks = <&prcc_kclk 1 9>, <&prcc_pclk 1 10>; |
698 | clock-names = "i2cclk", "apb_pclk"; | 707 | clock-names = "i2cclk", "apb_pclk"; |
708 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
699 | }; | 709 | }; |
700 | 710 | ||
701 | ssp@80002000 { | 711 | ssp@80002000 { |
@@ -709,6 +719,7 @@ | |||
709 | dmas = <&dma 8 0 0x2>, /* Logical - DevToMem */ | 719 | dmas = <&dma 8 0 0x2>, /* Logical - DevToMem */ |
710 | <&dma 8 0 0x0>; /* Logical - MemToDev */ | 720 | <&dma 8 0 0x0>; /* Logical - MemToDev */ |
711 | dma-names = "rx", "tx"; | 721 | dma-names = "rx", "tx"; |
722 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
712 | }; | 723 | }; |
713 | 724 | ||
714 | ssp@80003000 { | 725 | ssp@80003000 { |
@@ -722,6 +733,7 @@ | |||
722 | dmas = <&dma 9 0 0x2>, /* Logical - DevToMem */ | 733 | dmas = <&dma 9 0 0x2>, /* Logical - DevToMem */ |
723 | <&dma 9 0 0x0>; /* Logical - MemToDev */ | 734 | <&dma 9 0 0x0>; /* Logical - MemToDev */ |
724 | dma-names = "rx", "tx"; | 735 | dma-names = "rx", "tx"; |
736 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
725 | }; | 737 | }; |
726 | 738 | ||
727 | spi@8011a000 { | 739 | spi@8011a000 { |
@@ -736,6 +748,7 @@ | |||
736 | dmas = <&dma 0 0 0x2>, /* Logical - DevToMem */ | 748 | dmas = <&dma 0 0 0x2>, /* Logical - DevToMem */ |
737 | <&dma 0 0 0x0>; /* Logical - MemToDev */ | 749 | <&dma 0 0 0x0>; /* Logical - MemToDev */ |
738 | dma-names = "rx", "tx"; | 750 | dma-names = "rx", "tx"; |
751 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
739 | }; | 752 | }; |
740 | 753 | ||
741 | spi@80112000 { | 754 | spi@80112000 { |
@@ -750,6 +763,7 @@ | |||
750 | dmas = <&dma 35 0 0x2>, /* Logical - DevToMem */ | 763 | dmas = <&dma 35 0 0x2>, /* Logical - DevToMem */ |
751 | <&dma 35 0 0x0>; /* Logical - MemToDev */ | 764 | <&dma 35 0 0x0>; /* Logical - MemToDev */ |
752 | dma-names = "rx", "tx"; | 765 | dma-names = "rx", "tx"; |
766 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
753 | }; | 767 | }; |
754 | 768 | ||
755 | spi@80111000 { | 769 | spi@80111000 { |
@@ -764,6 +778,7 @@ | |||
764 | dmas = <&dma 33 0 0x2>, /* Logical - DevToMem */ | 778 | dmas = <&dma 33 0 0x2>, /* Logical - DevToMem */ |
765 | <&dma 33 0 0x0>; /* Logical - MemToDev */ | 779 | <&dma 33 0 0x0>; /* Logical - MemToDev */ |
766 | dma-names = "rx", "tx"; | 780 | dma-names = "rx", "tx"; |
781 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
767 | }; | 782 | }; |
768 | 783 | ||
769 | spi@80129000 { | 784 | spi@80129000 { |
@@ -778,6 +793,7 @@ | |||
778 | dmas = <&dma 40 0 0x2>, /* Logical - DevToMem */ | 793 | dmas = <&dma 40 0 0x2>, /* Logical - DevToMem */ |
779 | <&dma 40 0 0x0>; /* Logical - MemToDev */ | 794 | <&dma 40 0 0x0>; /* Logical - MemToDev */ |
780 | dma-names = "rx", "tx"; | 795 | dma-names = "rx", "tx"; |
796 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
781 | }; | 797 | }; |
782 | 798 | ||
783 | uart@80120000 { | 799 | uart@80120000 { |
@@ -836,6 +852,7 @@ | |||
836 | 852 | ||
837 | clocks = <&prcc_kclk 1 5>, <&prcc_pclk 1 5>; | 853 | clocks = <&prcc_kclk 1 5>, <&prcc_pclk 1 5>; |
838 | clock-names = "sdi", "apb_pclk"; | 854 | clock-names = "sdi", "apb_pclk"; |
855 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
839 | 856 | ||
840 | status = "disabled"; | 857 | status = "disabled"; |
841 | }; | 858 | }; |
@@ -851,6 +868,7 @@ | |||
851 | 868 | ||
852 | clocks = <&prcc_kclk 2 4>, <&prcc_pclk 2 6>; | 869 | clocks = <&prcc_kclk 2 4>, <&prcc_pclk 2 6>; |
853 | clock-names = "sdi", "apb_pclk"; | 870 | clock-names = "sdi", "apb_pclk"; |
871 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
854 | 872 | ||
855 | status = "disabled"; | 873 | status = "disabled"; |
856 | }; | 874 | }; |
@@ -866,6 +884,7 @@ | |||
866 | 884 | ||
867 | clocks = <&prcc_kclk 3 4>, <&prcc_pclk 3 4>; | 885 | clocks = <&prcc_kclk 3 4>, <&prcc_pclk 3 4>; |
868 | clock-names = "sdi", "apb_pclk"; | 886 | clock-names = "sdi", "apb_pclk"; |
887 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
869 | 888 | ||
870 | status = "disabled"; | 889 | status = "disabled"; |
871 | }; | 890 | }; |
@@ -881,6 +900,7 @@ | |||
881 | 900 | ||
882 | clocks = <&prcc_kclk 2 5>, <&prcc_pclk 2 7>; | 901 | clocks = <&prcc_kclk 2 5>, <&prcc_pclk 2 7>; |
883 | clock-names = "sdi", "apb_pclk"; | 902 | clock-names = "sdi", "apb_pclk"; |
903 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
884 | 904 | ||
885 | status = "disabled"; | 905 | status = "disabled"; |
886 | }; | 906 | }; |
@@ -896,6 +916,7 @@ | |||
896 | 916 | ||
897 | clocks = <&prcc_kclk 2 2>, <&prcc_pclk 2 4>; | 917 | clocks = <&prcc_kclk 2 2>, <&prcc_pclk 2 4>; |
898 | clock-names = "sdi", "apb_pclk"; | 918 | clock-names = "sdi", "apb_pclk"; |
919 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
899 | 920 | ||
900 | status = "disabled"; | 921 | status = "disabled"; |
901 | }; | 922 | }; |
@@ -911,6 +932,7 @@ | |||
911 | 932 | ||
912 | clocks = <&prcc_kclk 3 7>, <&prcc_pclk 3 7>; | 933 | clocks = <&prcc_kclk 3 7>, <&prcc_pclk 3 7>; |
913 | clock-names = "sdi", "apb_pclk"; | 934 | clock-names = "sdi", "apb_pclk"; |
935 | power-domains = <&pm_domains DOMAIN_VAPE>; | ||
914 | 936 | ||
915 | status = "disabled"; | 937 | status = "disabled"; |
916 | }; | 938 | }; |
diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig index bc614f44b33d..83a87e48901c 100644 --- a/arch/arm/configs/bcm_defconfig +++ b/arch/arm/configs/bcm_defconfig | |||
@@ -25,7 +25,8 @@ CONFIG_MODULE_UNLOAD=y | |||
25 | # CONFIG_BLK_DEV_BSG is not set | 25 | # CONFIG_BLK_DEV_BSG is not set |
26 | CONFIG_PARTITION_ADVANCED=y | 26 | CONFIG_PARTITION_ADVANCED=y |
27 | CONFIG_ARCH_BCM=y | 27 | CONFIG_ARCH_BCM=y |
28 | CONFIG_ARCH_BCM_MOBILE=y | 28 | CONFIG_ARCH_BCM_21664=y |
29 | CONFIG_ARCH_BCM_281XX=y | ||
29 | CONFIG_ARM_THUMBEE=y | 30 | CONFIG_ARM_THUMBEE=y |
30 | CONFIG_SMP=y | 31 | CONFIG_SMP=y |
31 | CONFIG_PREEMPT=y | 32 | CONFIG_PREEMPT=y |
diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig index c1f5adc5493e..71f14675d009 100644 --- a/arch/arm/configs/integrator_defconfig +++ b/arch/arm/configs/integrator_defconfig | |||
@@ -8,6 +8,9 @@ CONFIG_BLK_DEV_INITRD=y | |||
8 | CONFIG_MODULES=y | 8 | CONFIG_MODULES=y |
9 | CONFIG_MODULE_UNLOAD=y | 9 | CONFIG_MODULE_UNLOAD=y |
10 | CONFIG_PARTITION_ADVANCED=y | 10 | CONFIG_PARTITION_ADVANCED=y |
11 | CONFIG_ARCH_MULTI_V4T=y | ||
12 | CONFIG_ARCH_MULTI_V5=y | ||
13 | # CONFIG_ARCH_MULTI_V7 is not set | ||
11 | CONFIG_ARCH_INTEGRATOR=y | 14 | CONFIG_ARCH_INTEGRATOR=y |
12 | CONFIG_ARCH_INTEGRATOR_AP=y | 15 | CONFIG_ARCH_INTEGRATOR_AP=y |
13 | CONFIG_ARCH_INTEGRATOR_CP=y | 16 | CONFIG_ARCH_INTEGRATOR_CP=y |
diff --git a/arch/arm/include/asm/firmware.h b/arch/arm/include/asm/firmware.h index 2c9f10df7568..89aefe10d66b 100644 --- a/arch/arm/include/asm/firmware.h +++ b/arch/arm/include/asm/firmware.h | |||
@@ -28,7 +28,7 @@ struct firmware_ops { | |||
28 | /* | 28 | /* |
29 | * Enters CPU idle mode | 29 | * Enters CPU idle mode |
30 | */ | 30 | */ |
31 | int (*do_idle)(void); | 31 | int (*do_idle)(unsigned long mode); |
32 | /* | 32 | /* |
33 | * Sets boot address of specified physical CPU | 33 | * Sets boot address of specified physical CPU |
34 | */ | 34 | */ |
@@ -41,6 +41,14 @@ struct firmware_ops { | |||
41 | * Initializes L2 cache | 41 | * Initializes L2 cache |
42 | */ | 42 | */ |
43 | int (*l2x0_init)(void); | 43 | int (*l2x0_init)(void); |
44 | /* | ||
45 | * Enter system-wide suspend. | ||
46 | */ | ||
47 | int (*suspend)(void); | ||
48 | /* | ||
49 | * Restore state of privileged hardware after system-wide suspend. | ||
50 | */ | ||
51 | int (*resume)(void); | ||
44 | }; | 52 | }; |
45 | 53 | ||
46 | /* Global pointer for current firmware_ops structure, can't be NULL. */ | 54 | /* Global pointer for current firmware_ops structure, can't be NULL. */ |
diff --git a/arch/arm/include/debug/asm9260.S b/arch/arm/include/debug/asm9260.S new file mode 100644 index 000000000000..292f85b49fca --- /dev/null +++ b/arch/arm/include/debug/asm9260.S | |||
@@ -0,0 +1,29 @@ | |||
1 | /* Debugging macro include header | ||
2 | * | ||
3 | * Copyright (C) 1994-1999 Russell King | ||
4 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
5 | * Modified for ASM9260 by Oleksij Remepl <linux@rempel-privat.de> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | .macro addruart, rp, rv, tmp | ||
14 | ldr \rp, = CONFIG_DEBUG_UART_PHYS | ||
15 | ldr \rv, = CONFIG_DEBUG_UART_VIRT | ||
16 | .endm | ||
17 | |||
18 | .macro waituart,rd,rx | ||
19 | .endm | ||
20 | |||
21 | .macro senduart,rd,rx | ||
22 | str \rd, [\rx, #0x50] @ TXDATA | ||
23 | .endm | ||
24 | |||
25 | .macro busyuart,rd,rx | ||
26 | 1002: ldr \rd, [\rx, #0x60] @ STAT | ||
27 | tst \rd, #1 << 27 @ TXEMPTY | ||
28 | beq 1002b @ wait until transmit done | ||
29 | .endm | ||
diff --git a/arch/arm/include/debug/renesas-scif.S b/arch/arm/include/debug/renesas-scif.S new file mode 100644 index 000000000000..97820a8df51a --- /dev/null +++ b/arch/arm/include/debug/renesas-scif.S | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * Renesas SCIF(A) debugging macro include header | ||
3 | * | ||
4 | * Based on r8a7790.S | ||
5 | * | ||
6 | * Copyright (C) 2012-2013 Renesas Electronics Corporation | ||
7 | * Copyright (C) 1994-1999 Russell King | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #define SCIF_PHYS CONFIG_DEBUG_UART_PHYS | ||
15 | #define SCIF_VIRT ((SCIF_PHYS & 0x00ffffff) | 0xfd000000) | ||
16 | |||
17 | #if CONFIG_DEBUG_UART_PHYS < 0xe6e00000 | ||
18 | /* SCIFA */ | ||
19 | #define FTDR 0x20 | ||
20 | #define FSR 0x14 | ||
21 | #else | ||
22 | /* SCIF */ | ||
23 | #define FTDR 0x0c | ||
24 | #define FSR 0x10 | ||
25 | #endif | ||
26 | |||
27 | #define TDFE (1 << 5) | ||
28 | #define TEND (1 << 6) | ||
29 | |||
30 | .macro addruart, rp, rv, tmp | ||
31 | ldr \rp, =SCIF_PHYS | ||
32 | ldr \rv, =SCIF_VIRT | ||
33 | .endm | ||
34 | |||
35 | .macro waituart, rd, rx | ||
36 | 1001: ldrh \rd, [\rx, #FSR] | ||
37 | tst \rd, #TDFE | ||
38 | beq 1001b | ||
39 | .endm | ||
40 | |||
41 | .macro senduart, rd, rx | ||
42 | strb \rd, [\rx, #FTDR] | ||
43 | ldrh \rd, [\rx, #FSR] | ||
44 | bic \rd, \rd, #TEND | ||
45 | strh \rd, [\rx, #FSR] | ||
46 | .endm | ||
47 | |||
48 | .macro busyuart, rd, rx | ||
49 | 1001: ldrh \rd, [\rx, #FSR] | ||
50 | tst \rd, #TEND | ||
51 | beq 1001b | ||
52 | .endm | ||
diff --git a/arch/arm/mach-sa1100/include/mach/debug-macro.S b/arch/arm/include/debug/sa1100.S index 530772d937ad..a0ae4f4cd924 100644 --- a/arch/arm/mach-sa1100/include/mach/debug-macro.S +++ b/arch/arm/include/debug/sa1100.S | |||
@@ -1,4 +1,4 @@ | |||
1 | /* arch/arm/mach-sa1100/include/mach/debug-macro.S | 1 | /* arch/arm/include/debug/sa1100.S |
2 | * | 2 | * |
3 | * Debugging macro include header | 3 | * Debugging macro include header |
4 | * | 4 | * |
@@ -10,7 +10,13 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | #include <mach/hardware.h> | 13 | |
14 | #define UTCR3 0x0c | ||
15 | #define UTDR 0x14 | ||
16 | #define UTSR1 0x20 | ||
17 | #define UTCR3_TXE 0x00000002 /* Transmit Enable */ | ||
18 | #define UTSR1_TBY 0x00000001 /* Transmitter BusY (read) */ | ||
19 | #define UTSR1_TNF 0x00000004 /* Transmit FIFO Not Full (read) */ | ||
14 | 20 | ||
15 | .macro addruart, rp, rv, tmp | 21 | .macro addruart, rp, rv, tmp |
16 | mrc p15, 0, \rp, c1, c0 | 22 | mrc p15, 0, \rp, c1, c0 |
diff --git a/arch/arm/mach-asm9260/Kconfig b/arch/arm/mach-asm9260/Kconfig new file mode 100644 index 000000000000..8423be76080e --- /dev/null +++ b/arch/arm/mach-asm9260/Kconfig | |||
@@ -0,0 +1,6 @@ | |||
1 | config MACH_ASM9260 | ||
2 | bool "Alphascale ASM9260" | ||
3 | depends on ARCH_MULTI_V5 | ||
4 | select CPU_ARM926T | ||
5 | help | ||
6 | Support for Alphascale ASM9260 based platform. | ||
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 2abad742516d..1bd39b45d08b 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig | |||
@@ -5,8 +5,56 @@ menuconfig ARCH_BCM | |||
5 | 5 | ||
6 | if ARCH_BCM | 6 | if ARCH_BCM |
7 | 7 | ||
8 | comment "IPROC architected SoCs" | ||
9 | |||
10 | config ARCH_BCM_IPROC | ||
11 | bool | ||
12 | select ARM_GIC | ||
13 | select CACHE_L2X0 | ||
14 | select HAVE_ARM_SCU if SMP | ||
15 | select HAVE_ARM_TWD if SMP | ||
16 | select ARM_GLOBAL_TIMER | ||
17 | |||
18 | select CLKSRC_MMIO | ||
19 | select ARCH_REQUIRE_GPIOLIB | ||
20 | select ARM_AMBA | ||
21 | select PINCTRL | ||
22 | help | ||
23 | This enables support for systems based on Broadcom IPROC architected SoCs. | ||
24 | The IPROC complex contains one or more ARM CPUs along with common | ||
25 | core periperals. Application specific SoCs are created by adding a | ||
26 | uArchitecture containing peripherals outside of the IPROC complex. | ||
27 | Currently supported SoCs are Cygnus. | ||
28 | |||
29 | config ARCH_BCM_CYGNUS | ||
30 | bool "Broadcom Cygnus Support" if ARCH_MULTI_V7 | ||
31 | select ARCH_BCM_IPROC | ||
32 | help | ||
33 | Enable support for the Cygnus family, | ||
34 | which includes the following variants: | ||
35 | BCM11300, BCM11320, BCM11350, BCM11360, | ||
36 | BCM58300, BCM58302, BCM58303, BCM58305. | ||
37 | |||
38 | config ARCH_BCM_5301X | ||
39 | bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7 | ||
40 | select ARCH_BCM_IPROC | ||
41 | help | ||
42 | Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores. | ||
43 | |||
44 | This is a network SoC line mostly used in home routers and | ||
45 | wifi access points, it's internal name is Northstar. | ||
46 | This inclused the following SoC: BCM53010, BCM53011, BCM53012, | ||
47 | BCM53014, BCM53015, BCM53016, BCM53017, BCM53018, BCM4707, | ||
48 | BCM4708 and BCM4709. | ||
49 | |||
50 | Do not confuse this with the BCM4760 which is a totally | ||
51 | different SoC or with the older BCM47XX and BCM53XX based | ||
52 | network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx | ||
53 | |||
54 | comment "KONA architected SoCs" | ||
55 | |||
8 | config ARCH_BCM_MOBILE | 56 | config ARCH_BCM_MOBILE |
9 | bool "Broadcom Mobile SoC Support" if ARCH_MULTI_V7 | 57 | bool |
10 | select ARCH_REQUIRE_GPIOLIB | 58 | select ARCH_REQUIRE_GPIOLIB |
11 | select ARM_ERRATA_754322 | 59 | select ARM_ERRATA_754322 |
12 | select ARM_ERRATA_775420 | 60 | select ARM_ERRATA_775420 |
@@ -15,16 +63,13 @@ config ARCH_BCM_MOBILE | |||
15 | select TICK_ONESHOT | 63 | select TICK_ONESHOT |
16 | select HAVE_ARM_ARCH_TIMER | 64 | select HAVE_ARM_ARCH_TIMER |
17 | select PINCTRL | 65 | select PINCTRL |
66 | select ARCH_BCM_MOBILE_SMP if SMP | ||
18 | help | 67 | help |
19 | This enables support for systems based on Broadcom mobile SoCs. | 68 | This enables support for systems based on Broadcom mobile SoCs. |
20 | 69 | ||
21 | if ARCH_BCM_MOBILE | ||
22 | |||
23 | menu "Broadcom Mobile SoC Selection" | ||
24 | |||
25 | config ARCH_BCM_281XX | 70 | config ARCH_BCM_281XX |
26 | bool "Broadcom BCM281XX SoC family" | 71 | bool "Broadcom BCM281XX SoC family" |
27 | default y | 72 | select ARCH_BCM_MOBILE |
28 | select HAVE_SMP | 73 | select HAVE_SMP |
29 | help | 74 | help |
30 | Enable support for the BCM281XX family, which includes | 75 | Enable support for the BCM281XX family, which includes |
@@ -33,7 +78,7 @@ config ARCH_BCM_281XX | |||
33 | 78 | ||
34 | config ARCH_BCM_21664 | 79 | config ARCH_BCM_21664 |
35 | bool "Broadcom BCM21664 SoC family" | 80 | bool "Broadcom BCM21664 SoC family" |
36 | default y | 81 | select ARCH_BCM_MOBILE |
37 | select HAVE_SMP | 82 | select HAVE_SMP |
38 | help | 83 | help |
39 | Enable support for the BCM21664 family, which includes | 84 | Enable support for the BCM21664 family, which includes |
@@ -41,19 +86,18 @@ config ARCH_BCM_21664 | |||
41 | 86 | ||
42 | config ARCH_BCM_MOBILE_L2_CACHE | 87 | config ARCH_BCM_MOBILE_L2_CACHE |
43 | bool "Broadcom mobile SoC level 2 cache support" | 88 | bool "Broadcom mobile SoC level 2 cache support" |
44 | depends on (ARCH_BCM_281XX || ARCH_BCM_21664) | 89 | depends on ARCH_BCM_MOBILE |
45 | default y | 90 | default y |
46 | select CACHE_L2X0 | 91 | select CACHE_L2X0 |
47 | select ARCH_BCM_MOBILE_SMC | 92 | select ARCH_BCM_MOBILE_SMC |
48 | 93 | ||
49 | config ARCH_BCM_MOBILE_SMC | 94 | config ARCH_BCM_MOBILE_SMC |
50 | bool | 95 | bool |
51 | depends on ARCH_BCM_281XX || ARCH_BCM_21664 | 96 | depends on ARCH_BCM_MOBILE |
52 | 97 | ||
53 | config ARCH_BCM_MOBILE_SMP | 98 | config ARCH_BCM_MOBILE_SMP |
54 | bool "Broadcom mobile SoC SMP support" | 99 | bool |
55 | depends on (ARCH_BCM_281XX || ARCH_BCM_21664) && SMP | 100 | depends on ARCH_BCM_MOBILE |
56 | default y | ||
57 | select HAVE_ARM_SCU | 101 | select HAVE_ARM_SCU |
58 | select ARM_ERRATA_764369 | 102 | select ARM_ERRATA_764369 |
59 | help | 103 | help |
@@ -61,9 +105,7 @@ config ARCH_BCM_MOBILE_SMP | |||
61 | Provided as an option so SMP support for SoCs of this type | 105 | Provided as an option so SMP support for SoCs of this type |
62 | can be disabled for an SMP-enabled kernel. | 106 | can be disabled for an SMP-enabled kernel. |
63 | 107 | ||
64 | endmenu | 108 | comment "Other Architectures" |
65 | |||
66 | endif | ||
67 | 109 | ||
68 | config ARCH_BCM2835 | 110 | config ARCH_BCM2835 |
69 | bool "Broadcom BCM2835 family" if ARCH_MULTI_V6 | 111 | bool "Broadcom BCM2835 family" if ARCH_MULTI_V6 |
@@ -78,27 +120,6 @@ config ARCH_BCM2835 | |||
78 | This enables support for the Broadcom BCM2835 SoC. This SoC is | 120 | This enables support for the Broadcom BCM2835 SoC. This SoC is |
79 | used in the Raspberry Pi and Roku 2 devices. | 121 | used in the Raspberry Pi and Roku 2 devices. |
80 | 122 | ||
81 | config ARCH_BCM_5301X | ||
82 | bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7 | ||
83 | select ARM_GIC | ||
84 | select CACHE_L2X0 | ||
85 | select HAVE_ARM_SCU if SMP | ||
86 | select HAVE_ARM_TWD if SMP | ||
87 | select ARM_GLOBAL_TIMER | ||
88 | select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK | ||
89 | help | ||
90 | Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores. | ||
91 | |||
92 | This is a network SoC line mostly used in home routers and | ||
93 | wifi access points, it's internal name is Northstar. | ||
94 | This inclused the following SoC: BCM53010, BCM53011, BCM53012, | ||
95 | BCM53014, BCM53015, BCM53016, BCM53017, BCM53018, BCM4707, | ||
96 | BCM4708 and BCM4709. | ||
97 | |||
98 | Do not confuse this with the BCM4760 which is a totally | ||
99 | different SoC or with the older BCM47XX and BCM53XX based | ||
100 | network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx | ||
101 | |||
102 | config ARCH_BCM_63XX | 123 | config ARCH_BCM_63XX |
103 | bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7 | 124 | bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7 |
104 | depends on MMU | 125 | depends on MMU |
@@ -118,10 +139,7 @@ config ARCH_BCM_63XX | |||
118 | 139 | ||
119 | config ARCH_BRCMSTB | 140 | config ARCH_BRCMSTB |
120 | bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7 | 141 | bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7 |
121 | depends on MMU | ||
122 | select ARM_GIC | 142 | select ARM_GIC |
123 | select MIGHT_HAVE_PCI | ||
124 | select HAVE_SMP | ||
125 | select HAVE_ARM_ARCH_TIMER | 143 | select HAVE_ARM_ARCH_TIMER |
126 | select BRCMSTB_GISB_ARB | 144 | select BRCMSTB_GISB_ARB |
127 | select BRCMSTB_L2_IRQ | 145 | select BRCMSTB_L2_IRQ |
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile index 300ae4b79ae6..4c38674c73ec 100644 --- a/arch/arm/mach-bcm/Makefile +++ b/arch/arm/mach-bcm/Makefile | |||
@@ -10,6 +10,9 @@ | |||
10 | # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 | # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | # GNU General Public License for more details. | 11 | # GNU General Public License for more details. |
12 | 12 | ||
13 | # Cygnus | ||
14 | obj-$(CONFIG_ARCH_BCM_CYGNUS) += bcm_cygnus.o | ||
15 | |||
13 | # BCM281XX | 16 | # BCM281XX |
14 | obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o | 17 | obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o |
15 | 18 | ||
@@ -38,5 +41,7 @@ obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o | |||
38 | obj-$(CONFIG_ARCH_BCM_63XX) := bcm63xx.o | 41 | obj-$(CONFIG_ARCH_BCM_63XX) := bcm63xx.o |
39 | 42 | ||
40 | ifeq ($(CONFIG_ARCH_BRCMSTB),y) | 43 | ifeq ($(CONFIG_ARCH_BRCMSTB),y) |
44 | CFLAGS_platsmp-brcmstb.o += -march=armv7-a | ||
41 | obj-y += brcmstb.o | 45 | obj-y += brcmstb.o |
46 | obj-$(CONFIG_SMP) += headsmp-brcmstb.o platsmp-brcmstb.o | ||
42 | endif | 47 | endif |
diff --git a/arch/arm/mach-bcm/bcm_cygnus.c b/arch/arm/mach-bcm/bcm_cygnus.c new file mode 100644 index 000000000000..30dc58be51b8 --- /dev/null +++ b/arch/arm/mach-bcm/bcm_cygnus.c | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <asm/mach/arch.h> | ||
15 | |||
16 | static const char const *bcm_cygnus_dt_compat[] = { | ||
17 | "brcm,cygnus", | ||
18 | NULL, | ||
19 | }; | ||
20 | |||
21 | DT_MACHINE_START(BCM_CYGNUS_DT, "Broadcom Cygnus SoC") | ||
22 | .l2c_aux_val = 0, | ||
23 | .l2c_aux_mask = ~0, | ||
24 | .dt_compat = bcm_cygnus_dt_compat, | ||
25 | MACHINE_END | ||
diff --git a/arch/arm/mach-bcm/brcmstb.h b/arch/arm/mach-bcm/brcmstb.h new file mode 100644 index 000000000000..ec0c3d112b36 --- /dev/null +++ b/arch/arm/mach-bcm/brcmstb.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013-2014 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef __BRCMSTB_H__ | ||
15 | #define __BRCMSTB_H__ | ||
16 | |||
17 | void brcmstb_secondary_startup(void); | ||
18 | |||
19 | #endif /* __BRCMSTB_H__ */ | ||
diff --git a/arch/arm/mach-bcm/headsmp-brcmstb.S b/arch/arm/mach-bcm/headsmp-brcmstb.S new file mode 100644 index 000000000000..199c1ea58248 --- /dev/null +++ b/arch/arm/mach-bcm/headsmp-brcmstb.S | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * SMP boot code for secondary CPUs | ||
3 | * Based on arch/arm/mach-tegra/headsmp.S | ||
4 | * | ||
5 | * Copyright (C) 2010 NVIDIA, Inc. | ||
6 | * Copyright (C) 2013-2014 Broadcom Corporation | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation version 2. | ||
11 | * | ||
12 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
13 | * kind, whether express or implied; without even the implied warranty | ||
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <asm/assembler.h> | ||
19 | #include <linux/linkage.h> | ||
20 | #include <linux/init.h> | ||
21 | |||
22 | .section ".text.head", "ax" | ||
23 | |||
24 | ENTRY(brcmstb_secondary_startup) | ||
25 | /* | ||
26 | * Ensure CPU is in a sane state by disabling all IRQs and switching | ||
27 | * into SVC mode. | ||
28 | */ | ||
29 | setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r0 | ||
30 | |||
31 | bl v7_invalidate_l1 | ||
32 | b secondary_startup | ||
33 | ENDPROC(brcmstb_secondary_startup) | ||
diff --git a/arch/arm/mach-bcm/platsmp-brcmstb.c b/arch/arm/mach-bcm/platsmp-brcmstb.c new file mode 100644 index 000000000000..31c87a284a34 --- /dev/null +++ b/arch/arm/mach-bcm/platsmp-brcmstb.c | |||
@@ -0,0 +1,329 @@ | |||
1 | /* | ||
2 | * Broadcom STB CPU SMP and hotplug support for ARM | ||
3 | * | ||
4 | * Copyright (C) 2013-2014 Broadcom Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether express or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/delay.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/of_address.h> | ||
21 | #include <linux/of_platform.h> | ||
22 | #include <linux/printk.h> | ||
23 | #include <linux/regmap.h> | ||
24 | #include <linux/smp.h> | ||
25 | #include <linux/mfd/syscon.h> | ||
26 | |||
27 | #include <asm/cacheflush.h> | ||
28 | #include <asm/cp15.h> | ||
29 | #include <asm/mach-types.h> | ||
30 | #include <asm/smp_plat.h> | ||
31 | |||
32 | #include "brcmstb.h" | ||
33 | |||
34 | enum { | ||
35 | ZONE_MAN_CLKEN_MASK = BIT(0), | ||
36 | ZONE_MAN_RESET_CNTL_MASK = BIT(1), | ||
37 | ZONE_MAN_MEM_PWR_MASK = BIT(4), | ||
38 | ZONE_RESERVED_1_MASK = BIT(5), | ||
39 | ZONE_MAN_ISO_CNTL_MASK = BIT(6), | ||
40 | ZONE_MANUAL_CONTROL_MASK = BIT(7), | ||
41 | ZONE_PWR_DN_REQ_MASK = BIT(9), | ||
42 | ZONE_PWR_UP_REQ_MASK = BIT(10), | ||
43 | ZONE_BLK_RST_ASSERT_MASK = BIT(12), | ||
44 | ZONE_PWR_OFF_STATE_MASK = BIT(25), | ||
45 | ZONE_PWR_ON_STATE_MASK = BIT(26), | ||
46 | ZONE_DPG_PWR_STATE_MASK = BIT(28), | ||
47 | ZONE_MEM_PWR_STATE_MASK = BIT(29), | ||
48 | ZONE_RESET_STATE_MASK = BIT(31), | ||
49 | CPU0_PWR_ZONE_CTRL_REG = 1, | ||
50 | CPU_RESET_CONFIG_REG = 2, | ||
51 | }; | ||
52 | |||
53 | static void __iomem *cpubiuctrl_block; | ||
54 | static void __iomem *hif_cont_block; | ||
55 | static u32 cpu0_pwr_zone_ctrl_reg; | ||
56 | static u32 cpu_rst_cfg_reg; | ||
57 | static u32 hif_cont_reg; | ||
58 | |||
59 | #ifdef CONFIG_HOTPLUG_CPU | ||
60 | /* | ||
61 | * We must quiesce a dying CPU before it can be killed by the boot CPU. Because | ||
62 | * one or more cache may be disabled, we must flush to ensure coherency. We | ||
63 | * cannot use traditionl completion structures or spinlocks as they rely on | ||
64 | * coherency. | ||
65 | */ | ||
66 | static DEFINE_PER_CPU_ALIGNED(int, per_cpu_sw_state); | ||
67 | |||
68 | static int per_cpu_sw_state_rd(u32 cpu) | ||
69 | { | ||
70 | sync_cache_r(SHIFT_PERCPU_PTR(&per_cpu_sw_state, per_cpu_offset(cpu))); | ||
71 | return per_cpu(per_cpu_sw_state, cpu); | ||
72 | } | ||
73 | |||
74 | static void per_cpu_sw_state_wr(u32 cpu, int val) | ||
75 | { | ||
76 | dmb(); | ||
77 | per_cpu(per_cpu_sw_state, cpu) = val; | ||
78 | sync_cache_w(SHIFT_PERCPU_PTR(&per_cpu_sw_state, per_cpu_offset(cpu))); | ||
79 | } | ||
80 | #else | ||
81 | static inline void per_cpu_sw_state_wr(u32 cpu, int val) { } | ||
82 | #endif | ||
83 | |||
84 | static void __iomem *pwr_ctrl_get_base(u32 cpu) | ||
85 | { | ||
86 | void __iomem *base = cpubiuctrl_block + cpu0_pwr_zone_ctrl_reg; | ||
87 | base += (cpu_logical_map(cpu) * 4); | ||
88 | return base; | ||
89 | } | ||
90 | |||
91 | static u32 pwr_ctrl_rd(u32 cpu) | ||
92 | { | ||
93 | void __iomem *base = pwr_ctrl_get_base(cpu); | ||
94 | return readl_relaxed(base); | ||
95 | } | ||
96 | |||
97 | static void pwr_ctrl_wr(u32 cpu, u32 val) | ||
98 | { | ||
99 | void __iomem *base = pwr_ctrl_get_base(cpu); | ||
100 | writel(val, base); | ||
101 | } | ||
102 | |||
103 | static void cpu_rst_cfg_set(u32 cpu, int set) | ||
104 | { | ||
105 | u32 val; | ||
106 | val = readl_relaxed(cpubiuctrl_block + cpu_rst_cfg_reg); | ||
107 | if (set) | ||
108 | val |= BIT(cpu_logical_map(cpu)); | ||
109 | else | ||
110 | val &= ~BIT(cpu_logical_map(cpu)); | ||
111 | writel_relaxed(val, cpubiuctrl_block + cpu_rst_cfg_reg); | ||
112 | } | ||
113 | |||
114 | static void cpu_set_boot_addr(u32 cpu, unsigned long boot_addr) | ||
115 | { | ||
116 | const int reg_ofs = cpu_logical_map(cpu) * 8; | ||
117 | writel_relaxed(0, hif_cont_block + hif_cont_reg + reg_ofs); | ||
118 | writel_relaxed(boot_addr, hif_cont_block + hif_cont_reg + 4 + reg_ofs); | ||
119 | } | ||
120 | |||
121 | static void brcmstb_cpu_boot(u32 cpu) | ||
122 | { | ||
123 | /* Mark this CPU as "up" */ | ||
124 | per_cpu_sw_state_wr(cpu, 1); | ||
125 | |||
126 | /* | ||
127 | * Set the reset vector to point to the secondary_startup | ||
128 | * routine | ||
129 | */ | ||
130 | cpu_set_boot_addr(cpu, virt_to_phys(brcmstb_secondary_startup)); | ||
131 | |||
132 | /* Unhalt the cpu */ | ||
133 | cpu_rst_cfg_set(cpu, 0); | ||
134 | } | ||
135 | |||
136 | static void brcmstb_cpu_power_on(u32 cpu) | ||
137 | { | ||
138 | /* | ||
139 | * The secondary cores power was cut, so we must go through | ||
140 | * power-on initialization. | ||
141 | */ | ||
142 | u32 tmp; | ||
143 | |||
144 | /* Request zone power up */ | ||
145 | pwr_ctrl_wr(cpu, ZONE_PWR_UP_REQ_MASK); | ||
146 | |||
147 | /* Wait for the power up FSM to complete */ | ||
148 | do { | ||
149 | tmp = pwr_ctrl_rd(cpu); | ||
150 | } while (!(tmp & ZONE_PWR_ON_STATE_MASK)); | ||
151 | } | ||
152 | |||
153 | static int brcmstb_cpu_get_power_state(u32 cpu) | ||
154 | { | ||
155 | int tmp = pwr_ctrl_rd(cpu); | ||
156 | return (tmp & ZONE_RESET_STATE_MASK) ? 0 : 1; | ||
157 | } | ||
158 | |||
159 | #ifdef CONFIG_HOTPLUG_CPU | ||
160 | |||
161 | static void brcmstb_cpu_die(u32 cpu) | ||
162 | { | ||
163 | v7_exit_coherency_flush(all); | ||
164 | |||
165 | per_cpu_sw_state_wr(cpu, 0); | ||
166 | |||
167 | /* Sit and wait to die */ | ||
168 | wfi(); | ||
169 | |||
170 | /* We should never get here... */ | ||
171 | while (1) | ||
172 | ; | ||
173 | } | ||
174 | |||
175 | static int brcmstb_cpu_kill(u32 cpu) | ||
176 | { | ||
177 | u32 tmp; | ||
178 | |||
179 | while (per_cpu_sw_state_rd(cpu)) | ||
180 | ; | ||
181 | |||
182 | /* Program zone reset */ | ||
183 | pwr_ctrl_wr(cpu, ZONE_RESET_STATE_MASK | ZONE_BLK_RST_ASSERT_MASK | | ||
184 | ZONE_PWR_DN_REQ_MASK); | ||
185 | |||
186 | /* Verify zone reset */ | ||
187 | tmp = pwr_ctrl_rd(cpu); | ||
188 | if (!(tmp & ZONE_RESET_STATE_MASK)) | ||
189 | pr_err("%s: Zone reset bit for CPU %d not asserted!\n", | ||
190 | __func__, cpu); | ||
191 | |||
192 | /* Wait for power down */ | ||
193 | do { | ||
194 | tmp = pwr_ctrl_rd(cpu); | ||
195 | } while (!(tmp & ZONE_PWR_OFF_STATE_MASK)); | ||
196 | |||
197 | /* Flush pipeline before resetting CPU */ | ||
198 | mb(); | ||
199 | |||
200 | /* Assert reset on the CPU */ | ||
201 | cpu_rst_cfg_set(cpu, 1); | ||
202 | |||
203 | return 1; | ||
204 | } | ||
205 | |||
206 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
207 | |||
208 | static int __init setup_hifcpubiuctrl_regs(struct device_node *np) | ||
209 | { | ||
210 | int rc = 0; | ||
211 | char *name; | ||
212 | struct device_node *syscon_np = NULL; | ||
213 | |||
214 | name = "syscon-cpu"; | ||
215 | |||
216 | syscon_np = of_parse_phandle(np, name, 0); | ||
217 | if (!syscon_np) { | ||
218 | pr_err("can't find phandle %s\n", name); | ||
219 | rc = -EINVAL; | ||
220 | goto cleanup; | ||
221 | } | ||
222 | |||
223 | cpubiuctrl_block = of_iomap(syscon_np, 0); | ||
224 | if (!cpubiuctrl_block) { | ||
225 | pr_err("iomap failed for cpubiuctrl_block\n"); | ||
226 | rc = -EINVAL; | ||
227 | goto cleanup; | ||
228 | } | ||
229 | |||
230 | rc = of_property_read_u32_index(np, name, CPU0_PWR_ZONE_CTRL_REG, | ||
231 | &cpu0_pwr_zone_ctrl_reg); | ||
232 | if (rc) { | ||
233 | pr_err("failed to read 1st entry from %s property (%d)\n", name, | ||
234 | rc); | ||
235 | rc = -EINVAL; | ||
236 | goto cleanup; | ||
237 | } | ||
238 | |||
239 | rc = of_property_read_u32_index(np, name, CPU_RESET_CONFIG_REG, | ||
240 | &cpu_rst_cfg_reg); | ||
241 | if (rc) { | ||
242 | pr_err("failed to read 2nd entry from %s property (%d)\n", name, | ||
243 | rc); | ||
244 | rc = -EINVAL; | ||
245 | goto cleanup; | ||
246 | } | ||
247 | |||
248 | cleanup: | ||
249 | of_node_put(syscon_np); | ||
250 | return rc; | ||
251 | } | ||
252 | |||
253 | static int __init setup_hifcont_regs(struct device_node *np) | ||
254 | { | ||
255 | int rc = 0; | ||
256 | char *name; | ||
257 | struct device_node *syscon_np = NULL; | ||
258 | |||
259 | name = "syscon-cont"; | ||
260 | |||
261 | syscon_np = of_parse_phandle(np, name, 0); | ||
262 | if (!syscon_np) { | ||
263 | pr_err("can't find phandle %s\n", name); | ||
264 | rc = -EINVAL; | ||
265 | goto cleanup; | ||
266 | } | ||
267 | |||
268 | hif_cont_block = of_iomap(syscon_np, 0); | ||
269 | if (!hif_cont_block) { | ||
270 | pr_err("iomap failed for hif_cont_block\n"); | ||
271 | rc = -EINVAL; | ||
272 | goto cleanup; | ||
273 | } | ||
274 | |||
275 | /* Offset is at top of hif_cont_block */ | ||
276 | hif_cont_reg = 0; | ||
277 | |||
278 | cleanup: | ||
279 | of_node_put(syscon_np); | ||
280 | return rc; | ||
281 | } | ||
282 | |||
283 | static void __init brcmstb_cpu_ctrl_setup(unsigned int max_cpus) | ||
284 | { | ||
285 | int rc; | ||
286 | struct device_node *np; | ||
287 | char *name; | ||
288 | |||
289 | name = "brcm,brcmstb-smpboot"; | ||
290 | np = of_find_compatible_node(NULL, NULL, name); | ||
291 | if (!np) { | ||
292 | pr_err("can't find compatible node %s\n", name); | ||
293 | return; | ||
294 | } | ||
295 | |||
296 | rc = setup_hifcpubiuctrl_regs(np); | ||
297 | if (rc) | ||
298 | return; | ||
299 | |||
300 | rc = setup_hifcont_regs(np); | ||
301 | if (rc) | ||
302 | return; | ||
303 | } | ||
304 | |||
305 | static int brcmstb_boot_secondary(unsigned int cpu, struct task_struct *idle) | ||
306 | { | ||
307 | /* Missing the brcm,brcmstb-smpboot DT node? */ | ||
308 | if (!cpubiuctrl_block || !hif_cont_block) | ||
309 | return -ENODEV; | ||
310 | |||
311 | /* Bring up power to the core if necessary */ | ||
312 | if (brcmstb_cpu_get_power_state(cpu) == 0) | ||
313 | brcmstb_cpu_power_on(cpu); | ||
314 | |||
315 | brcmstb_cpu_boot(cpu); | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static struct smp_operations brcmstb_smp_ops __initdata = { | ||
321 | .smp_prepare_cpus = brcmstb_cpu_ctrl_setup, | ||
322 | .smp_boot_secondary = brcmstb_boot_secondary, | ||
323 | #ifdef CONFIG_HOTPLUG_CPU | ||
324 | .cpu_kill = brcmstb_cpu_kill, | ||
325 | .cpu_die = brcmstb_cpu_die, | ||
326 | #endif | ||
327 | }; | ||
328 | |||
329 | CPU_METHOD_OF_DECLARE(brcmstb_smp, "brcm,brahma-b15", &brcmstb_smp_ops); | ||
diff --git a/arch/arm/mach-berlin/Kconfig b/arch/arm/mach-berlin/Kconfig index 24f85be71671..3e40a947f3ea 100644 --- a/arch/arm/mach-berlin/Kconfig +++ b/arch/arm/mach-berlin/Kconfig | |||
@@ -1,10 +1,11 @@ | |||
1 | menuconfig ARCH_BERLIN | 1 | menuconfig ARCH_BERLIN |
2 | bool "Marvell Berlin SoCs" if ARCH_MULTI_V7 | 2 | bool "Marvell Berlin SoCs" if ARCH_MULTI_V7 |
3 | select ARCH_HAS_RESET_CONTROLLER | ||
3 | select ARCH_REQUIRE_GPIOLIB | 4 | select ARCH_REQUIRE_GPIOLIB |
4 | select ARM_GIC | 5 | select ARM_GIC |
5 | select GENERIC_IRQ_CHIP | ||
6 | select DW_APB_ICTL | 6 | select DW_APB_ICTL |
7 | select DW_APB_TIMER_OF | 7 | select DW_APB_TIMER_OF |
8 | select GENERIC_IRQ_CHIP | ||
8 | select PINCTRL | 9 | select PINCTRL |
9 | 10 | ||
10 | if ARCH_BERLIN | 11 | if ARCH_BERLIN |
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 2d0240f241b8..b9e3f1c61baf 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig | |||
@@ -24,6 +24,7 @@ menuconfig ARCH_EXYNOS | |||
24 | select PM_GENERIC_DOMAINS if PM_RUNTIME | 24 | select PM_GENERIC_DOMAINS if PM_RUNTIME |
25 | select S5P_DEV_MFC | 25 | select S5P_DEV_MFC |
26 | select SRAM | 26 | select SRAM |
27 | select MFD_SYSCON | ||
27 | help | 28 | help |
28 | Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5) | 29 | Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5) |
29 | 30 | ||
@@ -75,6 +76,11 @@ config SOC_EXYNOS4412 | |||
75 | default y | 76 | default y |
76 | depends on ARCH_EXYNOS4 | 77 | depends on ARCH_EXYNOS4 |
77 | 78 | ||
79 | config SOC_EXYNOS4415 | ||
80 | bool "SAMSUNG EXYNOS4415" | ||
81 | default y | ||
82 | depends on ARCH_EXYNOS4 | ||
83 | |||
78 | config SOC_EXYNOS5250 | 84 | config SOC_EXYNOS5250 |
79 | bool "SAMSUNG EXYNOS5250" | 85 | bool "SAMSUNG EXYNOS5250" |
80 | default y | 86 | default y |
@@ -123,4 +129,9 @@ config EXYNOS5420_MCPM | |||
123 | This is needed to provide CPU and cluster power management | 129 | This is needed to provide CPU and cluster power management |
124 | on Exynos5420 implementing big.LITTLE. | 130 | on Exynos5420 implementing big.LITTLE. |
125 | 131 | ||
132 | config EXYNOS_CPU_SUSPEND | ||
133 | bool | ||
134 | select ARM_CPU_SUSPEND | ||
135 | default PM_SLEEP || ARM_EXYNOS_CPUIDLE | ||
136 | |||
126 | endif | 137 | endif |
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index d634de588d96..bcefb5473ee4 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile | |||
@@ -11,13 +11,15 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include -I$(srctree) | |||
11 | 11 | ||
12 | obj-$(CONFIG_ARCH_EXYNOS) += exynos.o pmu.o exynos-smc.o firmware.o | 12 | obj-$(CONFIG_ARCH_EXYNOS) += exynos.o pmu.o exynos-smc.o firmware.o |
13 | 13 | ||
14 | obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o | 14 | obj-$(CONFIG_EXYNOS_CPU_SUSPEND) += pm.o sleep.o |
15 | obj-$(CONFIG_PM_SLEEP) += suspend.o | ||
15 | obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o | 16 | obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o |
16 | 17 | ||
17 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 18 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
18 | 19 | ||
19 | plus_sec := $(call as-instr,.arch_extension sec,+sec) | 20 | plus_sec := $(call as-instr,.arch_extension sec,+sec) |
20 | AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec) | 21 | AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec) |
22 | AFLAGS_sleep.o :=-Wa,-march=armv7-a$(plus_sec) | ||
21 | 23 | ||
22 | obj-$(CONFIG_EXYNOS5420_MCPM) += mcpm-exynos.o | 24 | obj-$(CONFIG_EXYNOS5420_MCPM) += mcpm-exynos.o |
23 | CFLAGS_mcpm-exynos.o += -march=armv7-a | 25 | CFLAGS_mcpm-exynos.o += -march=armv7-a |
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index 3d3e6af9d015..865f878063cc 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h | |||
@@ -12,7 +12,6 @@ | |||
12 | #ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H | 12 | #ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H |
13 | #define __ARCH_ARM_MACH_EXYNOS_COMMON_H | 13 | #define __ARCH_ARM_MACH_EXYNOS_COMMON_H |
14 | 14 | ||
15 | #include <linux/reboot.h> | ||
16 | #include <linux/of.h> | 15 | #include <linux/of.h> |
17 | 16 | ||
18 | #define EXYNOS3250_SOC_ID 0xE3472000 | 17 | #define EXYNOS3250_SOC_ID 0xE3472000 |
@@ -111,11 +110,19 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK) | |||
111 | #define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \ | 110 | #define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \ |
112 | soc_is_exynos5420() || soc_is_exynos5800()) | 111 | soc_is_exynos5420() || soc_is_exynos5800()) |
113 | 112 | ||
113 | extern u32 cp15_save_diag; | ||
114 | extern u32 cp15_save_power; | ||
115 | |||
114 | extern void __iomem *sysram_ns_base_addr; | 116 | extern void __iomem *sysram_ns_base_addr; |
115 | extern void __iomem *sysram_base_addr; | 117 | extern void __iomem *sysram_base_addr; |
116 | extern void __iomem *pmu_base_addr; | 118 | extern void __iomem *pmu_base_addr; |
117 | void exynos_sysram_init(void); | 119 | void exynos_sysram_init(void); |
118 | 120 | ||
121 | enum { | ||
122 | FW_DO_IDLE_SLEEP, | ||
123 | FW_DO_IDLE_AFTR, | ||
124 | }; | ||
125 | |||
119 | void exynos_firmware_init(void); | 126 | void exynos_firmware_init(void); |
120 | 127 | ||
121 | extern u32 exynos_get_eint_wake_mask(void); | 128 | extern u32 exynos_get_eint_wake_mask(void); |
@@ -127,32 +134,20 @@ static inline void exynos_pm_init(void) {} | |||
127 | #endif | 134 | #endif |
128 | 135 | ||
129 | extern void exynos_cpu_resume(void); | 136 | extern void exynos_cpu_resume(void); |
137 | extern void exynos_cpu_resume_ns(void); | ||
130 | 138 | ||
131 | extern struct smp_operations exynos_smp_ops; | 139 | extern struct smp_operations exynos_smp_ops; |
132 | 140 | ||
133 | /* PMU(Power Management Unit) support */ | ||
134 | |||
135 | #define PMU_TABLE_END (-1U) | ||
136 | |||
137 | enum sys_powerdown { | ||
138 | SYS_AFTR, | ||
139 | SYS_LPA, | ||
140 | SYS_SLEEP, | ||
141 | NUM_SYS_POWERDOWN, | ||
142 | }; | ||
143 | |||
144 | struct exynos_pmu_conf { | ||
145 | unsigned int offset; | ||
146 | unsigned int val[NUM_SYS_POWERDOWN]; | ||
147 | }; | ||
148 | |||
149 | extern void exynos_sys_powerdown_conf(enum sys_powerdown mode); | ||
150 | extern void exynos_cpu_power_down(int cpu); | 141 | extern void exynos_cpu_power_down(int cpu); |
151 | extern void exynos_cpu_power_up(int cpu); | 142 | extern void exynos_cpu_power_up(int cpu); |
152 | extern int exynos_cpu_power_state(int cpu); | 143 | extern int exynos_cpu_power_state(int cpu); |
153 | extern void exynos_cluster_power_down(int cluster); | 144 | extern void exynos_cluster_power_down(int cluster); |
154 | extern void exynos_cluster_power_up(int cluster); | 145 | extern void exynos_cluster_power_up(int cluster); |
155 | extern int exynos_cluster_power_state(int cluster); | 146 | extern int exynos_cluster_power_state(int cluster); |
147 | extern void exynos_cpu_save_register(void); | ||
148 | extern void exynos_cpu_restore_register(void); | ||
149 | extern void exynos_pm_central_suspend(void); | ||
150 | extern int exynos_pm_central_resume(void); | ||
156 | extern void exynos_enter_aftr(void); | 151 | extern void exynos_enter_aftr(void); |
157 | 152 | ||
158 | extern void s5p_init_cpu(void __iomem *cpuid_addr); | 153 | extern void s5p_init_cpu(void __iomem *cpuid_addr); |
diff --git a/arch/arm/mach-exynos/exynos-pmu.h b/arch/arm/mach-exynos/exynos-pmu.h new file mode 100644 index 000000000000..a2ab0d52b230 --- /dev/null +++ b/arch/arm/mach-exynos/exynos-pmu.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com | ||
4 | * | ||
5 | * Header for EXYNOS PMU Driver support | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef __EXYNOS_PMU_H | ||
13 | #define __EXYNOS_PMU_H | ||
14 | |||
15 | enum sys_powerdown { | ||
16 | SYS_AFTR, | ||
17 | SYS_LPA, | ||
18 | SYS_SLEEP, | ||
19 | NUM_SYS_POWERDOWN, | ||
20 | }; | ||
21 | |||
22 | extern void exynos_sys_powerdown_conf(enum sys_powerdown mode); | ||
23 | |||
24 | #endif /* __EXYNOS_PMU_H */ | ||
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index 6de7cf5ef2b2..c13d0837fa8c 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c | |||
@@ -87,28 +87,6 @@ static struct map_desc exynos5_iodesc[] __initdata = { | |||
87 | }, | 87 | }, |
88 | }; | 88 | }; |
89 | 89 | ||
90 | static void exynos_restart(enum reboot_mode mode, const char *cmd) | ||
91 | { | ||
92 | struct device_node *np; | ||
93 | u32 val = 0x1; | ||
94 | void __iomem *addr = pmu_base_addr + EXYNOS_SWRESET; | ||
95 | |||
96 | if (of_machine_is_compatible("samsung,exynos5440")) { | ||
97 | u32 status; | ||
98 | np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock"); | ||
99 | |||
100 | addr = of_iomap(np, 0) + 0xbc; | ||
101 | status = __raw_readl(addr); | ||
102 | |||
103 | addr = of_iomap(np, 0) + 0xcc; | ||
104 | val = __raw_readl(addr); | ||
105 | |||
106 | val = (val & 0xffff0000) | (status & 0xffff); | ||
107 | } | ||
108 | |||
109 | __raw_writel(val, addr); | ||
110 | } | ||
111 | |||
112 | static struct platform_device exynos_cpuidle = { | 90 | static struct platform_device exynos_cpuidle = { |
113 | .name = "exynos_cpuidle", | 91 | .name = "exynos_cpuidle", |
114 | #ifdef CONFIG_ARM_EXYNOS_CPUIDLE | 92 | #ifdef CONFIG_ARM_EXYNOS_CPUIDLE |
@@ -202,6 +180,7 @@ static const struct of_device_id exynos_dt_pmu_match[] = { | |||
202 | { .compatible = "samsung,exynos4210-pmu" }, | 180 | { .compatible = "samsung,exynos4210-pmu" }, |
203 | { .compatible = "samsung,exynos4212-pmu" }, | 181 | { .compatible = "samsung,exynos4212-pmu" }, |
204 | { .compatible = "samsung,exynos4412-pmu" }, | 182 | { .compatible = "samsung,exynos4412-pmu" }, |
183 | { .compatible = "samsung,exynos4415-pmu" }, | ||
205 | { .compatible = "samsung,exynos5250-pmu" }, | 184 | { .compatible = "samsung,exynos5250-pmu" }, |
206 | { .compatible = "samsung,exynos5260-pmu" }, | 185 | { .compatible = "samsung,exynos5260-pmu" }, |
207 | { .compatible = "samsung,exynos5410-pmu" }, | 186 | { .compatible = "samsung,exynos5410-pmu" }, |
@@ -268,7 +247,10 @@ static void __init exynos_dt_machine_init(void) | |||
268 | exynos_sysram_init(); | 247 | exynos_sysram_init(); |
269 | 248 | ||
270 | if (of_machine_is_compatible("samsung,exynos4210") || | 249 | if (of_machine_is_compatible("samsung,exynos4210") || |
271 | of_machine_is_compatible("samsung,exynos5250")) | 250 | of_machine_is_compatible("samsung,exynos4212") || |
251 | (of_machine_is_compatible("samsung,exynos4412") && | ||
252 | of_machine_is_compatible("samsung,trats2")) || | ||
253 | of_machine_is_compatible("samsung,exynos5250")) | ||
272 | platform_device_register(&exynos_cpuidle); | 254 | platform_device_register(&exynos_cpuidle); |
273 | 255 | ||
274 | platform_device_register_simple("exynos-cpufreq", -1, NULL, 0); | 256 | platform_device_register_simple("exynos-cpufreq", -1, NULL, 0); |
@@ -283,6 +265,7 @@ static char const *exynos_dt_compat[] __initconst = { | |||
283 | "samsung,exynos4210", | 265 | "samsung,exynos4210", |
284 | "samsung,exynos4212", | 266 | "samsung,exynos4212", |
285 | "samsung,exynos4412", | 267 | "samsung,exynos4412", |
268 | "samsung,exynos4415", | ||
286 | "samsung,exynos5", | 269 | "samsung,exynos5", |
287 | "samsung,exynos5250", | 270 | "samsung,exynos5250", |
288 | "samsung,exynos5260", | 271 | "samsung,exynos5260", |
@@ -328,7 +311,6 @@ DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)") | |||
328 | .init_machine = exynos_dt_machine_init, | 311 | .init_machine = exynos_dt_machine_init, |
329 | .init_late = exynos_init_late, | 312 | .init_late = exynos_init_late, |
330 | .dt_compat = exynos_dt_compat, | 313 | .dt_compat = exynos_dt_compat, |
331 | .restart = exynos_restart, | ||
332 | .reserve = exynos_reserve, | 314 | .reserve = exynos_reserve, |
333 | .dt_fixup = exynos_dt_fixup, | 315 | .dt_fixup = exynos_dt_fixup, |
334 | MACHINE_END | 316 | MACHINE_END |
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c index e8797bb78871..766f57d2f029 100644 --- a/arch/arm/mach-exynos/firmware.c +++ b/arch/arm/mach-exynos/firmware.c | |||
@@ -14,16 +14,44 @@ | |||
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
16 | 16 | ||
17 | #include <asm/cacheflush.h> | ||
18 | #include <asm/cputype.h> | ||
17 | #include <asm/firmware.h> | 19 | #include <asm/firmware.h> |
20 | #include <asm/suspend.h> | ||
18 | 21 | ||
19 | #include <mach/map.h> | 22 | #include <mach/map.h> |
20 | 23 | ||
21 | #include "common.h" | 24 | #include "common.h" |
22 | #include "smc.h" | 25 | #include "smc.h" |
23 | 26 | ||
24 | static int exynos_do_idle(void) | 27 | #define EXYNOS_SLEEP_MAGIC 0x00000bad |
28 | #define EXYNOS_AFTR_MAGIC 0xfcba0d10 | ||
29 | #define EXYNOS_BOOT_ADDR 0x8 | ||
30 | #define EXYNOS_BOOT_FLAG 0xc | ||
31 | |||
32 | static void exynos_save_cp15(void) | ||
25 | { | 33 | { |
26 | exynos_smc(SMC_CMD_SLEEP, 0, 0, 0); | 34 | /* Save Power control and Diagnostic registers */ |
35 | asm ("mrc p15, 0, %0, c15, c0, 0\n" | ||
36 | "mrc p15, 0, %1, c15, c0, 1\n" | ||
37 | : "=r" (cp15_save_power), "=r" (cp15_save_diag) | ||
38 | : : "cc"); | ||
39 | } | ||
40 | |||
41 | static int exynos_do_idle(unsigned long mode) | ||
42 | { | ||
43 | switch (mode) { | ||
44 | case FW_DO_IDLE_AFTR: | ||
45 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) | ||
46 | exynos_save_cp15(); | ||
47 | __raw_writel(virt_to_phys(exynos_cpu_resume_ns), | ||
48 | sysram_ns_base_addr + 0x24); | ||
49 | __raw_writel(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20); | ||
50 | exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0); | ||
51 | break; | ||
52 | case FW_DO_IDLE_SLEEP: | ||
53 | exynos_smc(SMC_CMD_SLEEP, 0, 0, 0); | ||
54 | } | ||
27 | return 0; | 55 | return 0; |
28 | } | 56 | } |
29 | 57 | ||
@@ -69,10 +97,43 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr) | |||
69 | return 0; | 97 | return 0; |
70 | } | 98 | } |
71 | 99 | ||
100 | static int exynos_cpu_suspend(unsigned long arg) | ||
101 | { | ||
102 | flush_cache_all(); | ||
103 | outer_flush_all(); | ||
104 | |||
105 | exynos_smc(SMC_CMD_SLEEP, 0, 0, 0); | ||
106 | |||
107 | pr_info("Failed to suspend the system\n"); | ||
108 | writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG); | ||
109 | return 1; | ||
110 | } | ||
111 | |||
112 | static int exynos_suspend(void) | ||
113 | { | ||
114 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) | ||
115 | exynos_save_cp15(); | ||
116 | |||
117 | writel(EXYNOS_SLEEP_MAGIC, sysram_ns_base_addr + EXYNOS_BOOT_FLAG); | ||
118 | writel(virt_to_phys(exynos_cpu_resume_ns), | ||
119 | sysram_ns_base_addr + EXYNOS_BOOT_ADDR); | ||
120 | |||
121 | return cpu_suspend(0, exynos_cpu_suspend); | ||
122 | } | ||
123 | |||
124 | static int exynos_resume(void) | ||
125 | { | ||
126 | writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
72 | static const struct firmware_ops exynos_firmware_ops = { | 131 | static const struct firmware_ops exynos_firmware_ops = { |
73 | .do_idle = exynos_do_idle, | 132 | .do_idle = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL, |
74 | .set_cpu_boot_addr = exynos_set_cpu_boot_addr, | 133 | .set_cpu_boot_addr = exynos_set_cpu_boot_addr, |
75 | .cpu_boot = exynos_cpu_boot, | 134 | .cpu_boot = exynos_cpu_boot, |
135 | .suspend = IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL, | ||
136 | .resume = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL, | ||
76 | }; | 137 | }; |
77 | 138 | ||
78 | void __init exynos_firmware_init(void) | 139 | void __init exynos_firmware_init(void) |
diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c index dc9a764a7c37..b0d3c2e876fb 100644 --- a/arch/arm/mach-exynos/mcpm-exynos.c +++ b/arch/arm/mach-exynos/mcpm-exynos.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/of_address.h> | 17 | #include <linux/of_address.h> |
18 | #include <linux/syscore_ops.h> | ||
18 | 19 | ||
19 | #include <asm/cputype.h> | 20 | #include <asm/cputype.h> |
20 | #include <asm/cp15.h> | 21 | #include <asm/cp15.h> |
@@ -30,6 +31,8 @@ | |||
30 | #define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29) | 31 | #define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29) |
31 | #define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30) | 32 | #define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30) |
32 | 33 | ||
34 | static void __iomem *ns_sram_base_addr; | ||
35 | |||
33 | /* | 36 | /* |
34 | * The common v7_exit_coherency_flush API could not be used because of the | 37 | * The common v7_exit_coherency_flush API could not be used because of the |
35 | * Erratum 799270 workaround. This macro is the same as the common one (in | 38 | * Erratum 799270 workaround. This macro is the same as the common one (in |
@@ -318,10 +321,26 @@ static const struct of_device_id exynos_dt_mcpm_match[] = { | |||
318 | {}, | 321 | {}, |
319 | }; | 322 | }; |
320 | 323 | ||
324 | static void exynos_mcpm_setup_entry_point(void) | ||
325 | { | ||
326 | /* | ||
327 | * U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr | ||
328 | * as part of secondary_cpu_start(). Let's redirect it to the | ||
329 | * mcpm_entry_point(). This is done during both secondary boot-up as | ||
330 | * well as system resume. | ||
331 | */ | ||
332 | __raw_writel(0xe59f0000, ns_sram_base_addr); /* ldr r0, [pc, #0] */ | ||
333 | __raw_writel(0xe12fff10, ns_sram_base_addr + 4); /* bx r0 */ | ||
334 | __raw_writel(virt_to_phys(mcpm_entry_point), ns_sram_base_addr + 8); | ||
335 | } | ||
336 | |||
337 | static struct syscore_ops exynos_mcpm_syscore_ops = { | ||
338 | .resume = exynos_mcpm_setup_entry_point, | ||
339 | }; | ||
340 | |||
321 | static int __init exynos_mcpm_init(void) | 341 | static int __init exynos_mcpm_init(void) |
322 | { | 342 | { |
323 | struct device_node *node; | 343 | struct device_node *node; |
324 | void __iomem *ns_sram_base_addr; | ||
325 | unsigned int value, i; | 344 | unsigned int value, i; |
326 | int ret; | 345 | int ret; |
327 | 346 | ||
@@ -387,16 +406,9 @@ static int __init exynos_mcpm_init(void) | |||
387 | pmu_raw_writel(value, EXYNOS_COMMON_OPTION(i)); | 406 | pmu_raw_writel(value, EXYNOS_COMMON_OPTION(i)); |
388 | } | 407 | } |
389 | 408 | ||
390 | /* | 409 | exynos_mcpm_setup_entry_point(); |
391 | * U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr | ||
392 | * as part of secondary_cpu_start(). Let's redirect it to the | ||
393 | * mcpm_entry_point(). | ||
394 | */ | ||
395 | __raw_writel(0xe59f0000, ns_sram_base_addr); /* ldr r0, [pc, #0] */ | ||
396 | __raw_writel(0xe12fff10, ns_sram_base_addr + 4); /* bx r0 */ | ||
397 | __raw_writel(virt_to_phys(mcpm_entry_point), ns_sram_base_addr + 8); | ||
398 | 410 | ||
399 | iounmap(ns_sram_base_addr); | 411 | register_syscore_ops(&exynos_mcpm_syscore_ops); |
400 | 412 | ||
401 | return ret; | 413 | return ret; |
402 | } | 414 | } |
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 9c6dd1451136..7a1ebfeeeeb8 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c | |||
@@ -126,6 +126,18 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious) | |||
126 | */ | 126 | */ |
127 | void exynos_cpu_power_down(int cpu) | 127 | void exynos_cpu_power_down(int cpu) |
128 | { | 128 | { |
129 | if (cpu == 0 && (of_machine_is_compatible("samsung,exynos5420") || | ||
130 | of_machine_is_compatible("samsung,exynos5800"))) { | ||
131 | /* | ||
132 | * Bypass power down for CPU0 during suspend. Check for | ||
133 | * the SYS_PWR_REG value to decide if we are suspending | ||
134 | * the system. | ||
135 | */ | ||
136 | int val = pmu_raw_readl(EXYNOS5_ARM_CORE0_SYS_PWR_REG); | ||
137 | |||
138 | if (!(val & S5P_CORE_LOCAL_PWR_EN)) | ||
139 | return; | ||
140 | } | ||
129 | pmu_raw_writel(0, EXYNOS_ARM_CORE_CONFIGURATION(cpu)); | 141 | pmu_raw_writel(0, EXYNOS_ARM_CORE_CONFIGURATION(cpu)); |
130 | } | 142 | } |
131 | 143 | ||
@@ -204,6 +216,26 @@ static inline void __iomem *cpu_boot_reg(int cpu) | |||
204 | } | 216 | } |
205 | 217 | ||
206 | /* | 218 | /* |
219 | * Set wake up by local power mode and execute software reset for given core. | ||
220 | * | ||
221 | * Currently this is needed only when booting secondary CPU on Exynos3250. | ||
222 | */ | ||
223 | static void exynos_core_restart(u32 core_id) | ||
224 | { | ||
225 | u32 val; | ||
226 | |||
227 | if (!of_machine_is_compatible("samsung,exynos3250")) | ||
228 | return; | ||
229 | |||
230 | val = pmu_raw_readl(EXYNOS_ARM_CORE_STATUS(core_id)); | ||
231 | val |= S5P_CORE_WAKEUP_FROM_LOCAL_CFG; | ||
232 | pmu_raw_writel(val, EXYNOS_ARM_CORE_STATUS(core_id)); | ||
233 | |||
234 | pr_info("CPU%u: Software reset\n", core_id); | ||
235 | pmu_raw_writel(EXYNOS_CORE_PO_RESET(core_id), EXYNOS_SWRESET); | ||
236 | } | ||
237 | |||
238 | /* | ||
207 | * Write pen_release in a way that is guaranteed to be visible to all | 239 | * Write pen_release in a way that is guaranteed to be visible to all |
208 | * observers, irrespective of whether they're taking part in coherency | 240 | * observers, irrespective of whether they're taking part in coherency |
209 | * or not. This is necessary for the hotplug code to work reliably. | 241 | * or not. This is necessary for the hotplug code to work reliably. |
@@ -279,6 +311,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
279 | return -ETIMEDOUT; | 311 | return -ETIMEDOUT; |
280 | } | 312 | } |
281 | } | 313 | } |
314 | |||
315 | exynos_core_restart(core_id); | ||
316 | |||
282 | /* | 317 | /* |
283 | * Send the secondary CPU a soft interrupt, thereby causing | 318 | * Send the secondary CPU a soft interrupt, thereby causing |
284 | * the boot monitor to read the system wide flags register, | 319 | * the boot monitor to read the system wide flags register, |
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index abefacb45976..86f3ecd88f78 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. | 2 | * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. |
3 | * http://www.samsung.com | 3 | * http://www.samsung.com |
4 | * | 4 | * |
5 | * EXYNOS - Power Management support | 5 | * EXYNOS - Power Management support |
@@ -15,109 +15,45 @@ | |||
15 | 15 | ||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/suspend.h> | 17 | #include <linux/suspend.h> |
18 | #include <linux/syscore_ops.h> | ||
19 | #include <linux/cpu_pm.h> | 18 | #include <linux/cpu_pm.h> |
20 | #include <linux/io.h> | 19 | #include <linux/io.h> |
21 | #include <linux/irqchip/arm-gic.h> | ||
22 | #include <linux/err.h> | 20 | #include <linux/err.h> |
23 | #include <linux/clk.h> | ||
24 | 21 | ||
25 | #include <asm/cacheflush.h> | 22 | #include <asm/firmware.h> |
26 | #include <asm/hardware/cache-l2x0.h> | ||
27 | #include <asm/smp_scu.h> | 23 | #include <asm/smp_scu.h> |
28 | #include <asm/suspend.h> | 24 | #include <asm/suspend.h> |
29 | 25 | ||
30 | #include <plat/pm-common.h> | 26 | #include <plat/pm-common.h> |
31 | #include <plat/regs-srom.h> | ||
32 | |||
33 | #include <mach/map.h> | ||
34 | 27 | ||
35 | #include "common.h" | 28 | #include "common.h" |
29 | #include "exynos-pmu.h" | ||
36 | #include "regs-pmu.h" | 30 | #include "regs-pmu.h" |
37 | #include "regs-sys.h" | 31 | #include "regs-sys.h" |
38 | 32 | ||
39 | /** | 33 | static inline void __iomem *exynos_boot_vector_addr(void) |
40 | * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping | ||
41 | * @hwirq: Hardware IRQ signal of the GIC | ||
42 | * @mask: Mask in PMU wake-up mask register | ||
43 | */ | ||
44 | struct exynos_wkup_irq { | ||
45 | unsigned int hwirq; | ||
46 | u32 mask; | ||
47 | }; | ||
48 | |||
49 | static struct sleep_save exynos5_sys_save[] = { | ||
50 | SAVE_ITEM(EXYNOS5_SYS_I2C_CFG), | ||
51 | }; | ||
52 | |||
53 | static struct sleep_save exynos_core_save[] = { | ||
54 | /* SROM side */ | ||
55 | SAVE_ITEM(S5P_SROM_BW), | ||
56 | SAVE_ITEM(S5P_SROM_BC0), | ||
57 | SAVE_ITEM(S5P_SROM_BC1), | ||
58 | SAVE_ITEM(S5P_SROM_BC2), | ||
59 | SAVE_ITEM(S5P_SROM_BC3), | ||
60 | }; | ||
61 | |||
62 | /* | ||
63 | * GIC wake-up support | ||
64 | */ | ||
65 | |||
66 | static u32 exynos_irqwake_intmask = 0xffffffff; | ||
67 | |||
68 | static const struct exynos_wkup_irq exynos4_wkup_irq[] = { | ||
69 | { 76, BIT(1) }, /* RTC alarm */ | ||
70 | { 77, BIT(2) }, /* RTC tick */ | ||
71 | { /* sentinel */ }, | ||
72 | }; | ||
73 | |||
74 | static const struct exynos_wkup_irq exynos5250_wkup_irq[] = { | ||
75 | { 75, BIT(1) }, /* RTC alarm */ | ||
76 | { 76, BIT(2) }, /* RTC tick */ | ||
77 | { /* sentinel */ }, | ||
78 | }; | ||
79 | |||
80 | static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) | ||
81 | { | 34 | { |
82 | const struct exynos_wkup_irq *wkup_irq; | 35 | if (samsung_rev() == EXYNOS4210_REV_1_1) |
83 | 36 | return pmu_base_addr + S5P_INFORM7; | |
84 | if (soc_is_exynos5250()) | 37 | else if (samsung_rev() == EXYNOS4210_REV_1_0) |
85 | wkup_irq = exynos5250_wkup_irq; | 38 | return sysram_base_addr + 0x24; |
86 | else | 39 | return pmu_base_addr + S5P_INFORM0; |
87 | wkup_irq = exynos4_wkup_irq; | ||
88 | |||
89 | while (wkup_irq->mask) { | ||
90 | if (wkup_irq->hwirq == data->hwirq) { | ||
91 | if (!state) | ||
92 | exynos_irqwake_intmask |= wkup_irq->mask; | ||
93 | else | ||
94 | exynos_irqwake_intmask &= ~wkup_irq->mask; | ||
95 | return 0; | ||
96 | } | ||
97 | ++wkup_irq; | ||
98 | } | ||
99 | |||
100 | return -ENOENT; | ||
101 | } | 40 | } |
102 | 41 | ||
103 | #define EXYNOS_BOOT_VECTOR_ADDR (samsung_rev() == EXYNOS4210_REV_1_1 ? \ | 42 | static inline void __iomem *exynos_boot_vector_flag(void) |
104 | pmu_base_addr + S5P_INFORM7 : \ | 43 | { |
105 | (samsung_rev() == EXYNOS4210_REV_1_0 ? \ | 44 | if (samsung_rev() == EXYNOS4210_REV_1_1) |
106 | (sysram_base_addr + 0x24) : \ | 45 | return pmu_base_addr + S5P_INFORM6; |
107 | pmu_base_addr + S5P_INFORM0)) | 46 | else if (samsung_rev() == EXYNOS4210_REV_1_0) |
108 | #define EXYNOS_BOOT_VECTOR_FLAG (samsung_rev() == EXYNOS4210_REV_1_1 ? \ | 47 | return sysram_base_addr + 0x20; |
109 | pmu_base_addr + S5P_INFORM6 : \ | 48 | return pmu_base_addr + S5P_INFORM1; |
110 | (samsung_rev() == EXYNOS4210_REV_1_0 ? \ | 49 | } |
111 | (sysram_base_addr + 0x20) : \ | ||
112 | pmu_base_addr + S5P_INFORM1)) | ||
113 | 50 | ||
114 | #define S5P_CHECK_AFTR 0xFCBA0D10 | 51 | #define S5P_CHECK_AFTR 0xFCBA0D10 |
115 | #define S5P_CHECK_SLEEP 0x00000BAD | ||
116 | 52 | ||
117 | /* For Cortex-A9 Diagnostic and Power control register */ | 53 | /* For Cortex-A9 Diagnostic and Power control register */ |
118 | static unsigned int save_arm_register[2]; | 54 | static unsigned int save_arm_register[2]; |
119 | 55 | ||
120 | static void exynos_cpu_save_register(void) | 56 | void exynos_cpu_save_register(void) |
121 | { | 57 | { |
122 | unsigned long tmp; | 58 | unsigned long tmp; |
123 | 59 | ||
@@ -134,7 +70,7 @@ static void exynos_cpu_save_register(void) | |||
134 | save_arm_register[1] = tmp; | 70 | save_arm_register[1] = tmp; |
135 | } | 71 | } |
136 | 72 | ||
137 | static void exynos_cpu_restore_register(void) | 73 | void exynos_cpu_restore_register(void) |
138 | { | 74 | { |
139 | unsigned long tmp; | 75 | unsigned long tmp; |
140 | 76 | ||
@@ -153,7 +89,7 @@ static void exynos_cpu_restore_register(void) | |||
153 | : "cc"); | 89 | : "cc"); |
154 | } | 90 | } |
155 | 91 | ||
156 | static void exynos_pm_central_suspend(void) | 92 | void exynos_pm_central_suspend(void) |
157 | { | 93 | { |
158 | unsigned long tmp; | 94 | unsigned long tmp; |
159 | 95 | ||
@@ -161,9 +97,13 @@ static void exynos_pm_central_suspend(void) | |||
161 | tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); | 97 | tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); |
162 | tmp &= ~S5P_CENTRAL_LOWPWR_CFG; | 98 | tmp &= ~S5P_CENTRAL_LOWPWR_CFG; |
163 | pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); | 99 | pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); |
100 | |||
101 | /* Setting SEQ_OPTION register */ | ||
102 | pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0, | ||
103 | S5P_CENTRAL_SEQ_OPTION); | ||
164 | } | 104 | } |
165 | 105 | ||
166 | static int exynos_pm_central_resume(void) | 106 | int exynos_pm_central_resume(void) |
167 | { | 107 | { |
168 | unsigned long tmp; | 108 | unsigned long tmp; |
169 | 109 | ||
@@ -194,17 +134,26 @@ static void exynos_set_wakeupmask(long mask) | |||
194 | 134 | ||
195 | static void exynos_cpu_set_boot_vector(long flags) | 135 | static void exynos_cpu_set_boot_vector(long flags) |
196 | { | 136 | { |
197 | __raw_writel(virt_to_phys(exynos_cpu_resume), EXYNOS_BOOT_VECTOR_ADDR); | 137 | __raw_writel(virt_to_phys(exynos_cpu_resume), |
198 | __raw_writel(flags, EXYNOS_BOOT_VECTOR_FLAG); | 138 | exynos_boot_vector_addr()); |
139 | __raw_writel(flags, exynos_boot_vector_flag()); | ||
199 | } | 140 | } |
200 | 141 | ||
201 | static int exynos_aftr_finisher(unsigned long flags) | 142 | static int exynos_aftr_finisher(unsigned long flags) |
202 | { | 143 | { |
144 | int ret; | ||
145 | |||
203 | exynos_set_wakeupmask(0x0000ff3e); | 146 | exynos_set_wakeupmask(0x0000ff3e); |
204 | exynos_cpu_set_boot_vector(S5P_CHECK_AFTR); | ||
205 | /* Set value of power down register for aftr mode */ | 147 | /* Set value of power down register for aftr mode */ |
206 | exynos_sys_powerdown_conf(SYS_AFTR); | 148 | exynos_sys_powerdown_conf(SYS_AFTR); |
207 | cpu_do_idle(); | 149 | |
150 | ret = call_firmware_op(do_idle, FW_DO_IDLE_AFTR); | ||
151 | if (ret == -ENOSYS) { | ||
152 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) | ||
153 | exynos_cpu_save_register(); | ||
154 | exynos_cpu_set_boot_vector(S5P_CHECK_AFTR); | ||
155 | cpu_do_idle(); | ||
156 | } | ||
208 | 157 | ||
209 | return 1; | 158 | return 1; |
210 | } | 159 | } |
@@ -214,196 +163,16 @@ void exynos_enter_aftr(void) | |||
214 | cpu_pm_enter(); | 163 | cpu_pm_enter(); |
215 | 164 | ||
216 | exynos_pm_central_suspend(); | 165 | exynos_pm_central_suspend(); |
217 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) | ||
218 | exynos_cpu_save_register(); | ||
219 | 166 | ||
220 | cpu_suspend(0, exynos_aftr_finisher); | 167 | cpu_suspend(0, exynos_aftr_finisher); |
221 | 168 | ||
222 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) { | 169 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) { |
223 | scu_enable(S5P_VA_SCU); | 170 | scu_enable(S5P_VA_SCU); |
224 | exynos_cpu_restore_register(); | 171 | if (call_firmware_op(resume) == -ENOSYS) |
172 | exynos_cpu_restore_register(); | ||
225 | } | 173 | } |
226 | 174 | ||
227 | exynos_pm_central_resume(); | 175 | exynos_pm_central_resume(); |
228 | 176 | ||
229 | cpu_pm_exit(); | 177 | cpu_pm_exit(); |
230 | } | 178 | } |
231 | |||
232 | static int exynos_cpu_suspend(unsigned long arg) | ||
233 | { | ||
234 | #ifdef CONFIG_CACHE_L2X0 | ||
235 | outer_flush_all(); | ||
236 | #endif | ||
237 | |||
238 | if (soc_is_exynos5250()) | ||
239 | flush_cache_all(); | ||
240 | |||
241 | /* issue the standby signal into the pm unit. */ | ||
242 | cpu_do_idle(); | ||
243 | |||
244 | pr_info("Failed to suspend the system\n"); | ||
245 | return 1; /* Aborting suspend */ | ||
246 | } | ||
247 | |||
248 | static void exynos_pm_prepare(void) | ||
249 | { | ||
250 | unsigned int tmp; | ||
251 | |||
252 | /* Set wake-up mask registers */ | ||
253 | pmu_raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK); | ||
254 | pmu_raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK); | ||
255 | |||
256 | s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | ||
257 | |||
258 | if (soc_is_exynos5250()) { | ||
259 | s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save)); | ||
260 | /* Disable USE_RETENTION of JPEG_MEM_OPTION */ | ||
261 | tmp = pmu_raw_readl(EXYNOS5_JPEG_MEM_OPTION); | ||
262 | tmp &= ~EXYNOS5_OPTION_USE_RETENTION; | ||
263 | pmu_raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION); | ||
264 | } | ||
265 | |||
266 | /* Set value of power down register for sleep mode */ | ||
267 | |||
268 | exynos_sys_powerdown_conf(SYS_SLEEP); | ||
269 | pmu_raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1); | ||
270 | |||
271 | /* ensure at least INFORM0 has the resume address */ | ||
272 | |||
273 | pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0); | ||
274 | } | ||
275 | |||
276 | static int exynos_pm_suspend(void) | ||
277 | { | ||
278 | unsigned long tmp; | ||
279 | |||
280 | exynos_pm_central_suspend(); | ||
281 | |||
282 | /* Setting SEQ_OPTION register */ | ||
283 | |||
284 | tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); | ||
285 | pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); | ||
286 | |||
287 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) | ||
288 | exynos_cpu_save_register(); | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static void exynos_pm_resume(void) | ||
294 | { | ||
295 | if (exynos_pm_central_resume()) | ||
296 | goto early_wakeup; | ||
297 | |||
298 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) | ||
299 | exynos_cpu_restore_register(); | ||
300 | |||
301 | /* For release retention */ | ||
302 | |||
303 | pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); | ||
304 | pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); | ||
305 | pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); | ||
306 | pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); | ||
307 | pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); | ||
308 | pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); | ||
309 | pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); | ||
310 | |||
311 | if (soc_is_exynos5250()) | ||
312 | s3c_pm_do_restore(exynos5_sys_save, | ||
313 | ARRAY_SIZE(exynos5_sys_save)); | ||
314 | |||
315 | s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | ||
316 | |||
317 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) | ||
318 | scu_enable(S5P_VA_SCU); | ||
319 | |||
320 | early_wakeup: | ||
321 | |||
322 | /* Clear SLEEP mode set in INFORM1 */ | ||
323 | pmu_raw_writel(0x0, S5P_INFORM1); | ||
324 | |||
325 | return; | ||
326 | } | ||
327 | |||
328 | static struct syscore_ops exynos_pm_syscore_ops = { | ||
329 | .suspend = exynos_pm_suspend, | ||
330 | .resume = exynos_pm_resume, | ||
331 | }; | ||
332 | |||
333 | /* | ||
334 | * Suspend Ops | ||
335 | */ | ||
336 | |||
337 | static int exynos_suspend_enter(suspend_state_t state) | ||
338 | { | ||
339 | int ret; | ||
340 | |||
341 | s3c_pm_debug_init(); | ||
342 | |||
343 | S3C_PMDBG("%s: suspending the system...\n", __func__); | ||
344 | |||
345 | S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__, | ||
346 | exynos_irqwake_intmask, exynos_get_eint_wake_mask()); | ||
347 | |||
348 | if (exynos_irqwake_intmask == -1U | ||
349 | && exynos_get_eint_wake_mask() == -1U) { | ||
350 | pr_err("%s: No wake-up sources!\n", __func__); | ||
351 | pr_err("%s: Aborting sleep\n", __func__); | ||
352 | return -EINVAL; | ||
353 | } | ||
354 | |||
355 | s3c_pm_save_uarts(); | ||
356 | exynos_pm_prepare(); | ||
357 | flush_cache_all(); | ||
358 | s3c_pm_check_store(); | ||
359 | |||
360 | ret = cpu_suspend(0, exynos_cpu_suspend); | ||
361 | if (ret) | ||
362 | return ret; | ||
363 | |||
364 | s3c_pm_restore_uarts(); | ||
365 | |||
366 | S3C_PMDBG("%s: wakeup stat: %08x\n", __func__, | ||
367 | pmu_raw_readl(S5P_WAKEUP_STAT)); | ||
368 | |||
369 | s3c_pm_check_restore(); | ||
370 | |||
371 | S3C_PMDBG("%s: resuming the system...\n", __func__); | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static int exynos_suspend_prepare(void) | ||
377 | { | ||
378 | s3c_pm_check_prepare(); | ||
379 | |||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static void exynos_suspend_finish(void) | ||
384 | { | ||
385 | s3c_pm_check_cleanup(); | ||
386 | } | ||
387 | |||
388 | static const struct platform_suspend_ops exynos_suspend_ops = { | ||
389 | .enter = exynos_suspend_enter, | ||
390 | .prepare = exynos_suspend_prepare, | ||
391 | .finish = exynos_suspend_finish, | ||
392 | .valid = suspend_valid_only_mem, | ||
393 | }; | ||
394 | |||
395 | void __init exynos_pm_init(void) | ||
396 | { | ||
397 | u32 tmp; | ||
398 | |||
399 | /* Platform-specific GIC callback */ | ||
400 | gic_arch_extn.irq_set_wake = exynos_irq_set_wake; | ||
401 | |||
402 | /* All wakeup disable */ | ||
403 | tmp = pmu_raw_readl(S5P_WAKEUP_MASK); | ||
404 | tmp |= ((0xFF << 8) | (0x1F << 1)); | ||
405 | pmu_raw_writel(tmp, S5P_WAKEUP_MASK); | ||
406 | |||
407 | register_syscore_ops(&exynos_pm_syscore_ops); | ||
408 | suspend_set_ops(&exynos_suspend_ops); | ||
409 | } | ||
diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c index d8fa0337db73..c15761ca2f18 100644 --- a/arch/arm/mach-exynos/pmu.c +++ b/arch/arm/mach-exynos/pmu.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. | 2 | * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. |
3 | * http://www.samsung.com/ | 3 | * http://www.samsung.com/ |
4 | * | 4 | * |
5 | * EXYNOS - CPU PMU(Power Management Unit) support | 5 | * EXYNOS - CPU PMU(Power Management Unit) support |
@@ -10,12 +10,136 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/of.h> |
14 | #include <linux/of_address.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/notifier.h> | ||
18 | #include <linux/reboot.h> | ||
14 | 19 | ||
15 | #include "common.h" | 20 | |
21 | #include "exynos-pmu.h" | ||
16 | #include "regs-pmu.h" | 22 | #include "regs-pmu.h" |
17 | 23 | ||
18 | static const struct exynos_pmu_conf *exynos_pmu_config; | 24 | #define PMU_TABLE_END (-1U) |
25 | |||
26 | struct exynos_pmu_conf { | ||
27 | unsigned int offset; | ||
28 | u8 val[NUM_SYS_POWERDOWN]; | ||
29 | }; | ||
30 | |||
31 | struct exynos_pmu_data { | ||
32 | const struct exynos_pmu_conf *pmu_config; | ||
33 | const struct exynos_pmu_conf *pmu_config_extra; | ||
34 | |||
35 | void (*pmu_init)(void); | ||
36 | void (*powerdown_conf)(enum sys_powerdown); | ||
37 | void (*powerdown_conf_extra)(enum sys_powerdown); | ||
38 | }; | ||
39 | |||
40 | struct exynos_pmu_context { | ||
41 | struct device *dev; | ||
42 | const struct exynos_pmu_data *pmu_data; | ||
43 | }; | ||
44 | |||
45 | static void __iomem *pmu_base_addr; | ||
46 | static struct exynos_pmu_context *pmu_context; | ||
47 | |||
48 | static inline void pmu_raw_writel(u32 val, u32 offset) | ||
49 | { | ||
50 | writel_relaxed(val, pmu_base_addr + offset); | ||
51 | } | ||
52 | |||
53 | static inline u32 pmu_raw_readl(u32 offset) | ||
54 | { | ||
55 | return readl_relaxed(pmu_base_addr + offset); | ||
56 | } | ||
57 | |||
58 | static struct exynos_pmu_conf exynos3250_pmu_config[] = { | ||
59 | /* { .offset = offset, .val = { AFTR, W-AFTR, SLEEP } */ | ||
60 | { EXYNOS3_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, | ||
61 | { EXYNOS3_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
62 | { EXYNOS3_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
63 | { EXYNOS3_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, | ||
64 | { EXYNOS3_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
65 | { EXYNOS3_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
66 | { EXYNOS3_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
67 | { EXYNOS3_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
68 | { EXYNOS3_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
69 | { EXYNOS3_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, | ||
70 | { EXYNOS3_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x3} }, | ||
71 | { EXYNOS3_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
72 | { EXYNOS3_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
73 | { EXYNOS3_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
74 | { EXYNOS3_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, | ||
75 | { EXYNOS3_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, | ||
76 | { EXYNOS3_LPDDR_PHY_DLL_LOCK_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, | ||
77 | { EXYNOS3_CMU_ACLKSTOP_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
78 | { EXYNOS3_CMU_SCLKSTOP_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
79 | { EXYNOS3_CMU_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
80 | { EXYNOS3_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
81 | { EXYNOS3_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
82 | { EXYNOS3_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
83 | { EXYNOS3_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
84 | { EXYNOS3_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
85 | { EXYNOS3_UPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, | ||
86 | { EXYNOS3_EPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
87 | { EXYNOS3_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
88 | { EXYNOS3_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
89 | { EXYNOS3_CMU_CLKSTOP_CAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
90 | { EXYNOS3_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
91 | { EXYNOS3_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
92 | { EXYNOS3_CMU_CLKSTOP_LCD0_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
93 | { EXYNOS3_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
94 | { EXYNOS3_CMU_CLKSTOP_MAUDIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
95 | { EXYNOS3_CMU_RESET_CAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
96 | { EXYNOS3_CMU_RESET_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
97 | { EXYNOS3_CMU_RESET_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
98 | { EXYNOS3_CMU_RESET_LCD0_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
99 | { EXYNOS3_CMU_RESET_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
100 | { EXYNOS3_CMU_RESET_MAUDIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
101 | { EXYNOS3_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, | ||
102 | { EXYNOS3_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, | ||
103 | { EXYNOS3_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x3} }, | ||
104 | { EXYNOS3_TOP_BUS_COREBLK_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, | ||
105 | { EXYNOS3_TOP_RETENTION_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, | ||
106 | { EXYNOS3_TOP_PWR_COREBLK_SYS_PWR_REG, { 0x3, 0x3, 0x3} }, | ||
107 | { EXYNOS3_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
108 | { EXYNOS3_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, | ||
109 | { EXYNOS3_LOGIC_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
110 | { EXYNOS3_OSCCLK_GATE_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, | ||
111 | { EXYNOS3_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
112 | { EXYNOS3_PAD_RETENTION_MAUDIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
113 | { EXYNOS3_PAD_RETENTION_GPIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
114 | { EXYNOS3_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
115 | { EXYNOS3_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
116 | { EXYNOS3_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
117 | { EXYNOS3_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
118 | { EXYNOS3_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
119 | { EXYNOS3_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
120 | { EXYNOS3_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
121 | { EXYNOS3_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
122 | { EXYNOS3_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
123 | { EXYNOS3_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
124 | { EXYNOS3_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
125 | { EXYNOS3_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
126 | { EXYNOS3_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
127 | { EXYNOS3_EXT_REGULATOR_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
128 | { EXYNOS3_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
129 | { EXYNOS3_GPIO_MODE_MAUDIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
130 | { EXYNOS3_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
131 | { EXYNOS3_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
132 | { EXYNOS3_TOP_ASB_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
133 | { EXYNOS3_TOP_ASB_ISOLATION_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
134 | { EXYNOS3_CAM_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
135 | { EXYNOS3_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
136 | { EXYNOS3_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
137 | { EXYNOS3_LCD0_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
138 | { EXYNOS3_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
139 | { EXYNOS3_MAUDIO_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
140 | { EXYNOS3_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
141 | { PMU_TABLE_END,}, | ||
142 | }; | ||
19 | 143 | ||
20 | static const struct exynos_pmu_conf exynos4210_pmu_config[] = { | 144 | static const struct exynos_pmu_conf exynos4210_pmu_config[] = { |
21 | /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */ | 145 | /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */ |
@@ -264,6 +388,7 @@ static const struct exynos_pmu_conf exynos5250_pmu_config[] = { | |||
264 | { EXYNOS5_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, | 388 | { EXYNOS5_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, |
265 | { EXYNOS5_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, | 389 | { EXYNOS5_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, |
266 | { EXYNOS5_JPEG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, | 390 | { EXYNOS5_JPEG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, |
391 | { EXYNOS5_JPEG_MEM_OPTION, { 0x10, 0x10, 0x0} }, | ||
267 | { EXYNOS5_HSI_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, | 392 | { EXYNOS5_HSI_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, |
268 | { EXYNOS5_MCUIOP_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, | 393 | { EXYNOS5_MCUIOP_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, |
269 | { EXYNOS5_SATA_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, | 394 | { EXYNOS5_SATA_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, |
@@ -315,6 +440,189 @@ static const struct exynos_pmu_conf exynos5250_pmu_config[] = { | |||
315 | { PMU_TABLE_END,}, | 440 | { PMU_TABLE_END,}, |
316 | }; | 441 | }; |
317 | 442 | ||
443 | static struct exynos_pmu_conf exynos5420_pmu_config[] = { | ||
444 | /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */ | ||
445 | { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
446 | { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
447 | { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
448 | { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
449 | { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
450 | { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
451 | { EXYNOS5420_ARM_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
452 | { EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
453 | { EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
454 | { EXYNOS5420_ARM_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
455 | { EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
456 | { EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
457 | { EXYNOS5420_KFC_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
458 | { EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
459 | { EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
460 | { EXYNOS5420_KFC_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
461 | { EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
462 | { EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
463 | { EXYNOS5420_KFC_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
464 | { EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
465 | { EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
466 | { EXYNOS5420_KFC_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
467 | { EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
468 | { EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
469 | { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
470 | { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
471 | { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
472 | { EXYNOS5420_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
473 | { EXYNOS5420_KFC_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
474 | { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
475 | { EXYNOS5420_KFC_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
476 | { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
477 | { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, | ||
478 | { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
479 | { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
480 | { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, | ||
481 | { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
482 | { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, | ||
483 | { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, | ||
484 | { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, | ||
485 | { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
486 | { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
487 | { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
488 | { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
489 | { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
490 | { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
491 | { EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
492 | { EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
493 | { EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
494 | { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
495 | { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
496 | { EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
497 | { EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
498 | { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, | ||
499 | { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, | ||
500 | { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x0} }, | ||
501 | { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, | ||
502 | { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, | ||
503 | { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, | ||
504 | { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
505 | { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, | ||
506 | { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
507 | { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
508 | { EXYNOS5420_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, | ||
509 | { EXYNOS5420_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, | ||
510 | { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
511 | { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
512 | { EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
513 | { EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
514 | { EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
515 | { EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
516 | { EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
517 | { EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
518 | { EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
519 | { EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
520 | { EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
521 | { EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
522 | { EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
523 | { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
524 | { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
525 | { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
526 | { EXYNOS5_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
527 | { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
528 | { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
529 | { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
530 | { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
531 | { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
532 | { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, | ||
533 | { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, | ||
534 | { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
535 | { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
536 | { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
537 | { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
538 | { EXYNOS5420_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
539 | { EXYNOS5420_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} }, | ||
540 | { EXYNOS5420_G2D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
541 | { EXYNOS5420_MSC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
542 | { EXYNOS5420_FSYS_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
543 | { EXYNOS5420_FSYS2_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
544 | { EXYNOS5420_PSGEN_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
545 | { EXYNOS5420_PERIC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
546 | { EXYNOS5420_WCORE_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, | ||
547 | { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
548 | { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
549 | { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
550 | { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
551 | { EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
552 | { EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
553 | { EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
554 | { EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
555 | { EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
556 | { EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
557 | { EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
558 | { EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
559 | { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
560 | { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
561 | { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
562 | { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
563 | { EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
564 | { EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
565 | { EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
566 | { EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
567 | { EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
568 | { EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
569 | { EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
570 | { EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
571 | { EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
572 | { EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
573 | { EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
574 | { EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
575 | { EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
576 | { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
577 | { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
578 | { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
579 | { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
580 | { EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
581 | { EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
582 | { EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
583 | { EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
584 | { EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, | ||
585 | { PMU_TABLE_END,}, | ||
586 | }; | ||
587 | |||
588 | static unsigned int const exynos3250_list_feed[] = { | ||
589 | EXYNOS3_ARM_CORE_OPTION(0), | ||
590 | EXYNOS3_ARM_CORE_OPTION(1), | ||
591 | EXYNOS3_ARM_CORE_OPTION(2), | ||
592 | EXYNOS3_ARM_CORE_OPTION(3), | ||
593 | EXYNOS3_ARM_COMMON_OPTION, | ||
594 | EXYNOS3_TOP_PWR_OPTION, | ||
595 | EXYNOS3_CORE_TOP_PWR_OPTION, | ||
596 | S5P_CAM_OPTION, | ||
597 | S5P_MFC_OPTION, | ||
598 | S5P_G3D_OPTION, | ||
599 | S5P_LCD0_OPTION, | ||
600 | S5P_ISP_OPTION, | ||
601 | }; | ||
602 | |||
603 | static void exynos3250_powerdown_conf_extra(enum sys_powerdown mode) | ||
604 | { | ||
605 | unsigned int i; | ||
606 | unsigned int tmp; | ||
607 | |||
608 | /* Enable only SC_FEEDBACK */ | ||
609 | for (i = 0; i < ARRAY_SIZE(exynos3250_list_feed); i++) { | ||
610 | tmp = pmu_raw_readl(exynos3250_list_feed[i]); | ||
611 | tmp &= ~(EXYNOS3_OPTION_USE_SC_COUNTER); | ||
612 | tmp |= EXYNOS3_OPTION_USE_SC_FEEDBACK; | ||
613 | pmu_raw_writel(tmp, exynos3250_list_feed[i]); | ||
614 | } | ||
615 | |||
616 | if (mode != SYS_SLEEP) | ||
617 | return; | ||
618 | |||
619 | pmu_raw_writel(XUSBXTI_DURATION, EXYNOS3_XUSBXTI_DURATION); | ||
620 | pmu_raw_writel(XXTI_DURATION, EXYNOS3_XXTI_DURATION); | ||
621 | pmu_raw_writel(EXT_REGULATOR_DURATION, EXYNOS3_EXT_REGULATOR_DURATION); | ||
622 | pmu_raw_writel(EXT_REGULATOR_COREBLK_DURATION, | ||
623 | EXYNOS3_EXT_REGULATOR_COREBLK_DURATION); | ||
624 | } | ||
625 | |||
318 | static unsigned int const exynos5_list_both_cnt_feed[] = { | 626 | static unsigned int const exynos5_list_both_cnt_feed[] = { |
319 | EXYNOS5_ARM_CORE0_OPTION, | 627 | EXYNOS5_ARM_CORE0_OPTION, |
320 | EXYNOS5_ARM_CORE1_OPTION, | 628 | EXYNOS5_ARM_CORE1_OPTION, |
@@ -335,7 +643,76 @@ static unsigned int const exynos5_list_disable_wfi_wfe[] = { | |||
335 | EXYNOS5_ISP_ARM_OPTION, | 643 | EXYNOS5_ISP_ARM_OPTION, |
336 | }; | 644 | }; |
337 | 645 | ||
338 | static void exynos5_init_pmu(void) | 646 | static unsigned int const exynos5420_list_disable_pmu_reg[] = { |
647 | EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, | ||
648 | EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, | ||
649 | EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, | ||
650 | EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG, | ||
651 | EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG, | ||
652 | EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG, | ||
653 | EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG, | ||
654 | EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG, | ||
655 | EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG, | ||
656 | EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG, | ||
657 | EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG, | ||
658 | EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, | ||
659 | EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, | ||
660 | EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, | ||
661 | EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG, | ||
662 | EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG, | ||
663 | EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG, | ||
664 | EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG, | ||
665 | EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG, | ||
666 | EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG, | ||
667 | EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG, | ||
668 | EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG, | ||
669 | EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG, | ||
670 | EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG, | ||
671 | EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG, | ||
672 | EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG, | ||
673 | EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG, | ||
674 | EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, | ||
675 | EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, | ||
676 | EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, | ||
677 | EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG, | ||
678 | EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG, | ||
679 | EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG, | ||
680 | EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG, | ||
681 | EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, | ||
682 | }; | ||
683 | |||
684 | static void exynos5_power_off(void) | ||
685 | { | ||
686 | unsigned int tmp; | ||
687 | |||
688 | pr_info("Power down.\n"); | ||
689 | tmp = pmu_raw_readl(EXYNOS_PS_HOLD_CONTROL); | ||
690 | tmp ^= (1 << 8); | ||
691 | pmu_raw_writel(tmp, EXYNOS_PS_HOLD_CONTROL); | ||
692 | |||
693 | /* Wait a little so we don't give a false warning below */ | ||
694 | mdelay(100); | ||
695 | |||
696 | pr_err("Power down failed, please power off system manually.\n"); | ||
697 | while (1) | ||
698 | ; | ||
699 | } | ||
700 | |||
701 | void exynos5420_powerdown_conf(enum sys_powerdown mode) | ||
702 | { | ||
703 | u32 this_cluster; | ||
704 | |||
705 | this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1); | ||
706 | |||
707 | /* | ||
708 | * set the cluster id to IROM register to ensure that we wake | ||
709 | * up with the current cluster. | ||
710 | */ | ||
711 | pmu_raw_writel(this_cluster, EXYNOS_IROM_DATA2); | ||
712 | } | ||
713 | |||
714 | |||
715 | static void exynos5_powerdown_conf(enum sys_powerdown mode) | ||
339 | { | 716 | { |
340 | unsigned int i; | 717 | unsigned int i; |
341 | unsigned int tmp; | 718 | unsigned int tmp; |
@@ -343,7 +720,7 @@ static void exynos5_init_pmu(void) | |||
343 | /* | 720 | /* |
344 | * Enable both SC_FEEDBACK and SC_COUNTER | 721 | * Enable both SC_FEEDBACK and SC_COUNTER |
345 | */ | 722 | */ |
346 | for (i = 0 ; i < ARRAY_SIZE(exynos5_list_both_cnt_feed) ; i++) { | 723 | for (i = 0; i < ARRAY_SIZE(exynos5_list_both_cnt_feed); i++) { |
347 | tmp = pmu_raw_readl(exynos5_list_both_cnt_feed[i]); | 724 | tmp = pmu_raw_readl(exynos5_list_both_cnt_feed[i]); |
348 | tmp |= (EXYNOS5_USE_SC_FEEDBACK | | 725 | tmp |= (EXYNOS5_USE_SC_FEEDBACK | |
349 | EXYNOS5_USE_SC_COUNTER); | 726 | EXYNOS5_USE_SC_COUNTER); |
@@ -360,7 +737,7 @@ static void exynos5_init_pmu(void) | |||
360 | /* | 737 | /* |
361 | * Disable WFI/WFE on XXX_OPTION | 738 | * Disable WFI/WFE on XXX_OPTION |
362 | */ | 739 | */ |
363 | for (i = 0 ; i < ARRAY_SIZE(exynos5_list_disable_wfi_wfe) ; i++) { | 740 | for (i = 0; i < ARRAY_SIZE(exynos5_list_disable_wfi_wfe); i++) { |
364 | tmp = pmu_raw_readl(exynos5_list_disable_wfi_wfe[i]); | 741 | tmp = pmu_raw_readl(exynos5_list_disable_wfi_wfe[i]); |
365 | tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE | | 742 | tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE | |
366 | EXYNOS5_OPTION_USE_STANDBYWFI); | 743 | EXYNOS5_OPTION_USE_STANDBYWFI); |
@@ -372,51 +749,257 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode) | |||
372 | { | 749 | { |
373 | unsigned int i; | 750 | unsigned int i; |
374 | 751 | ||
375 | if (soc_is_exynos5250()) | 752 | const struct exynos_pmu_data *pmu_data = pmu_context->pmu_data; |
376 | exynos5_init_pmu(); | 753 | |
754 | if (pmu_data->powerdown_conf) | ||
755 | pmu_data->powerdown_conf(mode); | ||
756 | |||
757 | if (pmu_data->pmu_config) { | ||
758 | for (i = 0; (pmu_data->pmu_config[i].offset != PMU_TABLE_END); i++) | ||
759 | pmu_raw_writel(pmu_data->pmu_config[i].val[mode], | ||
760 | pmu_data->pmu_config[i].offset); | ||
761 | } | ||
377 | 762 | ||
378 | for (i = 0; (exynos_pmu_config[i].offset != PMU_TABLE_END) ; i++) | 763 | if (pmu_data->powerdown_conf_extra) |
379 | pmu_raw_writel(exynos_pmu_config[i].val[mode], | 764 | pmu_data->powerdown_conf_extra(mode); |
380 | exynos_pmu_config[i].offset); | ||
381 | 765 | ||
382 | if (soc_is_exynos4412()) { | 766 | if (pmu_data->pmu_config_extra) { |
383 | for (i = 0; exynos4412_pmu_config[i].offset != PMU_TABLE_END ; i++) | 767 | for (i = 0; pmu_data->pmu_config_extra[i].offset != PMU_TABLE_END; i++) |
384 | pmu_raw_writel(exynos4412_pmu_config[i].val[mode], | 768 | pmu_raw_writel(pmu_data->pmu_config_extra[i].val[mode], |
385 | exynos4412_pmu_config[i].offset); | 769 | pmu_data->pmu_config_extra[i].offset); |
386 | } | 770 | } |
387 | } | 771 | } |
388 | 772 | ||
389 | static int __init exynos_pmu_init(void) | 773 | static void exynos3250_pmu_init(void) |
774 | { | ||
775 | unsigned int value; | ||
776 | |||
777 | /* | ||
778 | * To prevent from issuing new bus request form L2 memory system | ||
779 | * If core status is power down, should be set '1' to L2 power down | ||
780 | */ | ||
781 | value = pmu_raw_readl(EXYNOS3_ARM_COMMON_OPTION); | ||
782 | value |= EXYNOS3_OPTION_SKIP_DEACTIVATE_ACEACP_IN_PWDN; | ||
783 | pmu_raw_writel(value, EXYNOS3_ARM_COMMON_OPTION); | ||
784 | |||
785 | /* Enable USE_STANDBY_WFI for all CORE */ | ||
786 | pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION); | ||
787 | |||
788 | /* | ||
789 | * Set PSHOLD port for output high | ||
790 | */ | ||
791 | value = pmu_raw_readl(S5P_PS_HOLD_CONTROL); | ||
792 | value |= S5P_PS_HOLD_OUTPUT_HIGH; | ||
793 | pmu_raw_writel(value, S5P_PS_HOLD_CONTROL); | ||
794 | |||
795 | /* | ||
796 | * Enable signal for PSHOLD port | ||
797 | */ | ||
798 | value = pmu_raw_readl(S5P_PS_HOLD_CONTROL); | ||
799 | value |= S5P_PS_HOLD_EN; | ||
800 | pmu_raw_writel(value, S5P_PS_HOLD_CONTROL); | ||
801 | } | ||
802 | |||
803 | static void exynos5250_pmu_init(void) | ||
390 | { | 804 | { |
391 | unsigned int value; | 805 | unsigned int value; |
806 | /* | ||
807 | * When SYS_WDTRESET is set, watchdog timer reset request | ||
808 | * is ignored by power management unit. | ||
809 | */ | ||
810 | value = pmu_raw_readl(EXYNOS5_AUTO_WDTRESET_DISABLE); | ||
811 | value &= ~EXYNOS5_SYS_WDTRESET; | ||
812 | pmu_raw_writel(value, EXYNOS5_AUTO_WDTRESET_DISABLE); | ||
813 | |||
814 | value = pmu_raw_readl(EXYNOS5_MASK_WDTRESET_REQUEST); | ||
815 | value &= ~EXYNOS5_SYS_WDTRESET; | ||
816 | pmu_raw_writel(value, EXYNOS5_MASK_WDTRESET_REQUEST); | ||
817 | } | ||
818 | |||
819 | static void exynos5420_pmu_init(void) | ||
820 | { | ||
821 | unsigned int value; | ||
822 | int i; | ||
823 | |||
824 | /* | ||
825 | * Set the CMU_RESET, CMU_SYSCLK and CMU_CLKSTOP registers | ||
826 | * for local power blocks to Low initially as per Table 8-4: | ||
827 | * "System-Level Power-Down Configuration Registers". | ||
828 | */ | ||
829 | for (i = 0; i < ARRAY_SIZE(exynos5420_list_disable_pmu_reg); i++) | ||
830 | pmu_raw_writel(0, exynos5420_list_disable_pmu_reg[i]); | ||
831 | |||
832 | /* Enable USE_STANDBY_WFI for all CORE */ | ||
833 | pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION); | ||
834 | |||
835 | value = pmu_raw_readl(EXYNOS_L2_OPTION(0)); | ||
836 | value &= ~EXYNOS5_USE_RETENTION; | ||
837 | pmu_raw_writel(value, EXYNOS_L2_OPTION(0)); | ||
838 | |||
839 | value = pmu_raw_readl(EXYNOS_L2_OPTION(1)); | ||
840 | value &= ~EXYNOS5_USE_RETENTION; | ||
841 | pmu_raw_writel(value, EXYNOS_L2_OPTION(1)); | ||
842 | |||
843 | /* | ||
844 | * If L2_COMMON is turned off, clocks related to ATB async | ||
845 | * bridge are gated. Thus, when ISP power is gated, LPI | ||
846 | * may get stuck. | ||
847 | */ | ||
848 | value = pmu_raw_readl(EXYNOS5420_LPI_MASK); | ||
849 | value |= EXYNOS5420_ATB_ISP_ARM; | ||
850 | pmu_raw_writel(value, EXYNOS5420_LPI_MASK); | ||
851 | |||
852 | value = pmu_raw_readl(EXYNOS5420_LPI_MASK1); | ||
853 | value |= EXYNOS5420_ATB_KFC; | ||
854 | pmu_raw_writel(value, EXYNOS5420_LPI_MASK1); | ||
855 | |||
856 | /* Prevent issue of new bus request from L2 memory */ | ||
857 | value = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION); | ||
858 | value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; | ||
859 | pmu_raw_writel(value, EXYNOS5420_ARM_COMMON_OPTION); | ||
860 | |||
861 | value = pmu_raw_readl(EXYNOS5420_KFC_COMMON_OPTION); | ||
862 | value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; | ||
863 | pmu_raw_writel(value, EXYNOS5420_KFC_COMMON_OPTION); | ||
864 | |||
865 | /* This setting is to reduce suspend/resume time */ | ||
866 | pmu_raw_writel(DUR_WAIT_RESET, EXYNOS5420_LOGIC_RESET_DURATION3); | ||
867 | |||
868 | /* Serialized CPU wakeup of Eagle */ | ||
869 | pmu_raw_writel(SPREAD_ENABLE, EXYNOS5420_ARM_INTR_SPREAD_ENABLE); | ||
870 | |||
871 | pmu_raw_writel(SPREAD_USE_STANDWFI, | ||
872 | EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI); | ||
873 | |||
874 | pmu_raw_writel(0x1, EXYNOS5420_UP_SCHEDULER); | ||
875 | |||
876 | pm_power_off = exynos5_power_off; | ||
877 | pr_info("EXYNOS5420 PMU initialized\n"); | ||
878 | } | ||
879 | |||
880 | static int pmu_restart_notify(struct notifier_block *this, | ||
881 | unsigned long code, void *unused) | ||
882 | { | ||
883 | pmu_raw_writel(0x1, EXYNOS_SWRESET); | ||
884 | |||
885 | return NOTIFY_DONE; | ||
886 | } | ||
887 | |||
888 | static const struct exynos_pmu_data exynos3250_pmu_data = { | ||
889 | .pmu_config = exynos3250_pmu_config, | ||
890 | .pmu_init = exynos3250_pmu_init, | ||
891 | .powerdown_conf_extra = exynos3250_powerdown_conf_extra, | ||
892 | }; | ||
392 | 893 | ||
393 | exynos_pmu_config = exynos4210_pmu_config; | 894 | static const struct exynos_pmu_data exynos4210_pmu_data = { |
394 | 895 | .pmu_config = exynos4210_pmu_config, | |
395 | if (soc_is_exynos4210()) { | 896 | }; |
396 | exynos_pmu_config = exynos4210_pmu_config; | 897 | |
397 | pr_info("EXYNOS4210 PMU Initialize\n"); | 898 | static const struct exynos_pmu_data exynos4212_pmu_data = { |
398 | } else if (soc_is_exynos4212() || soc_is_exynos4412()) { | 899 | .pmu_config = exynos4x12_pmu_config, |
399 | exynos_pmu_config = exynos4x12_pmu_config; | 900 | }; |
400 | pr_info("EXYNOS4x12 PMU Initialize\n"); | 901 | |
401 | } else if (soc_is_exynos5250()) { | 902 | static const struct exynos_pmu_data exynos4412_pmu_data = { |
402 | /* | 903 | .pmu_config = exynos4x12_pmu_config, |
403 | * When SYS_WDTRESET is set, watchdog timer reset request | 904 | .pmu_config_extra = exynos4412_pmu_config, |
404 | * is ignored by power management unit. | 905 | }; |
405 | */ | 906 | |
406 | value = pmu_raw_readl(EXYNOS5_AUTO_WDTRESET_DISABLE); | 907 | static const struct exynos_pmu_data exynos5250_pmu_data = { |
407 | value &= ~EXYNOS5_SYS_WDTRESET; | 908 | .pmu_config = exynos5250_pmu_config, |
408 | pmu_raw_writel(value, EXYNOS5_AUTO_WDTRESET_DISABLE); | 909 | .pmu_init = exynos5250_pmu_init, |
409 | 910 | .powerdown_conf = exynos5_powerdown_conf, | |
410 | value = pmu_raw_readl(EXYNOS5_MASK_WDTRESET_REQUEST); | 911 | }; |
411 | value &= ~EXYNOS5_SYS_WDTRESET; | 912 | |
412 | pmu_raw_writel(value, EXYNOS5_MASK_WDTRESET_REQUEST); | 913 | static struct exynos_pmu_data exynos5420_pmu_data = { |
413 | 914 | .pmu_config = exynos5420_pmu_config, | |
414 | exynos_pmu_config = exynos5250_pmu_config; | 915 | .pmu_init = exynos5420_pmu_init, |
415 | pr_info("EXYNOS5250 PMU Initialize\n"); | 916 | .powerdown_conf = exynos5420_powerdown_conf, |
416 | } else { | 917 | }; |
417 | pr_info("EXYNOS: PMU not supported\n"); | 918 | |
919 | /* | ||
920 | * PMU platform driver and devicetree bindings. | ||
921 | */ | ||
922 | static const struct of_device_id exynos_pmu_of_device_ids[] = { | ||
923 | { | ||
924 | .compatible = "samsung,exynos3250-pmu", | ||
925 | .data = &exynos3250_pmu_data, | ||
926 | }, { | ||
927 | .compatible = "samsung,exynos4210-pmu", | ||
928 | .data = &exynos4210_pmu_data, | ||
929 | }, { | ||
930 | .compatible = "samsung,exynos4212-pmu", | ||
931 | .data = &exynos4212_pmu_data, | ||
932 | }, { | ||
933 | .compatible = "samsung,exynos4412-pmu", | ||
934 | .data = &exynos4412_pmu_data, | ||
935 | }, { | ||
936 | .compatible = "samsung,exynos5250-pmu", | ||
937 | .data = &exynos5250_pmu_data, | ||
938 | }, { | ||
939 | .compatible = "samsung,exynos5420-pmu", | ||
940 | .data = &exynos5420_pmu_data, | ||
941 | }, | ||
942 | { /*sentinel*/ }, | ||
943 | }; | ||
944 | |||
945 | /* | ||
946 | * Exynos PMU restart notifier, handles restart functionality | ||
947 | */ | ||
948 | static struct notifier_block pmu_restart_handler = { | ||
949 | .notifier_call = pmu_restart_notify, | ||
950 | .priority = 128, | ||
951 | }; | ||
952 | |||
953 | static int exynos_pmu_probe(struct platform_device *pdev) | ||
954 | { | ||
955 | const struct of_device_id *match; | ||
956 | struct device *dev = &pdev->dev; | ||
957 | struct resource *res; | ||
958 | int ret; | ||
959 | |||
960 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
961 | pmu_base_addr = devm_ioremap_resource(dev, res); | ||
962 | if (IS_ERR(pmu_base_addr)) | ||
963 | return PTR_ERR(pmu_base_addr); | ||
964 | |||
965 | pmu_context = devm_kzalloc(&pdev->dev, | ||
966 | sizeof(struct exynos_pmu_context), | ||
967 | GFP_KERNEL); | ||
968 | if (!pmu_context) { | ||
969 | dev_err(dev, "Cannot allocate memory.\n"); | ||
970 | return -ENOMEM; | ||
418 | } | 971 | } |
972 | pmu_context->dev = dev; | ||
973 | |||
974 | match = of_match_node(exynos_pmu_of_device_ids, dev->of_node); | ||
975 | |||
976 | pmu_context->pmu_data = match->data; | ||
977 | |||
978 | if (pmu_context->pmu_data->pmu_init) | ||
979 | pmu_context->pmu_data->pmu_init(); | ||
980 | |||
981 | platform_set_drvdata(pdev, pmu_context); | ||
419 | 982 | ||
983 | ret = register_restart_handler(&pmu_restart_handler); | ||
984 | if (ret) | ||
985 | dev_warn(dev, "can't register restart handler err=%d\n", ret); | ||
986 | |||
987 | dev_dbg(dev, "Exynos PMU Driver probe done\n"); | ||
420 | return 0; | 988 | return 0; |
421 | } | 989 | } |
422 | arch_initcall(exynos_pmu_init); | 990 | |
991 | static struct platform_driver exynos_pmu_driver = { | ||
992 | .driver = { | ||
993 | .name = "exynos-pmu", | ||
994 | .owner = THIS_MODULE, | ||
995 | .of_match_table = exynos_pmu_of_device_ids, | ||
996 | }, | ||
997 | .probe = exynos_pmu_probe, | ||
998 | }; | ||
999 | |||
1000 | static int __init exynos_pmu_init(void) | ||
1001 | { | ||
1002 | return platform_driver_register(&exynos_pmu_driver); | ||
1003 | |||
1004 | } | ||
1005 | postcore_initcall(exynos_pmu_init); | ||
diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h index 4e9b4440e2bd..b5f4406fc1b5 100644 --- a/arch/arm/mach-exynos/regs-pmu.h +++ b/arch/arm/mach-exynos/regs-pmu.h | |||
@@ -19,9 +19,24 @@ | |||
19 | #define S5P_CENTRAL_SEQ_OPTION 0x0208 | 19 | #define S5P_CENTRAL_SEQ_OPTION 0x0208 |
20 | 20 | ||
21 | #define S5P_USE_STANDBY_WFI0 (1 << 16) | 21 | #define S5P_USE_STANDBY_WFI0 (1 << 16) |
22 | #define S5P_USE_STANDBY_WFI1 (1 << 17) | ||
23 | #define S5P_USE_STANDBY_WFI2 (1 << 19) | ||
24 | #define S5P_USE_STANDBY_WFI3 (1 << 20) | ||
22 | #define S5P_USE_STANDBY_WFE0 (1 << 24) | 25 | #define S5P_USE_STANDBY_WFE0 (1 << 24) |
26 | #define S5P_USE_STANDBY_WFE1 (1 << 25) | ||
27 | #define S5P_USE_STANDBY_WFE2 (1 << 27) | ||
28 | #define S5P_USE_STANDBY_WFE3 (1 << 28) | ||
29 | |||
30 | #define S5P_USE_STANDBY_WFI_ALL \ | ||
31 | (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFI1 | \ | ||
32 | S5P_USE_STANDBY_WFI2 | S5P_USE_STANDBY_WFI3 | \ | ||
33 | S5P_USE_STANDBY_WFE0 | S5P_USE_STANDBY_WFE1 | \ | ||
34 | S5P_USE_STANDBY_WFE2 | S5P_USE_STANDBY_WFE3) | ||
35 | |||
23 | #define S5P_USE_DELAYED_RESET_ASSERTION BIT(12) | 36 | #define S5P_USE_DELAYED_RESET_ASSERTION BIT(12) |
24 | 37 | ||
38 | #define EXYNOS_CORE_PO_RESET(n) ((1 << 4) << n) | ||
39 | #define EXYNOS_WAKEUP_FROM_LOWPWR (1 << 28) | ||
25 | #define EXYNOS_SWRESET 0x0400 | 40 | #define EXYNOS_SWRESET 0x0400 |
26 | #define EXYNOS5440_SWRESET 0x00C4 | 41 | #define EXYNOS5440_SWRESET 0x00C4 |
27 | 42 | ||
@@ -36,6 +51,7 @@ | |||
36 | #define S5P_INFORM7 0x081C | 51 | #define S5P_INFORM7 0x081C |
37 | #define S5P_PMU_SPARE3 0x090C | 52 | #define S5P_PMU_SPARE3 0x090C |
38 | 53 | ||
54 | #define EXYNOS_IROM_DATA2 0x0988 | ||
39 | #define S5P_ARM_CORE0_LOWPWR 0x1000 | 55 | #define S5P_ARM_CORE0_LOWPWR 0x1000 |
40 | #define S5P_DIS_IRQ_CORE0 0x1004 | 56 | #define S5P_DIS_IRQ_CORE0 0x1004 |
41 | #define S5P_DIS_IRQ_CENTRAL0 0x1008 | 57 | #define S5P_DIS_IRQ_CENTRAL0 0x1008 |
@@ -118,6 +134,31 @@ | |||
118 | #define EXYNOS_COMMON_OPTION(_nr) \ | 134 | #define EXYNOS_COMMON_OPTION(_nr) \ |
119 | (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8) | 135 | (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8) |
120 | 136 | ||
137 | #define EXYNOS_CORE_LOCAL_PWR_EN 0x3 | ||
138 | |||
139 | #define EXYNOS_ARM_COMMON_STATUS 0x2504 | ||
140 | #define EXYNOS_COMMON_OPTION(_nr) \ | ||
141 | (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8) | ||
142 | |||
143 | #define EXYNOS_ARM_L2_CONFIGURATION 0x2600 | ||
144 | #define EXYNOS_L2_CONFIGURATION(_nr) \ | ||
145 | (EXYNOS_ARM_L2_CONFIGURATION + ((_nr) * 0x80)) | ||
146 | #define EXYNOS_L2_STATUS(_nr) \ | ||
147 | (EXYNOS_L2_CONFIGURATION(_nr) + 0x4) | ||
148 | #define EXYNOS_L2_OPTION(_nr) \ | ||
149 | (EXYNOS_L2_CONFIGURATION(_nr) + 0x8) | ||
150 | #define EXYNOS_L2_COMMON_PWR_EN 0x3 | ||
151 | |||
152 | #define EXYNOS_ARM_CORE_X_STATUS_OFFSET 0x4 | ||
153 | |||
154 | #define EXYNOS5_APLL_SYSCLK_CONFIGURATION 0x2A00 | ||
155 | #define EXYNOS5_APLL_SYSCLK_STATUS 0x2A04 | ||
156 | |||
157 | #define EXYNOS5_ARM_L2_OPTION 0x2608 | ||
158 | #define EXYNOS5_USE_RETENTION BIT(4) | ||
159 | |||
160 | #define EXYNOS5_L2RSTDISABLE_VALUE BIT(3) | ||
161 | |||
121 | #define S5P_PAD_RET_MAUDIO_OPTION 0x3028 | 162 | #define S5P_PAD_RET_MAUDIO_OPTION 0x3028 |
122 | #define S5P_PAD_RET_GPIO_OPTION 0x3108 | 163 | #define S5P_PAD_RET_GPIO_OPTION 0x3108 |
123 | #define S5P_PAD_RET_UART_OPTION 0x3128 | 164 | #define S5P_PAD_RET_UART_OPTION 0x3128 |
@@ -126,7 +167,19 @@ | |||
126 | #define S5P_PAD_RET_EBIA_OPTION 0x3188 | 167 | #define S5P_PAD_RET_EBIA_OPTION 0x3188 |
127 | #define S5P_PAD_RET_EBIB_OPTION 0x31A8 | 168 | #define S5P_PAD_RET_EBIB_OPTION 0x31A8 |
128 | 169 | ||
170 | #define S5P_PS_HOLD_CONTROL 0x330C | ||
171 | #define S5P_PS_HOLD_EN (1 << 31) | ||
172 | #define S5P_PS_HOLD_OUTPUT_HIGH (3 << 8) | ||
173 | |||
174 | #define S5P_CAM_OPTION 0x3C08 | ||
175 | #define S5P_MFC_OPTION 0x3C48 | ||
176 | #define S5P_G3D_OPTION 0x3C68 | ||
177 | #define S5P_LCD0_OPTION 0x3C88 | ||
178 | #define S5P_LCD1_OPTION 0x3CA8 | ||
179 | #define S5P_ISP_OPTION S5P_LCD1_OPTION | ||
180 | |||
129 | #define S5P_CORE_LOCAL_PWR_EN 0x3 | 181 | #define S5P_CORE_LOCAL_PWR_EN 0x3 |
182 | #define S5P_CORE_WAKEUP_FROM_LOCAL_CFG (0x3 << 8) | ||
130 | 183 | ||
131 | /* Only for EXYNOS4210 */ | 184 | /* Only for EXYNOS4210 */ |
132 | #define S5P_CMU_CLKSTOP_LCD1_LOWPWR 0x1154 | 185 | #define S5P_CMU_CLKSTOP_LCD1_LOWPWR 0x1154 |
@@ -185,11 +238,116 @@ | |||
185 | #define S5P_DIS_IRQ_CORE3 0x1034 | 238 | #define S5P_DIS_IRQ_CORE3 0x1034 |
186 | #define S5P_DIS_IRQ_CENTRAL3 0x1038 | 239 | #define S5P_DIS_IRQ_CENTRAL3 0x1038 |
187 | 240 | ||
241 | /* Only for EXYNOS3XXX */ | ||
242 | #define EXYNOS3_ARM_CORE0_SYS_PWR_REG 0x1000 | ||
243 | #define EXYNOS3_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG 0x1004 | ||
244 | #define EXYNOS3_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG 0x1008 | ||
245 | #define EXYNOS3_ARM_CORE1_SYS_PWR_REG 0x1010 | ||
246 | #define EXYNOS3_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG 0x1014 | ||
247 | #define EXYNOS3_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG 0x1018 | ||
248 | #define EXYNOS3_ISP_ARM_SYS_PWR_REG 0x1050 | ||
249 | #define EXYNOS3_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG 0x1054 | ||
250 | #define EXYNOS3_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG 0x1058 | ||
251 | #define EXYNOS3_ARM_COMMON_SYS_PWR_REG 0x1080 | ||
252 | #define EXYNOS3_ARM_L2_SYS_PWR_REG 0x10C0 | ||
253 | #define EXYNOS3_CMU_ACLKSTOP_SYS_PWR_REG 0x1100 | ||
254 | #define EXYNOS3_CMU_SCLKSTOP_SYS_PWR_REG 0x1104 | ||
255 | #define EXYNOS3_CMU_RESET_SYS_PWR_REG 0x110C | ||
256 | #define EXYNOS3_CMU_ACLKSTOP_COREBLK_SYS_PWR_REG 0x1110 | ||
257 | #define EXYNOS3_CMU_SCLKSTOP_COREBLK_SYS_PWR_REG 0x1114 | ||
258 | #define EXYNOS3_CMU_RESET_COREBLK_SYS_PWR_REG 0x111C | ||
259 | #define EXYNOS3_APLL_SYSCLK_SYS_PWR_REG 0x1120 | ||
260 | #define EXYNOS3_MPLL_SYSCLK_SYS_PWR_REG 0x1124 | ||
261 | #define EXYNOS3_VPLL_SYSCLK_SYS_PWR_REG 0x1128 | ||
262 | #define EXYNOS3_EPLL_SYSCLK_SYS_PWR_REG 0x112C | ||
263 | #define EXYNOS3_MPLLUSER_SYSCLK_SYS_PWR_REG 0x1130 | ||
264 | #define EXYNOS3_BPLLUSER_SYSCLK_SYS_PWR_REG 0x1134 | ||
265 | #define EXYNOS3_EPLLUSER_SYSCLK_SYS_PWR_REG 0x1138 | ||
266 | #define EXYNOS3_CMU_CLKSTOP_CAM_SYS_PWR_REG 0x1140 | ||
267 | #define EXYNOS3_CMU_CLKSTOP_MFC_SYS_PWR_REG 0x1148 | ||
268 | #define EXYNOS3_CMU_CLKSTOP_G3D_SYS_PWR_REG 0x114C | ||
269 | #define EXYNOS3_CMU_CLKSTOP_LCD0_SYS_PWR_REG 0x1150 | ||
270 | #define EXYNOS3_CMU_CLKSTOP_ISP_SYS_PWR_REG 0x1154 | ||
271 | #define EXYNOS3_CMU_CLKSTOP_MAUDIO_SYS_PWR_REG 0x1158 | ||
272 | #define EXYNOS3_CMU_RESET_CAM_SYS_PWR_REG 0x1160 | ||
273 | #define EXYNOS3_CMU_RESET_MFC_SYS_PWR_REG 0x1168 | ||
274 | #define EXYNOS3_CMU_RESET_G3D_SYS_PWR_REG 0x116C | ||
275 | #define EXYNOS3_CMU_RESET_LCD0_SYS_PWR_REG 0x1170 | ||
276 | #define EXYNOS3_CMU_RESET_ISP_SYS_PWR_REG 0x1174 | ||
277 | #define EXYNOS3_CMU_RESET_MAUDIO_SYS_PWR_REG 0x1178 | ||
278 | #define EXYNOS3_TOP_BUS_SYS_PWR_REG 0x1180 | ||
279 | #define EXYNOS3_TOP_RETENTION_SYS_PWR_REG 0x1184 | ||
280 | #define EXYNOS3_TOP_PWR_SYS_PWR_REG 0x1188 | ||
281 | #define EXYNOS3_TOP_BUS_COREBLK_SYS_PWR_REG 0x1190 | ||
282 | #define EXYNOS3_TOP_RETENTION_COREBLK_SYS_PWR_REG 0x1194 | ||
283 | #define EXYNOS3_TOP_PWR_COREBLK_SYS_PWR_REG 0x1198 | ||
284 | #define EXYNOS3_LOGIC_RESET_SYS_PWR_REG 0x11A0 | ||
285 | #define EXYNOS3_OSCCLK_GATE_SYS_PWR_REG 0x11A4 | ||
286 | #define EXYNOS3_LOGIC_RESET_COREBLK_SYS_PWR_REG 0x11B0 | ||
287 | #define EXYNOS3_OSCCLK_GATE_COREBLK_SYS_PWR_REG 0x11B4 | ||
288 | #define EXYNOS3_PAD_RETENTION_DRAM_SYS_PWR_REG 0x1200 | ||
289 | #define EXYNOS3_PAD_RETENTION_MAUDIO_SYS_PWR_REG 0x1204 | ||
290 | #define EXYNOS3_PAD_RETENTION_SPI_SYS_PWR_REG 0x1208 | ||
291 | #define EXYNOS3_PAD_RETENTION_MMC2_SYS_PWR_REG 0x1218 | ||
292 | #define EXYNOS3_PAD_RETENTION_GPIO_SYS_PWR_REG 0x1220 | ||
293 | #define EXYNOS3_PAD_RETENTION_UART_SYS_PWR_REG 0x1224 | ||
294 | #define EXYNOS3_PAD_RETENTION_MMC0_SYS_PWR_REG 0x1228 | ||
295 | #define EXYNOS3_PAD_RETENTION_MMC1_SYS_PWR_REG 0x122C | ||
296 | #define EXYNOS3_PAD_RETENTION_EBIA_SYS_PWR_REG 0x1230 | ||
297 | #define EXYNOS3_PAD_RETENTION_EBIB_SYS_PWR_REG 0x1234 | ||
298 | #define EXYNOS3_PAD_RETENTION_JTAG_SYS_PWR_REG 0x1238 | ||
299 | #define EXYNOS3_PAD_ISOLATION_SYS_PWR_REG 0x1240 | ||
300 | #define EXYNOS3_PAD_ALV_SEL_SYS_PWR_REG 0x1260 | ||
301 | #define EXYNOS3_XUSBXTI_SYS_PWR_REG 0x1280 | ||
302 | #define EXYNOS3_XXTI_SYS_PWR_REG 0x1284 | ||
303 | #define EXYNOS3_EXT_REGULATOR_SYS_PWR_REG 0x12C0 | ||
304 | #define EXYNOS3_EXT_REGULATOR_COREBLK_SYS_PWR_REG 0x12C4 | ||
305 | #define EXYNOS3_GPIO_MODE_SYS_PWR_REG 0x1300 | ||
306 | #define EXYNOS3_GPIO_MODE_MAUDIO_SYS_PWR_REG 0x1340 | ||
307 | #define EXYNOS3_TOP_ASB_RESET_SYS_PWR_REG 0x1344 | ||
308 | #define EXYNOS3_TOP_ASB_ISOLATION_SYS_PWR_REG 0x1348 | ||
309 | #define EXYNOS3_TOP_ASB_RESET_COREBLK_SYS_PWR_REG 0x1350 | ||
310 | #define EXYNOS3_TOP_ASB_ISOLATION_COREBLK_SYS_PWR_REG 0x1354 | ||
311 | #define EXYNOS3_CAM_SYS_PWR_REG 0x1380 | ||
312 | #define EXYNOS3_MFC_SYS_PWR_REG 0x1388 | ||
313 | #define EXYNOS3_G3D_SYS_PWR_REG 0x138C | ||
314 | #define EXYNOS3_LCD0_SYS_PWR_REG 0x1390 | ||
315 | #define EXYNOS3_ISP_SYS_PWR_REG 0x1394 | ||
316 | #define EXYNOS3_MAUDIO_SYS_PWR_REG 0x1398 | ||
317 | #define EXYNOS3_DRAM_FREQ_DOWN_SYS_PWR_REG 0x13B0 | ||
318 | #define EXYNOS3_DDRPHY_DLLOFF_SYS_PWR_REG 0x13B4 | ||
319 | #define EXYNOS3_CMU_SYSCLK_ISP_SYS_PWR_REG 0x13B8 | ||
320 | #define EXYNOS3_LPDDR_PHY_DLL_LOCK_SYS_PWR_REG 0x13C0 | ||
321 | #define EXYNOS3_BPLL_SYSCLK_SYS_PWR_REG 0x13C4 | ||
322 | #define EXYNOS3_UPLL_SYSCLK_SYS_PWR_REG 0x13C8 | ||
323 | |||
324 | #define EXYNOS3_ARM_CORE0_OPTION 0x2008 | ||
325 | #define EXYNOS3_ARM_CORE_OPTION(_nr) \ | ||
326 | (EXYNOS3_ARM_CORE0_OPTION + ((_nr) * 0x80)) | ||
327 | |||
328 | #define EXYNOS3_ARM_COMMON_OPTION 0x2408 | ||
329 | #define EXYNOS3_TOP_PWR_OPTION 0x2C48 | ||
330 | #define EXYNOS3_CORE_TOP_PWR_OPTION 0x2CA8 | ||
331 | #define EXYNOS3_XUSBXTI_DURATION 0x341C | ||
332 | #define EXYNOS3_XXTI_DURATION 0x343C | ||
333 | #define EXYNOS3_EXT_REGULATOR_DURATION 0x361C | ||
334 | #define EXYNOS3_EXT_REGULATOR_COREBLK_DURATION 0x363C | ||
335 | #define XUSBXTI_DURATION 0x00000BB8 | ||
336 | #define XXTI_DURATION XUSBXTI_DURATION | ||
337 | #define EXT_REGULATOR_DURATION 0x00001D4C | ||
338 | #define EXT_REGULATOR_COREBLK_DURATION EXT_REGULATOR_DURATION | ||
339 | |||
340 | /* for XXX_OPTION */ | ||
341 | #define EXYNOS3_OPTION_USE_SC_COUNTER (1 << 0) | ||
342 | #define EXYNOS3_OPTION_USE_SC_FEEDBACK (1 << 1) | ||
343 | #define EXYNOS3_OPTION_SKIP_DEACTIVATE_ACEACP_IN_PWDN (1 << 7) | ||
344 | |||
188 | /* For EXYNOS5 */ | 345 | /* For EXYNOS5 */ |
189 | 346 | ||
190 | #define EXYNOS5_AUTO_WDTRESET_DISABLE 0x0408 | 347 | #define EXYNOS5_AUTO_WDTRESET_DISABLE 0x0408 |
191 | #define EXYNOS5_MASK_WDTRESET_REQUEST 0x040C | 348 | #define EXYNOS5_MASK_WDTRESET_REQUEST 0x040C |
192 | 349 | ||
350 | #define EXYNOS5_USE_RETENTION BIT(4) | ||
193 | #define EXYNOS5_SYS_WDTRESET (1 << 20) | 351 | #define EXYNOS5_SYS_WDTRESET (1 << 20) |
194 | 352 | ||
195 | #define EXYNOS5_ARM_CORE0_SYS_PWR_REG 0x1000 | 353 | #define EXYNOS5_ARM_CORE0_SYS_PWR_REG 0x1000 |
@@ -329,4 +487,204 @@ static inline unsigned int exynos_pmu_cpunr(unsigned int mpidr) | |||
329 | + MPIDR_AFFINITY_LEVEL(mpidr, 0)); | 487 | + MPIDR_AFFINITY_LEVEL(mpidr, 0)); |
330 | } | 488 | } |
331 | 489 | ||
490 | /* Only for EXYNOS5420 */ | ||
491 | #define EXYNOS5420_ISP_ARM_OPTION 0x2488 | ||
492 | #define EXYNOS5420_L2RSTDISABLE_VALUE BIT(3) | ||
493 | |||
494 | #define EXYNOS5420_LPI_MASK 0x0004 | ||
495 | #define EXYNOS5420_LPI_MASK1 0x0008 | ||
496 | #define EXYNOS5420_UFS BIT(8) | ||
497 | #define EXYNOS5420_ATB_KFC BIT(13) | ||
498 | #define EXYNOS5420_ATB_ISP_ARM BIT(19) | ||
499 | #define EXYNOS5420_EMULATION BIT(31) | ||
500 | #define ATB_ISP_ARM BIT(12) | ||
501 | #define ATB_KFC BIT(13) | ||
502 | #define ATB_NOC BIT(14) | ||
503 | |||
504 | #define EXYNOS5420_ARM_INTR_SPREAD_ENABLE 0x0100 | ||
505 | #define EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI 0x0104 | ||
506 | #define EXYNOS5420_UP_SCHEDULER 0x0120 | ||
507 | #define SPREAD_ENABLE 0xF | ||
508 | #define SPREAD_USE_STANDWFI 0xF | ||
509 | |||
510 | #define EXYNOS5420_BB_CON1 0x0784 | ||
511 | #define EXYNOS5420_BB_SEL_EN BIT(31) | ||
512 | #define EXYNOS5420_BB_PMOS_EN BIT(7) | ||
513 | #define EXYNOS5420_BB_1300X 0XF | ||
514 | |||
515 | #define EXYNOS5420_ARM_CORE2_SYS_PWR_REG 0x1020 | ||
516 | #define EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG 0x1024 | ||
517 | #define EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG 0x1028 | ||
518 | #define EXYNOS5420_ARM_CORE3_SYS_PWR_REG 0x1030 | ||
519 | #define EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG 0x1034 | ||
520 | #define EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG 0x1038 | ||
521 | #define EXYNOS5420_KFC_CORE0_SYS_PWR_REG 0x1040 | ||
522 | #define EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG 0x1044 | ||
523 | #define EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG 0x1048 | ||
524 | #define EXYNOS5420_KFC_CORE1_SYS_PWR_REG 0x1050 | ||
525 | #define EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG 0x1054 | ||
526 | #define EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG 0x1058 | ||
527 | #define EXYNOS5420_KFC_CORE2_SYS_PWR_REG 0x1060 | ||
528 | #define EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG 0x1064 | ||
529 | #define EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG 0x1068 | ||
530 | #define EXYNOS5420_KFC_CORE3_SYS_PWR_REG 0x1070 | ||
531 | #define EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG 0x1074 | ||
532 | #define EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG 0x1078 | ||
533 | #define EXYNOS5420_ISP_ARM_SYS_PWR_REG 0x1090 | ||
534 | #define EXYNOS5420_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG 0x1094 | ||
535 | #define EXYNOS5420_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG 0x1098 | ||
536 | #define EXYNOS5420_ARM_COMMON_SYS_PWR_REG 0x10A0 | ||
537 | #define EXYNOS5420_KFC_COMMON_SYS_PWR_REG 0x10B0 | ||
538 | #define EXYNOS5420_KFC_L2_SYS_PWR_REG 0x10D0 | ||
539 | #define EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG 0x1158 | ||
540 | #define EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG 0x115C | ||
541 | #define EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG 0x1160 | ||
542 | #define EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG 0x1174 | ||
543 | #define EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG 0x1178 | ||
544 | #define EXYNOS5420_INTRAM_MEM_SYS_PWR_REG 0x11B8 | ||
545 | #define EXYNOS5420_INTROM_MEM_SYS_PWR_REG 0x11BC | ||
546 | #define EXYNOS5420_ONENANDXL_MEM_SYS_PWR 0x11C0 | ||
547 | #define EXYNOS5420_USBDEV_MEM_SYS_PWR 0x11CC | ||
548 | #define EXYNOS5420_USBDEV1_MEM_SYS_PWR 0x11D0 | ||
549 | #define EXYNOS5420_SDMMC_MEM_SYS_PWR 0x11D4 | ||
550 | #define EXYNOS5420_CSSYS_MEM_SYS_PWR 0x11D8 | ||
551 | #define EXYNOS5420_SECSS_MEM_SYS_PWR 0x11DC | ||
552 | #define EXYNOS5420_ROTATOR_MEM_SYS_PWR 0x11E0 | ||
553 | #define EXYNOS5420_INTRAM_MEM_SYS_PWR 0x11E4 | ||
554 | #define EXYNOS5420_INTROM_MEM_SYS_PWR 0x11E8 | ||
555 | #define EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG 0x1208 | ||
556 | #define EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG 0x1210 | ||
557 | #define EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG 0x1214 | ||
558 | #define EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG 0x1218 | ||
559 | #define EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG 0x121C | ||
560 | #define EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG 0x1220 | ||
561 | #define EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG 0x1224 | ||
562 | #define EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG 0x1228 | ||
563 | #define EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG 0x122C | ||
564 | #define EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG 0x1230 | ||
565 | #define EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG 0x1234 | ||
566 | #define EXYNOS5420_DISP1_SYS_PWR_REG 0x1410 | ||
567 | #define EXYNOS5420_MAU_SYS_PWR_REG 0x1414 | ||
568 | #define EXYNOS5420_G2D_SYS_PWR_REG 0x1418 | ||
569 | #define EXYNOS5420_MSC_SYS_PWR_REG 0x141C | ||
570 | #define EXYNOS5420_FSYS_SYS_PWR_REG 0x1420 | ||
571 | #define EXYNOS5420_FSYS2_SYS_PWR_REG 0x1424 | ||
572 | #define EXYNOS5420_PSGEN_SYS_PWR_REG 0x1428 | ||
573 | #define EXYNOS5420_PERIC_SYS_PWR_REG 0x142C | ||
574 | #define EXYNOS5420_WCORE_SYS_PWR_REG 0x1430 | ||
575 | #define EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG 0x1490 | ||
576 | #define EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG 0x1494 | ||
577 | #define EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG 0x1498 | ||
578 | #define EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG 0x149C | ||
579 | #define EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG 0x14A0 | ||
580 | #define EXYNOS5420_CMU_CLKSTOP_FSYS2_SYS_PWR_REG 0x14A4 | ||
581 | #define EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG 0x14A8 | ||
582 | #define EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG 0x14AC | ||
583 | #define EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG 0x14B0 | ||
584 | #define EXYNOS5420_CMU_SYSCLK_TOPPWR_SYS_PWR_REG 0x14BC | ||
585 | #define EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG 0x14D0 | ||
586 | #define EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG 0x14D4 | ||
587 | #define EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG 0x14D8 | ||
588 | #define EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG 0x14DC | ||
589 | #define EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG 0x14E0 | ||
590 | #define EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG 0x14E4 | ||
591 | #define EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG 0x14E8 | ||
592 | #define EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG 0x14EC | ||
593 | #define EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG 0x14F0 | ||
594 | #define EXYNOS5420_CMU_SYSCLK_SYSMEM_TOPPWR_SYS_PWR_REG 0x14F4 | ||
595 | #define EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG 0x1570 | ||
596 | #define EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG 0x1574 | ||
597 | #define EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG 0x1578 | ||
598 | #define EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG 0x157C | ||
599 | #define EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG 0x1590 | ||
600 | #define EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG 0x1594 | ||
601 | #define EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG 0x1598 | ||
602 | #define EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG 0x159C | ||
603 | #define EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG 0x15A0 | ||
604 | #define EXYNOS5420_SFR_AXI_CGDIS1 0x15E4 | ||
605 | #define EXYNOS_ARM_CORE2_CONFIGURATION 0x2100 | ||
606 | #define EXYNOS5420_ARM_CORE2_OPTION 0x2108 | ||
607 | #define EXYNOS_ARM_CORE3_CONFIGURATION 0x2180 | ||
608 | #define EXYNOS5420_ARM_CORE3_OPTION 0x2188 | ||
609 | #define EXYNOS5420_ARM_COMMON_STATUS 0x2504 | ||
610 | #define EXYNOS5420_ARM_COMMON_OPTION 0x2508 | ||
611 | #define EXYNOS5420_KFC_COMMON_STATUS 0x2584 | ||
612 | #define EXYNOS5420_KFC_COMMON_OPTION 0x2588 | ||
613 | #define EXYNOS5420_LOGIC_RESET_DURATION3 0x2D1C | ||
614 | |||
615 | #define EXYNOS5420_PAD_RET_GPIO_OPTION 0x30C8 | ||
616 | #define EXYNOS5420_PAD_RET_UART_OPTION 0x30E8 | ||
617 | #define EXYNOS5420_PAD_RET_MMCA_OPTION 0x3108 | ||
618 | #define EXYNOS5420_PAD_RET_MMCB_OPTION 0x3128 | ||
619 | #define EXYNOS5420_PAD_RET_MMCC_OPTION 0x3148 | ||
620 | #define EXYNOS5420_PAD_RET_HSI_OPTION 0x3168 | ||
621 | #define EXYNOS5420_PAD_RET_SPI_OPTION 0x31C8 | ||
622 | #define EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION 0x31E8 | ||
623 | #define EXYNOS_PAD_RET_DRAM_OPTION 0x3008 | ||
624 | #define EXYNOS_PAD_RET_MAUDIO_OPTION 0x3028 | ||
625 | #define EXYNOS_PAD_RET_JTAG_OPTION 0x3048 | ||
626 | #define EXYNOS_PAD_RET_GPIO_OPTION 0x3108 | ||
627 | #define EXYNOS_PAD_RET_UART_OPTION 0x3128 | ||
628 | #define EXYNOS_PAD_RET_MMCA_OPTION 0x3148 | ||
629 | #define EXYNOS_PAD_RET_MMCB_OPTION 0x3168 | ||
630 | #define EXYNOS_PAD_RET_EBIA_OPTION 0x3188 | ||
631 | #define EXYNOS_PAD_RET_EBIB_OPTION 0x31A8 | ||
632 | |||
633 | #define EXYNOS_PS_HOLD_CONTROL 0x330C | ||
634 | |||
635 | /* For SYS_PWR_REG */ | ||
636 | #define EXYNOS_SYS_PWR_CFG BIT(0) | ||
637 | |||
638 | #define EXYNOS5420_MFC_CONFIGURATION 0x4060 | ||
639 | #define EXYNOS5420_MFC_STATUS 0x4064 | ||
640 | #define EXYNOS5420_MFC_OPTION 0x4068 | ||
641 | #define EXYNOS5420_G3D_CONFIGURATION 0x4080 | ||
642 | #define EXYNOS5420_G3D_STATUS 0x4084 | ||
643 | #define EXYNOS5420_G3D_OPTION 0x4088 | ||
644 | #define EXYNOS5420_DISP0_CONFIGURATION 0x40A0 | ||
645 | #define EXYNOS5420_DISP0_STATUS 0x40A4 | ||
646 | #define EXYNOS5420_DISP0_OPTION 0x40A8 | ||
647 | #define EXYNOS5420_DISP1_CONFIGURATION 0x40C0 | ||
648 | #define EXYNOS5420_DISP1_STATUS 0x40C4 | ||
649 | #define EXYNOS5420_DISP1_OPTION 0x40C8 | ||
650 | #define EXYNOS5420_MAU_CONFIGURATION 0x40E0 | ||
651 | #define EXYNOS5420_MAU_STATUS 0x40E4 | ||
652 | #define EXYNOS5420_MAU_OPTION 0x40E8 | ||
653 | #define EXYNOS5420_FSYS2_OPTION 0x4168 | ||
654 | #define EXYNOS5420_PSGEN_OPTION 0x4188 | ||
655 | |||
656 | /* For EXYNOS_CENTRAL_SEQ_OPTION */ | ||
657 | #define EXYNOS5_USE_STANDBYWFI_ARM_CORE0 BIT(16) | ||
658 | #define EXYNOS5_USE_STANDBYWFI_ARM_CORE1 BUT(17) | ||
659 | #define EXYNOS5_USE_STANDBYWFE_ARM_CORE0 BIT(24) | ||
660 | #define EXYNOS5_USE_STANDBYWFE_ARM_CORE1 BIT(25) | ||
661 | |||
662 | #define EXYNOS5420_ARM_USE_STANDBY_WFI0 BIT(4) | ||
663 | #define EXYNOS5420_ARM_USE_STANDBY_WFI1 BIT(5) | ||
664 | #define EXYNOS5420_ARM_USE_STANDBY_WFI2 BIT(6) | ||
665 | #define EXYNOS5420_ARM_USE_STANDBY_WFI3 BIT(7) | ||
666 | #define EXYNOS5420_KFC_USE_STANDBY_WFI0 BIT(8) | ||
667 | #define EXYNOS5420_KFC_USE_STANDBY_WFI1 BIT(9) | ||
668 | #define EXYNOS5420_KFC_USE_STANDBY_WFI2 BIT(10) | ||
669 | #define EXYNOS5420_KFC_USE_STANDBY_WFI3 BIT(11) | ||
670 | #define EXYNOS5420_ARM_USE_STANDBY_WFE0 BIT(16) | ||
671 | #define EXYNOS5420_ARM_USE_STANDBY_WFE1 BIT(17) | ||
672 | #define EXYNOS5420_ARM_USE_STANDBY_WFE2 BIT(18) | ||
673 | #define EXYNOS5420_ARM_USE_STANDBY_WFE3 BIT(19) | ||
674 | #define EXYNOS5420_KFC_USE_STANDBY_WFE0 BIT(20) | ||
675 | #define EXYNOS5420_KFC_USE_STANDBY_WFE1 BIT(21) | ||
676 | #define EXYNOS5420_KFC_USE_STANDBY_WFE2 BIT(22) | ||
677 | #define EXYNOS5420_KFC_USE_STANDBY_WFE3 BIT(23) | ||
678 | |||
679 | #define DUR_WAIT_RESET 0xF | ||
680 | |||
681 | #define EXYNOS5420_USE_STANDBY_WFI_ALL (EXYNOS5420_ARM_USE_STANDBY_WFI0 \ | ||
682 | | EXYNOS5420_ARM_USE_STANDBY_WFI1 \ | ||
683 | | EXYNOS5420_ARM_USE_STANDBY_WFI2 \ | ||
684 | | EXYNOS5420_ARM_USE_STANDBY_WFI3 \ | ||
685 | | EXYNOS5420_KFC_USE_STANDBY_WFI0 \ | ||
686 | | EXYNOS5420_KFC_USE_STANDBY_WFI1 \ | ||
687 | | EXYNOS5420_KFC_USE_STANDBY_WFI2 \ | ||
688 | | EXYNOS5420_KFC_USE_STANDBY_WFI3) | ||
689 | |||
332 | #endif /* __ASM_ARCH_REGS_PMU_H */ | 690 | #endif /* __ASM_ARCH_REGS_PMU_H */ |
diff --git a/arch/arm/mach-exynos/sleep.S b/arch/arm/mach-exynos/sleep.S index 108a45f4bb62..e3c373082bbe 100644 --- a/arch/arm/mach-exynos/sleep.S +++ b/arch/arm/mach-exynos/sleep.S | |||
@@ -16,6 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/linkage.h> | 18 | #include <linux/linkage.h> |
19 | #include "smc.h" | ||
19 | 20 | ||
20 | #define CPU_MASK 0xff0ffff0 | 21 | #define CPU_MASK 0xff0ffff0 |
21 | #define CPU_CORTEX_A9 0x410fc090 | 22 | #define CPU_CORTEX_A9 0x410fc090 |
@@ -55,3 +56,30 @@ ENTRY(exynos_cpu_resume) | |||
55 | #endif | 56 | #endif |
56 | b cpu_resume | 57 | b cpu_resume |
57 | ENDPROC(exynos_cpu_resume) | 58 | ENDPROC(exynos_cpu_resume) |
59 | |||
60 | .align | ||
61 | |||
62 | ENTRY(exynos_cpu_resume_ns) | ||
63 | mrc p15, 0, r0, c0, c0, 0 | ||
64 | ldr r1, =CPU_MASK | ||
65 | and r0, r0, r1 | ||
66 | ldr r1, =CPU_CORTEX_A9 | ||
67 | cmp r0, r1 | ||
68 | bne skip_cp15 | ||
69 | |||
70 | adr r0, cp15_save_power | ||
71 | ldr r1, [r0] | ||
72 | adr r0, cp15_save_diag | ||
73 | ldr r2, [r0] | ||
74 | mov r0, #SMC_CMD_C15RESUME | ||
75 | dsb | ||
76 | smc #0 | ||
77 | skip_cp15: | ||
78 | b cpu_resume | ||
79 | ENDPROC(exynos_cpu_resume_ns) | ||
80 | .globl cp15_save_diag | ||
81 | cp15_save_diag: | ||
82 | .long 0 @ cp15 diagnostic | ||
83 | .globl cp15_save_power | ||
84 | cp15_save_power: | ||
85 | .long 0 @ cp15 power control | ||
diff --git a/arch/arm/mach-exynos/smc.h b/arch/arm/mach-exynos/smc.h index 13a1dc8ecbf2..f7b82f9c1e21 100644 --- a/arch/arm/mach-exynos/smc.h +++ b/arch/arm/mach-exynos/smc.h | |||
@@ -26,6 +26,10 @@ | |||
26 | #define SMC_CMD_L2X0INVALL (-24) | 26 | #define SMC_CMD_L2X0INVALL (-24) |
27 | #define SMC_CMD_L2X0DEBUG (-25) | 27 | #define SMC_CMD_L2X0DEBUG (-25) |
28 | 28 | ||
29 | #ifndef __ASSEMBLY__ | ||
30 | |||
29 | extern void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3); | 31 | extern void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3); |
30 | 32 | ||
33 | #endif /* __ASSEMBLY__ */ | ||
34 | |||
31 | #endif | 35 | #endif |
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c new file mode 100644 index 000000000000..f8e7dcd17055 --- /dev/null +++ b/arch/arm/mach-exynos/suspend.c | |||
@@ -0,0 +1,566 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com | ||
4 | * | ||
5 | * EXYNOS - Suspend support | ||
6 | * | ||
7 | * Based on arch/arm/mach-s3c2410/pm.c | ||
8 | * Copyright (c) 2006 Simtec Electronics | ||
9 | * Ben Dooks <ben@simtec.co.uk> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/init.h> | ||
17 | #include <linux/suspend.h> | ||
18 | #include <linux/syscore_ops.h> | ||
19 | #include <linux/cpu_pm.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/irqchip/arm-gic.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/regulator/machine.h> | ||
24 | |||
25 | #include <asm/cacheflush.h> | ||
26 | #include <asm/hardware/cache-l2x0.h> | ||
27 | #include <asm/firmware.h> | ||
28 | #include <asm/mcpm.h> | ||
29 | #include <asm/smp_scu.h> | ||
30 | #include <asm/suspend.h> | ||
31 | |||
32 | #include <plat/pm-common.h> | ||
33 | #include <plat/regs-srom.h> | ||
34 | |||
35 | #include "common.h" | ||
36 | #include "regs-pmu.h" | ||
37 | #include "regs-sys.h" | ||
38 | #include "exynos-pmu.h" | ||
39 | |||
40 | #define S5P_CHECK_SLEEP 0x00000BAD | ||
41 | |||
42 | #define REG_TABLE_END (-1U) | ||
43 | |||
44 | #define EXYNOS5420_CPU_STATE 0x28 | ||
45 | |||
46 | /** | ||
47 | * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping | ||
48 | * @hwirq: Hardware IRQ signal of the GIC | ||
49 | * @mask: Mask in PMU wake-up mask register | ||
50 | */ | ||
51 | struct exynos_wkup_irq { | ||
52 | unsigned int hwirq; | ||
53 | u32 mask; | ||
54 | }; | ||
55 | |||
56 | static struct sleep_save exynos5_sys_save[] = { | ||
57 | SAVE_ITEM(EXYNOS5_SYS_I2C_CFG), | ||
58 | }; | ||
59 | |||
60 | static struct sleep_save exynos_core_save[] = { | ||
61 | /* SROM side */ | ||
62 | SAVE_ITEM(S5P_SROM_BW), | ||
63 | SAVE_ITEM(S5P_SROM_BC0), | ||
64 | SAVE_ITEM(S5P_SROM_BC1), | ||
65 | SAVE_ITEM(S5P_SROM_BC2), | ||
66 | SAVE_ITEM(S5P_SROM_BC3), | ||
67 | }; | ||
68 | |||
69 | struct exynos_pm_data { | ||
70 | const struct exynos_wkup_irq *wkup_irq; | ||
71 | struct sleep_save *extra_save; | ||
72 | int num_extra_save; | ||
73 | unsigned int wake_disable_mask; | ||
74 | unsigned int *release_ret_regs; | ||
75 | |||
76 | void (*pm_prepare)(void); | ||
77 | void (*pm_resume_prepare)(void); | ||
78 | void (*pm_resume)(void); | ||
79 | int (*pm_suspend)(void); | ||
80 | int (*cpu_suspend)(unsigned long); | ||
81 | }; | ||
82 | |||
83 | struct exynos_pm_data *pm_data; | ||
84 | |||
85 | static int exynos5420_cpu_state; | ||
86 | static unsigned int exynos_pmu_spare3; | ||
87 | |||
88 | /* | ||
89 | * GIC wake-up support | ||
90 | */ | ||
91 | |||
92 | static u32 exynos_irqwake_intmask = 0xffffffff; | ||
93 | |||
94 | static const struct exynos_wkup_irq exynos4_wkup_irq[] = { | ||
95 | { 76, BIT(1) }, /* RTC alarm */ | ||
96 | { 77, BIT(2) }, /* RTC tick */ | ||
97 | { /* sentinel */ }, | ||
98 | }; | ||
99 | |||
100 | static const struct exynos_wkup_irq exynos5250_wkup_irq[] = { | ||
101 | { 75, BIT(1) }, /* RTC alarm */ | ||
102 | { 76, BIT(2) }, /* RTC tick */ | ||
103 | { /* sentinel */ }, | ||
104 | }; | ||
105 | |||
106 | unsigned int exynos_release_ret_regs[] = { | ||
107 | S5P_PAD_RET_MAUDIO_OPTION, | ||
108 | S5P_PAD_RET_GPIO_OPTION, | ||
109 | S5P_PAD_RET_UART_OPTION, | ||
110 | S5P_PAD_RET_MMCA_OPTION, | ||
111 | S5P_PAD_RET_MMCB_OPTION, | ||
112 | S5P_PAD_RET_EBIA_OPTION, | ||
113 | S5P_PAD_RET_EBIB_OPTION, | ||
114 | REG_TABLE_END, | ||
115 | }; | ||
116 | |||
117 | unsigned int exynos5420_release_ret_regs[] = { | ||
118 | EXYNOS_PAD_RET_DRAM_OPTION, | ||
119 | EXYNOS_PAD_RET_MAUDIO_OPTION, | ||
120 | EXYNOS_PAD_RET_JTAG_OPTION, | ||
121 | EXYNOS5420_PAD_RET_GPIO_OPTION, | ||
122 | EXYNOS5420_PAD_RET_UART_OPTION, | ||
123 | EXYNOS5420_PAD_RET_MMCA_OPTION, | ||
124 | EXYNOS5420_PAD_RET_MMCB_OPTION, | ||
125 | EXYNOS5420_PAD_RET_MMCC_OPTION, | ||
126 | EXYNOS5420_PAD_RET_HSI_OPTION, | ||
127 | EXYNOS_PAD_RET_EBIA_OPTION, | ||
128 | EXYNOS_PAD_RET_EBIB_OPTION, | ||
129 | EXYNOS5420_PAD_RET_SPI_OPTION, | ||
130 | EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION, | ||
131 | REG_TABLE_END, | ||
132 | }; | ||
133 | |||
134 | static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) | ||
135 | { | ||
136 | const struct exynos_wkup_irq *wkup_irq; | ||
137 | |||
138 | if (!pm_data->wkup_irq) | ||
139 | return -ENOENT; | ||
140 | wkup_irq = pm_data->wkup_irq; | ||
141 | |||
142 | while (wkup_irq->mask) { | ||
143 | if (wkup_irq->hwirq == data->hwirq) { | ||
144 | if (!state) | ||
145 | exynos_irqwake_intmask |= wkup_irq->mask; | ||
146 | else | ||
147 | exynos_irqwake_intmask &= ~wkup_irq->mask; | ||
148 | return 0; | ||
149 | } | ||
150 | ++wkup_irq; | ||
151 | } | ||
152 | |||
153 | return -ENOENT; | ||
154 | } | ||
155 | |||
156 | static int exynos_cpu_do_idle(void) | ||
157 | { | ||
158 | /* issue the standby signal into the pm unit. */ | ||
159 | cpu_do_idle(); | ||
160 | |||
161 | pr_info("Failed to suspend the system\n"); | ||
162 | return 1; /* Aborting suspend */ | ||
163 | } | ||
164 | static void exynos_flush_cache_all(void) | ||
165 | { | ||
166 | flush_cache_all(); | ||
167 | outer_flush_all(); | ||
168 | } | ||
169 | |||
170 | static int exynos_cpu_suspend(unsigned long arg) | ||
171 | { | ||
172 | exynos_flush_cache_all(); | ||
173 | return exynos_cpu_do_idle(); | ||
174 | } | ||
175 | |||
176 | static int exynos5420_cpu_suspend(unsigned long arg) | ||
177 | { | ||
178 | /* MCPM works with HW CPU identifiers */ | ||
179 | unsigned int mpidr = read_cpuid_mpidr(); | ||
180 | unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); | ||
181 | unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); | ||
182 | |||
183 | __raw_writel(0x0, sysram_base_addr + EXYNOS5420_CPU_STATE); | ||
184 | |||
185 | if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) { | ||
186 | mcpm_set_entry_vector(cpu, cluster, exynos_cpu_resume); | ||
187 | |||
188 | /* | ||
189 | * Residency value passed to mcpm_cpu_suspend back-end | ||
190 | * has to be given clear semantics. Set to 0 as a | ||
191 | * temporary value. | ||
192 | */ | ||
193 | mcpm_cpu_suspend(0); | ||
194 | } | ||
195 | |||
196 | pr_info("Failed to suspend the system\n"); | ||
197 | |||
198 | /* return value != 0 means failure */ | ||
199 | return 1; | ||
200 | } | ||
201 | |||
202 | static void exynos_pm_set_wakeup_mask(void) | ||
203 | { | ||
204 | /* Set wake-up mask registers */ | ||
205 | pmu_raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK); | ||
206 | pmu_raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK); | ||
207 | } | ||
208 | |||
209 | static void exynos_pm_enter_sleep_mode(void) | ||
210 | { | ||
211 | /* Set value of power down register for sleep mode */ | ||
212 | exynos_sys_powerdown_conf(SYS_SLEEP); | ||
213 | pmu_raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1); | ||
214 | } | ||
215 | |||
216 | static void exynos_pm_prepare(void) | ||
217 | { | ||
218 | /* Set wake-up mask registers */ | ||
219 | exynos_pm_set_wakeup_mask(); | ||
220 | |||
221 | s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | ||
222 | |||
223 | if (pm_data->extra_save) | ||
224 | s3c_pm_do_save(pm_data->extra_save, | ||
225 | pm_data->num_extra_save); | ||
226 | |||
227 | exynos_pm_enter_sleep_mode(); | ||
228 | |||
229 | /* ensure at least INFORM0 has the resume address */ | ||
230 | pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0); | ||
231 | } | ||
232 | |||
233 | static void exynos5420_pm_prepare(void) | ||
234 | { | ||
235 | unsigned int tmp; | ||
236 | |||
237 | /* Set wake-up mask registers */ | ||
238 | exynos_pm_set_wakeup_mask(); | ||
239 | |||
240 | s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | ||
241 | |||
242 | exynos_pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3); | ||
243 | /* | ||
244 | * The cpu state needs to be saved and restored so that the | ||
245 | * secondary CPUs will enter low power start. Though the U-Boot | ||
246 | * is setting the cpu state with low power flag, the kernel | ||
247 | * needs to restore it back in case, the primary cpu fails to | ||
248 | * suspend for any reason. | ||
249 | */ | ||
250 | exynos5420_cpu_state = __raw_readl(sysram_base_addr + | ||
251 | EXYNOS5420_CPU_STATE); | ||
252 | |||
253 | exynos_pm_enter_sleep_mode(); | ||
254 | |||
255 | /* ensure at least INFORM0 has the resume address */ | ||
256 | if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) | ||
257 | pmu_raw_writel(virt_to_phys(mcpm_entry_point), S5P_INFORM0); | ||
258 | |||
259 | tmp = pmu_raw_readl(EXYNOS5_ARM_L2_OPTION); | ||
260 | tmp &= ~EXYNOS5_USE_RETENTION; | ||
261 | pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION); | ||
262 | |||
263 | tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1); | ||
264 | tmp |= EXYNOS5420_UFS; | ||
265 | pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); | ||
266 | |||
267 | tmp = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION); | ||
268 | tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE; | ||
269 | pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION); | ||
270 | |||
271 | tmp = pmu_raw_readl(EXYNOS5420_FSYS2_OPTION); | ||
272 | tmp |= EXYNOS5420_EMULATION; | ||
273 | pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); | ||
274 | |||
275 | tmp = pmu_raw_readl(EXYNOS5420_PSGEN_OPTION); | ||
276 | tmp |= EXYNOS5420_EMULATION; | ||
277 | pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); | ||
278 | } | ||
279 | |||
280 | |||
281 | static int exynos_pm_suspend(void) | ||
282 | { | ||
283 | exynos_pm_central_suspend(); | ||
284 | |||
285 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) | ||
286 | exynos_cpu_save_register(); | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static int exynos5420_pm_suspend(void) | ||
292 | { | ||
293 | u32 this_cluster; | ||
294 | |||
295 | exynos_pm_central_suspend(); | ||
296 | |||
297 | /* Setting SEQ_OPTION register */ | ||
298 | |||
299 | this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1); | ||
300 | if (!this_cluster) | ||
301 | pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0, | ||
302 | S5P_CENTRAL_SEQ_OPTION); | ||
303 | else | ||
304 | pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0, | ||
305 | S5P_CENTRAL_SEQ_OPTION); | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static void exynos_pm_release_retention(void) | ||
310 | { | ||
311 | unsigned int i; | ||
312 | |||
313 | for (i = 0; (pm_data->release_ret_regs[i] != REG_TABLE_END); i++) | ||
314 | pmu_raw_writel(EXYNOS_WAKEUP_FROM_LOWPWR, | ||
315 | pm_data->release_ret_regs[i]); | ||
316 | } | ||
317 | |||
318 | static void exynos_pm_resume(void) | ||
319 | { | ||
320 | u32 cpuid = read_cpuid_part(); | ||
321 | |||
322 | if (exynos_pm_central_resume()) | ||
323 | goto early_wakeup; | ||
324 | |||
325 | /* For release retention */ | ||
326 | exynos_pm_release_retention(); | ||
327 | |||
328 | if (pm_data->extra_save) | ||
329 | s3c_pm_do_restore_core(pm_data->extra_save, | ||
330 | pm_data->num_extra_save); | ||
331 | |||
332 | s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | ||
333 | |||
334 | if (cpuid == ARM_CPU_PART_CORTEX_A9) | ||
335 | scu_enable(S5P_VA_SCU); | ||
336 | |||
337 | if (call_firmware_op(resume) == -ENOSYS | ||
338 | && cpuid == ARM_CPU_PART_CORTEX_A9) | ||
339 | exynos_cpu_restore_register(); | ||
340 | |||
341 | early_wakeup: | ||
342 | |||
343 | /* Clear SLEEP mode set in INFORM1 */ | ||
344 | pmu_raw_writel(0x0, S5P_INFORM1); | ||
345 | } | ||
346 | |||
347 | static void exynos5420_prepare_pm_resume(void) | ||
348 | { | ||
349 | if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) | ||
350 | WARN_ON(mcpm_cpu_powered_up()); | ||
351 | } | ||
352 | |||
353 | static void exynos5420_pm_resume(void) | ||
354 | { | ||
355 | unsigned long tmp; | ||
356 | |||
357 | /* Restore the CPU0 low power state register */ | ||
358 | tmp = pmu_raw_readl(EXYNOS5_ARM_CORE0_SYS_PWR_REG); | ||
359 | pmu_raw_writel(tmp | S5P_CORE_LOCAL_PWR_EN, | ||
360 | EXYNOS5_ARM_CORE0_SYS_PWR_REG); | ||
361 | |||
362 | /* Restore the sysram cpu state register */ | ||
363 | __raw_writel(exynos5420_cpu_state, | ||
364 | sysram_base_addr + EXYNOS5420_CPU_STATE); | ||
365 | |||
366 | pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, | ||
367 | S5P_CENTRAL_SEQ_OPTION); | ||
368 | |||
369 | if (exynos_pm_central_resume()) | ||
370 | goto early_wakeup; | ||
371 | |||
372 | /* For release retention */ | ||
373 | exynos_pm_release_retention(); | ||
374 | |||
375 | pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3); | ||
376 | |||
377 | s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | ||
378 | |||
379 | early_wakeup: | ||
380 | |||
381 | tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1); | ||
382 | tmp &= ~EXYNOS5420_UFS; | ||
383 | pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); | ||
384 | |||
385 | tmp = pmu_raw_readl(EXYNOS5420_FSYS2_OPTION); | ||
386 | tmp &= ~EXYNOS5420_EMULATION; | ||
387 | pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); | ||
388 | |||
389 | tmp = pmu_raw_readl(EXYNOS5420_PSGEN_OPTION); | ||
390 | tmp &= ~EXYNOS5420_EMULATION; | ||
391 | pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); | ||
392 | |||
393 | /* Clear SLEEP mode set in INFORM1 */ | ||
394 | pmu_raw_writel(0x0, S5P_INFORM1); | ||
395 | } | ||
396 | |||
397 | /* | ||
398 | * Suspend Ops | ||
399 | */ | ||
400 | |||
401 | static int exynos_suspend_enter(suspend_state_t state) | ||
402 | { | ||
403 | int ret; | ||
404 | |||
405 | s3c_pm_debug_init(); | ||
406 | |||
407 | S3C_PMDBG("%s: suspending the system...\n", __func__); | ||
408 | |||
409 | S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__, | ||
410 | exynos_irqwake_intmask, exynos_get_eint_wake_mask()); | ||
411 | |||
412 | if (exynos_irqwake_intmask == -1U | ||
413 | && exynos_get_eint_wake_mask() == -1U) { | ||
414 | pr_err("%s: No wake-up sources!\n", __func__); | ||
415 | pr_err("%s: Aborting sleep\n", __func__); | ||
416 | return -EINVAL; | ||
417 | } | ||
418 | |||
419 | s3c_pm_save_uarts(); | ||
420 | if (pm_data->pm_prepare) | ||
421 | pm_data->pm_prepare(); | ||
422 | flush_cache_all(); | ||
423 | s3c_pm_check_store(); | ||
424 | |||
425 | ret = call_firmware_op(suspend); | ||
426 | if (ret == -ENOSYS) | ||
427 | ret = cpu_suspend(0, pm_data->cpu_suspend); | ||
428 | if (ret) | ||
429 | return ret; | ||
430 | |||
431 | if (pm_data->pm_resume_prepare) | ||
432 | pm_data->pm_resume_prepare(); | ||
433 | s3c_pm_restore_uarts(); | ||
434 | |||
435 | S3C_PMDBG("%s: wakeup stat: %08x\n", __func__, | ||
436 | pmu_raw_readl(S5P_WAKEUP_STAT)); | ||
437 | |||
438 | s3c_pm_check_restore(); | ||
439 | |||
440 | S3C_PMDBG("%s: resuming the system...\n", __func__); | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | static int exynos_suspend_prepare(void) | ||
446 | { | ||
447 | int ret; | ||
448 | |||
449 | /* | ||
450 | * REVISIT: It would be better if struct platform_suspend_ops | ||
451 | * .prepare handler get the suspend_state_t as a parameter to | ||
452 | * avoid hard-coding the suspend to mem state. It's safe to do | ||
453 | * it now only because the suspend_valid_only_mem function is | ||
454 | * used as the .valid callback used to check if a given state | ||
455 | * is supported by the platform anyways. | ||
456 | */ | ||
457 | ret = regulator_suspend_prepare(PM_SUSPEND_MEM); | ||
458 | if (ret) { | ||
459 | pr_err("Failed to prepare regulators for suspend (%d)\n", ret); | ||
460 | return ret; | ||
461 | } | ||
462 | |||
463 | s3c_pm_check_prepare(); | ||
464 | |||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | static void exynos_suspend_finish(void) | ||
469 | { | ||
470 | int ret; | ||
471 | |||
472 | s3c_pm_check_cleanup(); | ||
473 | |||
474 | ret = regulator_suspend_finish(); | ||
475 | if (ret) | ||
476 | pr_warn("Failed to resume regulators from suspend (%d)\n", ret); | ||
477 | } | ||
478 | |||
479 | static const struct platform_suspend_ops exynos_suspend_ops = { | ||
480 | .enter = exynos_suspend_enter, | ||
481 | .prepare = exynos_suspend_prepare, | ||
482 | .finish = exynos_suspend_finish, | ||
483 | .valid = suspend_valid_only_mem, | ||
484 | }; | ||
485 | |||
486 | static const struct exynos_pm_data exynos4_pm_data = { | ||
487 | .wkup_irq = exynos4_wkup_irq, | ||
488 | .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), | ||
489 | .release_ret_regs = exynos_release_ret_regs, | ||
490 | .pm_suspend = exynos_pm_suspend, | ||
491 | .pm_resume = exynos_pm_resume, | ||
492 | .pm_prepare = exynos_pm_prepare, | ||
493 | .cpu_suspend = exynos_cpu_suspend, | ||
494 | }; | ||
495 | |||
496 | static const struct exynos_pm_data exynos5250_pm_data = { | ||
497 | .wkup_irq = exynos5250_wkup_irq, | ||
498 | .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), | ||
499 | .release_ret_regs = exynos_release_ret_regs, | ||
500 | .extra_save = exynos5_sys_save, | ||
501 | .num_extra_save = ARRAY_SIZE(exynos5_sys_save), | ||
502 | .pm_suspend = exynos_pm_suspend, | ||
503 | .pm_resume = exynos_pm_resume, | ||
504 | .pm_prepare = exynos_pm_prepare, | ||
505 | .cpu_suspend = exynos_cpu_suspend, | ||
506 | }; | ||
507 | |||
508 | static struct exynos_pm_data exynos5420_pm_data = { | ||
509 | .wkup_irq = exynos5250_wkup_irq, | ||
510 | .wake_disable_mask = (0x7F << 7) | (0x1F << 1), | ||
511 | .release_ret_regs = exynos5420_release_ret_regs, | ||
512 | .pm_resume_prepare = exynos5420_prepare_pm_resume, | ||
513 | .pm_resume = exynos5420_pm_resume, | ||
514 | .pm_suspend = exynos5420_pm_suspend, | ||
515 | .pm_prepare = exynos5420_pm_prepare, | ||
516 | .cpu_suspend = exynos5420_cpu_suspend, | ||
517 | }; | ||
518 | |||
519 | static struct of_device_id exynos_pmu_of_device_ids[] = { | ||
520 | { | ||
521 | .compatible = "samsung,exynos4210-pmu", | ||
522 | .data = &exynos4_pm_data, | ||
523 | }, { | ||
524 | .compatible = "samsung,exynos4212-pmu", | ||
525 | .data = &exynos4_pm_data, | ||
526 | }, { | ||
527 | .compatible = "samsung,exynos4412-pmu", | ||
528 | .data = &exynos4_pm_data, | ||
529 | }, { | ||
530 | .compatible = "samsung,exynos5250-pmu", | ||
531 | .data = &exynos5250_pm_data, | ||
532 | }, { | ||
533 | .compatible = "samsung,exynos5420-pmu", | ||
534 | .data = &exynos5420_pm_data, | ||
535 | }, | ||
536 | { /*sentinel*/ }, | ||
537 | }; | ||
538 | |||
539 | static struct syscore_ops exynos_pm_syscore_ops; | ||
540 | |||
541 | void __init exynos_pm_init(void) | ||
542 | { | ||
543 | const struct of_device_id *match; | ||
544 | u32 tmp; | ||
545 | |||
546 | of_find_matching_node_and_match(NULL, exynos_pmu_of_device_ids, &match); | ||
547 | if (!match) { | ||
548 | pr_err("Failed to find PMU node\n"); | ||
549 | return; | ||
550 | } | ||
551 | pm_data = (struct exynos_pm_data *) match->data; | ||
552 | |||
553 | /* Platform-specific GIC callback */ | ||
554 | gic_arch_extn.irq_set_wake = exynos_irq_set_wake; | ||
555 | |||
556 | /* All wakeup disable */ | ||
557 | tmp = pmu_raw_readl(S5P_WAKEUP_MASK); | ||
558 | tmp |= pm_data->wake_disable_mask; | ||
559 | pmu_raw_writel(tmp, S5P_WAKEUP_MASK); | ||
560 | |||
561 | exynos_pm_syscore_ops.suspend = pm_data->pm_suspend; | ||
562 | exynos_pm_syscore_ops.resume = pm_data->pm_resume; | ||
563 | |||
564 | register_syscore_ops(&exynos_pm_syscore_ops); | ||
565 | suspend_set_ops(&exynos_suspend_ops); | ||
566 | } | ||
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 11b2957f792b..e8627e04e1e6 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig | |||
@@ -633,12 +633,41 @@ config SOC_VF610 | |||
633 | bool "Vybrid Family VF610 support" | 633 | bool "Vybrid Family VF610 support" |
634 | select ARM_GIC | 634 | select ARM_GIC |
635 | select PINCTRL_VF610 | 635 | select PINCTRL_VF610 |
636 | select VF_PIT_TIMER | ||
637 | select PL310_ERRATA_769419 if CACHE_L2X0 | 636 | select PL310_ERRATA_769419 if CACHE_L2X0 |
638 | 637 | ||
639 | help | 638 | help |
640 | This enable support for Freescale Vybrid VF610 processor. | 639 | This enable support for Freescale Vybrid VF610 processor. |
641 | 640 | ||
641 | choice | ||
642 | prompt "Clocksource for scheduler clock" | ||
643 | depends on SOC_VF610 | ||
644 | default VF_USE_ARM_GLOBAL_TIMER | ||
645 | |||
646 | config VF_USE_ARM_GLOBAL_TIMER | ||
647 | bool "Use ARM Global Timer" | ||
648 | select ARM_GLOBAL_TIMER | ||
649 | select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK | ||
650 | help | ||
651 | Use the ARM Global Timer as clocksource | ||
652 | |||
653 | config VF_USE_PIT_TIMER | ||
654 | bool "Use PIT timer" | ||
655 | select VF_PIT_TIMER | ||
656 | help | ||
657 | Use SoC Periodic Interrupt Timer (PIT) as clocksource | ||
658 | |||
659 | endchoice | ||
660 | |||
661 | config SOC_LS1021A | ||
662 | bool "Freescale LS1021A support" | ||
663 | select ARM_GIC | ||
664 | select HAVE_ARM_ARCH_TIMER | ||
665 | select PCI_DOMAINS if PCI | ||
666 | select ZONE_DMA if ARM_LPAE | ||
667 | |||
668 | help | ||
669 | This enable support for Freescale LS1021A processor. | ||
670 | |||
642 | endif | 671 | endif |
643 | 672 | ||
644 | source "arch/arm/mach-imx/devices/Kconfig" | 673 | source "arch/arm/mach-imx/devices/Kconfig" |
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 6e4fcd8339cd..f5ac685a29fc 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile | |||
@@ -12,7 +12,7 @@ obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci- | |||
12 | obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o | 12 | obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o |
13 | 13 | ||
14 | imx5-pm-$(CONFIG_PM) += pm-imx5.o | 14 | imx5-pm-$(CONFIG_PM) += pm-imx5.o |
15 | obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o clk-imx51-imx53.o $(imx5-pm-y) | 15 | obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o clk-imx51-imx53.o clk-cpu.o $(imx5-pm-y) |
16 | 16 | ||
17 | obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ | 17 | obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ |
18 | clk-pfd.o clk-busy.o clk.o \ | 18 | clk-pfd.o clk-busy.o clk.o \ |
@@ -89,7 +89,7 @@ obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o | |||
89 | obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o | 89 | obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o |
90 | obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o | 90 | obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o |
91 | obj-$(CONFIG_HAVE_IMX_SRC) += src.o | 91 | obj-$(CONFIG_HAVE_IMX_SRC) += src.o |
92 | ifdef CONFIG_SOC_IMX6 | 92 | ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),) |
93 | AFLAGS_headsmp.o :=-Wa,-march=armv7-a | 93 | AFLAGS_headsmp.o :=-Wa,-march=armv7-a |
94 | obj-$(CONFIG_SMP) += headsmp.o platsmp.o | 94 | obj-$(CONFIG_SMP) += headsmp.o platsmp.o |
95 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 95 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
@@ -110,4 +110,6 @@ obj-$(CONFIG_SOC_IMX53) += mach-imx53.o | |||
110 | 110 | ||
111 | obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o | 111 | obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o |
112 | 112 | ||
113 | obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o | ||
114 | |||
113 | obj-y += devices/ | 115 | obj-y += devices/ |
diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 8259a625a920..7f262fe4ba77 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c | |||
@@ -30,8 +30,11 @@ | |||
30 | #define ANADIG_DIGPROG_IMX6SL 0x280 | 30 | #define ANADIG_DIGPROG_IMX6SL 0x280 |
31 | 31 | ||
32 | #define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 | 32 | #define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 |
33 | #define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN 0x8 | ||
33 | #define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000 | 34 | #define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000 |
34 | #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000 | 35 | #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000 |
36 | /* Below MISC0_DISCON_HIGH_SNVS is only for i.MX6SL */ | ||
37 | #define BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS 0x2000 | ||
35 | #define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000 | 38 | #define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000 |
36 | #define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000 | 39 | #define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000 |
37 | 40 | ||
@@ -56,16 +59,43 @@ static void imx_anatop_enable_fet_odrive(bool enable) | |||
56 | BM_ANADIG_REG_CORE_FET_ODRIVE); | 59 | BM_ANADIG_REG_CORE_FET_ODRIVE); |
57 | } | 60 | } |
58 | 61 | ||
62 | static inline void imx_anatop_enable_2p5_pulldown(bool enable) | ||
63 | { | ||
64 | regmap_write(anatop, ANADIG_REG_2P5 + (enable ? REG_SET : REG_CLR), | ||
65 | BM_ANADIG_REG_2P5_ENABLE_PULLDOWN); | ||
66 | } | ||
67 | |||
68 | static inline void imx_anatop_disconnect_high_snvs(bool enable) | ||
69 | { | ||
70 | regmap_write(anatop, ANADIG_ANA_MISC0 + (enable ? REG_SET : REG_CLR), | ||
71 | BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS); | ||
72 | } | ||
73 | |||
59 | void imx_anatop_pre_suspend(void) | 74 | void imx_anatop_pre_suspend(void) |
60 | { | 75 | { |
61 | imx_anatop_enable_weak2p5(true); | 76 | if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2) |
77 | imx_anatop_enable_2p5_pulldown(true); | ||
78 | else | ||
79 | imx_anatop_enable_weak2p5(true); | ||
80 | |||
62 | imx_anatop_enable_fet_odrive(true); | 81 | imx_anatop_enable_fet_odrive(true); |
82 | |||
83 | if (cpu_is_imx6sl()) | ||
84 | imx_anatop_disconnect_high_snvs(true); | ||
63 | } | 85 | } |
64 | 86 | ||
65 | void imx_anatop_post_resume(void) | 87 | void imx_anatop_post_resume(void) |
66 | { | 88 | { |
89 | if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2) | ||
90 | imx_anatop_enable_2p5_pulldown(false); | ||
91 | else | ||
92 | imx_anatop_enable_weak2p5(false); | ||
93 | |||
67 | imx_anatop_enable_fet_odrive(false); | 94 | imx_anatop_enable_fet_odrive(false); |
68 | imx_anatop_enable_weak2p5(false); | 95 | |
96 | if (cpu_is_imx6sl()) | ||
97 | imx_anatop_disconnect_high_snvs(false); | ||
98 | |||
69 | } | 99 | } |
70 | 100 | ||
71 | static void imx_anatop_usb_chrg_detect_disable(void) | 101 | static void imx_anatop_usb_chrg_detect_disable(void) |
diff --git a/arch/arm/mach-imx/clk-cpu.c b/arch/arm/mach-imx/clk-cpu.c new file mode 100644 index 000000000000..aa1c345e2a19 --- /dev/null +++ b/arch/arm/mach-imx/clk-cpu.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Lucas Stach <l.stach@pengutronix.de>, Pengutronix | ||
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 | * http://www.opensource.org/licenses/gpl-license.html | ||
9 | * http://www.gnu.org/copyleft/gpl.html | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk.h> | ||
13 | #include <linux/clk-provider.h> | ||
14 | #include <linux/slab.h> | ||
15 | |||
16 | struct clk_cpu { | ||
17 | struct clk_hw hw; | ||
18 | struct clk *div; | ||
19 | struct clk *mux; | ||
20 | struct clk *pll; | ||
21 | struct clk *step; | ||
22 | }; | ||
23 | |||
24 | static inline struct clk_cpu *to_clk_cpu(struct clk_hw *hw) | ||
25 | { | ||
26 | return container_of(hw, struct clk_cpu, hw); | ||
27 | } | ||
28 | |||
29 | static unsigned long clk_cpu_recalc_rate(struct clk_hw *hw, | ||
30 | unsigned long parent_rate) | ||
31 | { | ||
32 | struct clk_cpu *cpu = to_clk_cpu(hw); | ||
33 | |||
34 | return clk_get_rate(cpu->div); | ||
35 | } | ||
36 | |||
37 | static long clk_cpu_round_rate(struct clk_hw *hw, unsigned long rate, | ||
38 | unsigned long *prate) | ||
39 | { | ||
40 | struct clk_cpu *cpu = to_clk_cpu(hw); | ||
41 | |||
42 | return clk_round_rate(cpu->pll, rate); | ||
43 | } | ||
44 | |||
45 | static int clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate, | ||
46 | unsigned long parent_rate) | ||
47 | { | ||
48 | struct clk_cpu *cpu = to_clk_cpu(hw); | ||
49 | int ret; | ||
50 | |||
51 | /* switch to PLL bypass clock */ | ||
52 | ret = clk_set_parent(cpu->mux, cpu->step); | ||
53 | if (ret) | ||
54 | return ret; | ||
55 | |||
56 | /* reprogram PLL */ | ||
57 | ret = clk_set_rate(cpu->pll, rate); | ||
58 | if (ret) { | ||
59 | clk_set_parent(cpu->mux, cpu->pll); | ||
60 | return ret; | ||
61 | } | ||
62 | /* switch back to PLL clock */ | ||
63 | clk_set_parent(cpu->mux, cpu->pll); | ||
64 | |||
65 | /* Ensure the divider is what we expect */ | ||
66 | clk_set_rate(cpu->div, rate); | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static const struct clk_ops clk_cpu_ops = { | ||
72 | .recalc_rate = clk_cpu_recalc_rate, | ||
73 | .round_rate = clk_cpu_round_rate, | ||
74 | .set_rate = clk_cpu_set_rate, | ||
75 | }; | ||
76 | |||
77 | struct clk *imx_clk_cpu(const char *name, const char *parent_name, | ||
78 | struct clk *div, struct clk *mux, struct clk *pll, | ||
79 | struct clk *step) | ||
80 | { | ||
81 | struct clk_cpu *cpu; | ||
82 | struct clk *clk; | ||
83 | struct clk_init_data init; | ||
84 | |||
85 | cpu = kzalloc(sizeof(*cpu), GFP_KERNEL); | ||
86 | if (!cpu) | ||
87 | return ERR_PTR(-ENOMEM); | ||
88 | |||
89 | cpu->div = div; | ||
90 | cpu->mux = mux; | ||
91 | cpu->pll = pll; | ||
92 | cpu->step = step; | ||
93 | |||
94 | init.name = name; | ||
95 | init.ops = &clk_cpu_ops; | ||
96 | init.flags = 0; | ||
97 | init.parent_names = &parent_name; | ||
98 | init.num_parents = 1; | ||
99 | |||
100 | cpu->hw.init = &init; | ||
101 | |||
102 | clk = clk_register(NULL, &cpu->hw); | ||
103 | if (IS_ERR(clk)) | ||
104 | kfree(cpu); | ||
105 | |||
106 | return clk; | ||
107 | } | ||
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index 72d65214223e..0f7e536147cb 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c | |||
@@ -125,6 +125,8 @@ static const char *mx53_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", "pll4_sw", | |||
125 | static const char *spdif_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "spdif_xtal_sel", }; | 125 | static const char *spdif_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "spdif_xtal_sel", }; |
126 | static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", }; | 126 | static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", }; |
127 | static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", }; | 127 | static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", }; |
128 | static const char *step_sels[] = { "lp_apm", }; | ||
129 | static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" }; | ||
128 | 130 | ||
129 | static struct clk *clk[IMX5_CLK_END]; | 131 | static struct clk *clk[IMX5_CLK_END]; |
130 | static struct clk_onecell_data clk_data; | 132 | static struct clk_onecell_data clk_data; |
@@ -193,7 +195,9 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base) | |||
193 | clk[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3); | 195 | clk[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3); |
194 | clk[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1, | 196 | clk[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1, |
195 | usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str)); | 197 | usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str)); |
196 | clk[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3); | 198 | clk[IMX5_CLK_STEP_SEL] = imx_clk_mux("step_sel", MXC_CCM_CCSR, 7, 2, step_sels, ARRAY_SIZE(step_sels)); |
199 | clk[IMX5_CLK_CPU_PODF_SEL] = imx_clk_mux("cpu_podf_sel", MXC_CCM_CCSR, 2, 1, cpu_podf_sels, ARRAY_SIZE(cpu_podf_sels)); | ||
200 | clk[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf", "cpu_podf_sel", MXC_CCM_CACRR, 0, 3); | ||
197 | clk[IMX5_CLK_DI_PRED] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); | 201 | clk[IMX5_CLK_DI_PRED] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); |
198 | clk[IMX5_CLK_IIM_GATE] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); | 202 | clk[IMX5_CLK_IIM_GATE] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); |
199 | clk[IMX5_CLK_UART1_IPG_GATE] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); | 203 | clk[IMX5_CLK_UART1_IPG_GATE] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); |
@@ -537,6 +541,11 @@ static void __init mx53_clocks_init(struct device_node *np) | |||
537 | clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24); | 541 | clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24); |
538 | clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, | 542 | clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, |
539 | mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel)); | 543 | mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel)); |
544 | clk[IMX5_CLK_ARM] = imx_clk_cpu("arm", "cpu_podf", | ||
545 | clk[IMX5_CLK_CPU_PODF], | ||
546 | clk[IMX5_CLK_CPU_PODF_SEL], | ||
547 | clk[IMX5_CLK_PLL1_SW], | ||
548 | clk[IMX5_CLK_STEP_SEL]); | ||
540 | 549 | ||
541 | imx_check_clocks(clk, ARRAY_SIZE(clk)); | 550 | imx_check_clocks(clk, ARRAY_SIZE(clk)); |
542 | 551 | ||
@@ -551,6 +560,9 @@ static void __init mx53_clocks_init(struct device_node *np) | |||
551 | /* move can bus clk to 24MHz */ | 560 | /* move can bus clk to 24MHz */ |
552 | clk_set_parent(clk[IMX5_CLK_CAN_SEL], clk[IMX5_CLK_LP_APM]); | 561 | clk_set_parent(clk[IMX5_CLK_CAN_SEL], clk[IMX5_CLK_LP_APM]); |
553 | 562 | ||
563 | /* make sure step clock is running from 24MHz */ | ||
564 | clk_set_parent(clk[IMX5_CLK_STEP_SEL], clk[IMX5_CLK_LP_APM]); | ||
565 | |||
554 | clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]); | 566 | clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]); |
555 | imx_print_silicon_rev("i.MX53", mx53_revision()); | 567 | imx_print_silicon_rev("i.MX53", mx53_revision()); |
556 | clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]); | 568 | clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]); |
diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c index 409637254594..5937ddee1a99 100644 --- a/arch/arm/mach-imx/clk-vf610.c +++ b/arch/arm/mach-imx/clk-vf610.c | |||
@@ -120,6 +120,17 @@ static unsigned int const clks_init_on[] __initconst = { | |||
120 | VF610_CLK_DDR_SEL, | 120 | VF610_CLK_DDR_SEL, |
121 | }; | 121 | }; |
122 | 122 | ||
123 | static struct clk * __init vf610_get_fixed_clock( | ||
124 | struct device_node *ccm_node, const char *name) | ||
125 | { | ||
126 | struct clk *clk = of_clk_get_by_name(ccm_node, name); | ||
127 | |||
128 | /* Backward compatibility if device tree is missing clks assignments */ | ||
129 | if (IS_ERR(clk)) | ||
130 | clk = imx_obtain_fixed_clock(name, 0); | ||
131 | return clk; | ||
132 | }; | ||
133 | |||
123 | static void __init vf610_clocks_init(struct device_node *ccm_node) | 134 | static void __init vf610_clocks_init(struct device_node *ccm_node) |
124 | { | 135 | { |
125 | struct device_node *np; | 136 | struct device_node *np; |
@@ -130,13 +141,13 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) | |||
130 | clk[VF610_CLK_SIRC_32K] = imx_clk_fixed("sirc_32k", 32000); | 141 | clk[VF610_CLK_SIRC_32K] = imx_clk_fixed("sirc_32k", 32000); |
131 | clk[VF610_CLK_FIRC] = imx_clk_fixed("firc", 24000000); | 142 | clk[VF610_CLK_FIRC] = imx_clk_fixed("firc", 24000000); |
132 | 143 | ||
133 | clk[VF610_CLK_SXOSC] = imx_obtain_fixed_clock("sxosc", 0); | 144 | clk[VF610_CLK_SXOSC] = vf610_get_fixed_clock(ccm_node, "sxosc"); |
134 | clk[VF610_CLK_FXOSC] = imx_obtain_fixed_clock("fxosc", 0); | 145 | clk[VF610_CLK_FXOSC] = vf610_get_fixed_clock(ccm_node, "fxosc"); |
135 | clk[VF610_CLK_AUDIO_EXT] = imx_obtain_fixed_clock("audio_ext", 0); | 146 | clk[VF610_CLK_AUDIO_EXT] = vf610_get_fixed_clock(ccm_node, "audio_ext"); |
136 | clk[VF610_CLK_ENET_EXT] = imx_obtain_fixed_clock("enet_ext", 0); | 147 | clk[VF610_CLK_ENET_EXT] = vf610_get_fixed_clock(ccm_node, "enet_ext"); |
137 | 148 | ||
138 | /* Clock source from external clock via LVDs PAD */ | 149 | /* Clock source from external clock via LVDs PAD */ |
139 | clk[VF610_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0); | 150 | clk[VF610_CLK_ANACLK1] = vf610_get_fixed_clock(ccm_node, "anaclk1"); |
140 | 151 | ||
141 | clk[VF610_CLK_FXOSC_HALF] = imx_clk_fixed_factor("fxosc_half", "fxosc", 1, 2); | 152 | clk[VF610_CLK_FXOSC_HALF] = imx_clk_fixed_factor("fxosc_half", "fxosc", 1, 2); |
142 | 153 | ||
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h index 4cdf8b6a74e8..5ef82e2f8fc5 100644 --- a/arch/arm/mach-imx/clk.h +++ b/arch/arm/mach-imx/clk.h | |||
@@ -131,4 +131,8 @@ static inline struct clk *imx_clk_fixed_factor(const char *name, | |||
131 | CLK_SET_RATE_PARENT, mult, div); | 131 | CLK_SET_RATE_PARENT, mult, div); |
132 | } | 132 | } |
133 | 133 | ||
134 | struct clk *imx_clk_cpu(const char *name, const char *parent_name, | ||
135 | struct clk *div, struct clk *mux, struct clk *pll, | ||
136 | struct clk *step); | ||
137 | |||
134 | #endif | 138 | #endif |
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 3d383cb5e6d1..cfcdb623d78f 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h | |||
@@ -115,6 +115,7 @@ void imx_anatop_post_resume(void); | |||
115 | int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); | 115 | int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); |
116 | void imx6q_set_int_mem_clk_lpm(bool enable); | 116 | void imx6q_set_int_mem_clk_lpm(bool enable); |
117 | void imx6sl_set_wait_clk(bool enter); | 117 | void imx6sl_set_wait_clk(bool enter); |
118 | int imx_mmdc_get_ddr_type(void); | ||
118 | 119 | ||
119 | void imx_cpu_die(unsigned int cpu); | 120 | void imx_cpu_die(unsigned int cpu); |
120 | int imx_cpu_kill(unsigned int cpu); | 121 | int imx_cpu_kill(unsigned int cpu); |
@@ -156,5 +157,6 @@ static inline void imx_init_l2cache(void) {} | |||
156 | #endif | 157 | #endif |
157 | 158 | ||
158 | extern struct smp_operations imx_smp_ops; | 159 | extern struct smp_operations imx_smp_ops; |
160 | extern struct smp_operations ls1021a_smp_ops; | ||
159 | 161 | ||
160 | #endif | 162 | #endif |
diff --git a/arch/arm/mach-imx/mach-imx53.c b/arch/arm/mach-imx/mach-imx53.c index 18b5c5c136db..86316a979297 100644 --- a/arch/arm/mach-imx/mach-imx53.c +++ b/arch/arm/mach-imx/mach-imx53.c | |||
@@ -40,6 +40,8 @@ static void __init imx53_dt_init(void) | |||
40 | static void __init imx53_init_late(void) | 40 | static void __init imx53_init_late(void) |
41 | { | 41 | { |
42 | imx53_pm_init(); | 42 | imx53_pm_init(); |
43 | |||
44 | platform_device_register_simple("cpufreq-dt", -1, NULL, 0); | ||
43 | } | 45 | } |
44 | 46 | ||
45 | static const char * const imx53_dt_board_compat[] __initconst = { | 47 | static const char * const imx53_dt_board_compat[] __initconst = { |
diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c index 4111c0fa8d09..7a96c6577234 100644 --- a/arch/arm/mach-imx/mach-imx6sx.c +++ b/arch/arm/mach-imx/mach-imx6sx.c | |||
@@ -8,12 +8,62 @@ | |||
8 | 8 | ||
9 | #include <linux/irqchip.h> | 9 | #include <linux/irqchip.h> |
10 | #include <linux/of_platform.h> | 10 | #include <linux/of_platform.h> |
11 | #include <linux/phy.h> | ||
12 | #include <linux/regmap.h> | ||
13 | #include <linux/mfd/syscon.h> | ||
14 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> | ||
11 | #include <asm/mach/arch.h> | 15 | #include <asm/mach/arch.h> |
12 | #include <asm/mach/map.h> | 16 | #include <asm/mach/map.h> |
13 | 17 | ||
14 | #include "common.h" | 18 | #include "common.h" |
15 | #include "cpuidle.h" | 19 | #include "cpuidle.h" |
16 | 20 | ||
21 | static int ar8031_phy_fixup(struct phy_device *dev) | ||
22 | { | ||
23 | u16 val; | ||
24 | |||
25 | /* Set RGMII IO voltage to 1.8V */ | ||
26 | phy_write(dev, 0x1d, 0x1f); | ||
27 | phy_write(dev, 0x1e, 0x8); | ||
28 | |||
29 | /* introduce tx clock delay */ | ||
30 | phy_write(dev, 0x1d, 0x5); | ||
31 | val = phy_read(dev, 0x1e); | ||
32 | val |= 0x0100; | ||
33 | phy_write(dev, 0x1e, val); | ||
34 | |||
35 | return 0; | ||
36 | } | ||
37 | |||
38 | #define PHY_ID_AR8031 0x004dd074 | ||
39 | static void __init imx6sx_enet_phy_init(void) | ||
40 | { | ||
41 | if (IS_BUILTIN(CONFIG_PHYLIB)) | ||
42 | phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff, | ||
43 | ar8031_phy_fixup); | ||
44 | } | ||
45 | |||
46 | static void __init imx6sx_enet_clk_sel(void) | ||
47 | { | ||
48 | struct regmap *gpr; | ||
49 | |||
50 | gpr = syscon_regmap_lookup_by_compatible("fsl,imx6sx-iomuxc-gpr"); | ||
51 | if (!IS_ERR(gpr)) { | ||
52 | regmap_update_bits(gpr, IOMUXC_GPR1, | ||
53 | IMX6SX_GPR1_FEC_CLOCK_MUX_SEL_MASK, 0); | ||
54 | regmap_update_bits(gpr, IOMUXC_GPR1, | ||
55 | IMX6SX_GPR1_FEC_CLOCK_PAD_DIR_MASK, 0); | ||
56 | } else { | ||
57 | pr_err("failed to find fsl,imx6sx-iomux-gpr regmap\n"); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | static inline void imx6sx_enet_init(void) | ||
62 | { | ||
63 | imx6sx_enet_phy_init(); | ||
64 | imx6sx_enet_clk_sel(); | ||
65 | } | ||
66 | |||
17 | static void __init imx6sx_init_machine(void) | 67 | static void __init imx6sx_init_machine(void) |
18 | { | 68 | { |
19 | struct device *parent; | 69 | struct device *parent; |
@@ -24,6 +74,7 @@ static void __init imx6sx_init_machine(void) | |||
24 | 74 | ||
25 | of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); | 75 | of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); |
26 | 76 | ||
77 | imx6sx_enet_init(); | ||
27 | imx_anatop_init(); | 78 | imx_anatop_init(); |
28 | imx6sx_pm_init(); | 79 | imx6sx_pm_init(); |
29 | } | 80 | } |
diff --git a/arch/arm/mach-imx/mach-ls1021a.c b/arch/arm/mach-imx/mach-ls1021a.c new file mode 100644 index 000000000000..b89c858ebfd6 --- /dev/null +++ b/arch/arm/mach-imx/mach-ls1021a.c | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright 2013-2014 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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <asm/mach/arch.h> | ||
11 | |||
12 | #include "common.h" | ||
13 | |||
14 | static const char * const ls1021a_dt_compat[] __initconst = { | ||
15 | "fsl,ls1021a", | ||
16 | NULL, | ||
17 | }; | ||
18 | |||
19 | DT_MACHINE_START(LS1021A, "Freescale LS1021A") | ||
20 | .smp = smp_ops(ls1021a_smp_ops), | ||
21 | .dt_compat = ls1021a_dt_compat, | ||
22 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c index 7a9686ad994c..3729d90cfa46 100644 --- a/arch/arm/mach-imx/mmdc.c +++ b/arch/arm/mach-imx/mmdc.c | |||
@@ -21,6 +21,12 @@ | |||
21 | #define BP_MMDC_MAPSR_PSD 0 | 21 | #define BP_MMDC_MAPSR_PSD 0 |
22 | #define BP_MMDC_MAPSR_PSS 4 | 22 | #define BP_MMDC_MAPSR_PSS 4 |
23 | 23 | ||
24 | #define MMDC_MDMISC 0x18 | ||
25 | #define BM_MMDC_MDMISC_DDR_TYPE 0x18 | ||
26 | #define BP_MMDC_MDMISC_DDR_TYPE 0x3 | ||
27 | |||
28 | static int ddr_type; | ||
29 | |||
24 | static int imx_mmdc_probe(struct platform_device *pdev) | 30 | static int imx_mmdc_probe(struct platform_device *pdev) |
25 | { | 31 | { |
26 | struct device_node *np = pdev->dev.of_node; | 32 | struct device_node *np = pdev->dev.of_node; |
@@ -31,6 +37,12 @@ static int imx_mmdc_probe(struct platform_device *pdev) | |||
31 | mmdc_base = of_iomap(np, 0); | 37 | mmdc_base = of_iomap(np, 0); |
32 | WARN_ON(!mmdc_base); | 38 | WARN_ON(!mmdc_base); |
33 | 39 | ||
40 | reg = mmdc_base + MMDC_MDMISC; | ||
41 | /* Get ddr type */ | ||
42 | val = readl_relaxed(reg); | ||
43 | ddr_type = (val & BM_MMDC_MDMISC_DDR_TYPE) >> | ||
44 | BP_MMDC_MDMISC_DDR_TYPE; | ||
45 | |||
34 | reg = mmdc_base + MMDC_MAPSR; | 46 | reg = mmdc_base + MMDC_MAPSR; |
35 | 47 | ||
36 | /* Enable automatic power saving */ | 48 | /* Enable automatic power saving */ |
@@ -51,6 +63,11 @@ static int imx_mmdc_probe(struct platform_device *pdev) | |||
51 | return 0; | 63 | return 0; |
52 | } | 64 | } |
53 | 65 | ||
66 | int imx_mmdc_get_ddr_type(void) | ||
67 | { | ||
68 | return ddr_type; | ||
69 | } | ||
70 | |||
54 | static struct of_device_id imx_mmdc_dt_ids[] = { | 71 | static struct of_device_id imx_mmdc_dt_ids[] = { |
55 | { .compatible = "fsl,imx6q-mmdc", }, | 72 | { .compatible = "fsl,imx6q-mmdc", }, |
56 | { /* sentinel */ } | 73 | { /* sentinel */ } |
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index 17a41ca65acf..4c1343df2ba4 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h | |||
@@ -55,6 +55,8 @@ | |||
55 | #define IMX_CHIP_REVISION_3_3 0x33 | 55 | #define IMX_CHIP_REVISION_3_3 0x33 |
56 | #define IMX_CHIP_REVISION_UNKNOWN 0xff | 56 | #define IMX_CHIP_REVISION_UNKNOWN 0xff |
57 | 57 | ||
58 | #define IMX_DDR_TYPE_LPDDR2 1 | ||
59 | |||
58 | #ifndef __ASSEMBLY__ | 60 | #ifndef __ASSEMBLY__ |
59 | extern unsigned int __mxc_cpu_type; | 61 | extern unsigned int __mxc_cpu_type; |
60 | #endif | 62 | #endif |
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index 771bd25c1025..7f270015fe58 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c | |||
@@ -11,7 +11,10 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/of_address.h> | ||
15 | #include <linux/of.h> | ||
14 | #include <linux/smp.h> | 16 | #include <linux/smp.h> |
17 | |||
15 | #include <asm/cacheflush.h> | 18 | #include <asm/cacheflush.h> |
16 | #include <asm/page.h> | 19 | #include <asm/page.h> |
17 | #include <asm/smp_scu.h> | 20 | #include <asm/smp_scu.h> |
@@ -94,3 +97,33 @@ struct smp_operations imx_smp_ops __initdata = { | |||
94 | .cpu_kill = imx_cpu_kill, | 97 | .cpu_kill = imx_cpu_kill, |
95 | #endif | 98 | #endif |
96 | }; | 99 | }; |
100 | |||
101 | #define DCFG_CCSR_SCRATCHRW1 0x200 | ||
102 | |||
103 | static int ls1021a_boot_secondary(unsigned int cpu, struct task_struct *idle) | ||
104 | { | ||
105 | arch_send_wakeup_ipi_mask(cpumask_of(cpu)); | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static void __init ls1021a_smp_prepare_cpus(unsigned int max_cpus) | ||
111 | { | ||
112 | struct device_node *np; | ||
113 | void __iomem *dcfg_base; | ||
114 | unsigned long paddr; | ||
115 | |||
116 | np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcfg"); | ||
117 | dcfg_base = of_iomap(np, 0); | ||
118 | BUG_ON(!dcfg_base); | ||
119 | |||
120 | paddr = virt_to_phys(secondary_startup); | ||
121 | writel_relaxed(cpu_to_be32(paddr), dcfg_base + DCFG_CCSR_SCRATCHRW1); | ||
122 | |||
123 | iounmap(dcfg_base); | ||
124 | } | ||
125 | |||
126 | struct smp_operations ls1021a_smp_ops __initdata = { | ||
127 | .smp_prepare_cpus = ls1021a_smp_prepare_cpus, | ||
128 | .smp_boot_secondary = ls1021a_boot_secondary, | ||
129 | }; | ||
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index d815d1ba27a5..5d2c1bd5f5ef 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c | |||
@@ -88,7 +88,7 @@ struct imx6_pm_base { | |||
88 | }; | 88 | }; |
89 | 89 | ||
90 | struct imx6_pm_socdata { | 90 | struct imx6_pm_socdata { |
91 | u32 cpu_type; | 91 | u32 ddr_type; |
92 | const char *mmdc_compat; | 92 | const char *mmdc_compat; |
93 | const char *src_compat; | 93 | const char *src_compat; |
94 | const char *iomuxc_compat; | 94 | const char *iomuxc_compat; |
@@ -138,7 +138,6 @@ static const u32 imx6sx_mmdc_io_offset[] __initconst = { | |||
138 | }; | 138 | }; |
139 | 139 | ||
140 | static const struct imx6_pm_socdata imx6q_pm_data __initconst = { | 140 | static const struct imx6_pm_socdata imx6q_pm_data __initconst = { |
141 | .cpu_type = MXC_CPU_IMX6Q, | ||
142 | .mmdc_compat = "fsl,imx6q-mmdc", | 141 | .mmdc_compat = "fsl,imx6q-mmdc", |
143 | .src_compat = "fsl,imx6q-src", | 142 | .src_compat = "fsl,imx6q-src", |
144 | .iomuxc_compat = "fsl,imx6q-iomuxc", | 143 | .iomuxc_compat = "fsl,imx6q-iomuxc", |
@@ -148,7 +147,6 @@ static const struct imx6_pm_socdata imx6q_pm_data __initconst = { | |||
148 | }; | 147 | }; |
149 | 148 | ||
150 | static const struct imx6_pm_socdata imx6dl_pm_data __initconst = { | 149 | static const struct imx6_pm_socdata imx6dl_pm_data __initconst = { |
151 | .cpu_type = MXC_CPU_IMX6DL, | ||
152 | .mmdc_compat = "fsl,imx6q-mmdc", | 150 | .mmdc_compat = "fsl,imx6q-mmdc", |
153 | .src_compat = "fsl,imx6q-src", | 151 | .src_compat = "fsl,imx6q-src", |
154 | .iomuxc_compat = "fsl,imx6dl-iomuxc", | 152 | .iomuxc_compat = "fsl,imx6dl-iomuxc", |
@@ -158,7 +156,6 @@ static const struct imx6_pm_socdata imx6dl_pm_data __initconst = { | |||
158 | }; | 156 | }; |
159 | 157 | ||
160 | static const struct imx6_pm_socdata imx6sl_pm_data __initconst = { | 158 | static const struct imx6_pm_socdata imx6sl_pm_data __initconst = { |
161 | .cpu_type = MXC_CPU_IMX6SL, | ||
162 | .mmdc_compat = "fsl,imx6sl-mmdc", | 159 | .mmdc_compat = "fsl,imx6sl-mmdc", |
163 | .src_compat = "fsl,imx6sl-src", | 160 | .src_compat = "fsl,imx6sl-src", |
164 | .iomuxc_compat = "fsl,imx6sl-iomuxc", | 161 | .iomuxc_compat = "fsl,imx6sl-iomuxc", |
@@ -168,7 +165,6 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = { | |||
168 | }; | 165 | }; |
169 | 166 | ||
170 | static const struct imx6_pm_socdata imx6sx_pm_data __initconst = { | 167 | static const struct imx6_pm_socdata imx6sx_pm_data __initconst = { |
171 | .cpu_type = MXC_CPU_IMX6SX, | ||
172 | .mmdc_compat = "fsl,imx6sx-mmdc", | 168 | .mmdc_compat = "fsl,imx6sx-mmdc", |
173 | .src_compat = "fsl,imx6sx-src", | 169 | .src_compat = "fsl,imx6sx-src", |
174 | .iomuxc_compat = "fsl,imx6sx-iomuxc", | 170 | .iomuxc_compat = "fsl,imx6sx-iomuxc", |
@@ -187,7 +183,7 @@ static const struct imx6_pm_socdata imx6sx_pm_data __initconst = { | |||
187 | struct imx6_cpu_pm_info { | 183 | struct imx6_cpu_pm_info { |
188 | phys_addr_t pbase; /* The physical address of pm_info. */ | 184 | phys_addr_t pbase; /* The physical address of pm_info. */ |
189 | phys_addr_t resume_addr; /* The physical resume address for asm code */ | 185 | phys_addr_t resume_addr; /* The physical resume address for asm code */ |
190 | u32 cpu_type; | 186 | u32 ddr_type; |
191 | u32 pm_info_size; /* Size of pm_info. */ | 187 | u32 pm_info_size; /* Size of pm_info. */ |
192 | struct imx6_pm_base mmdc_base; | 188 | struct imx6_pm_base mmdc_base; |
193 | struct imx6_pm_base src_base; | 189 | struct imx6_pm_base src_base; |
@@ -521,7 +517,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) | |||
521 | goto pl310_cache_map_failed; | 517 | goto pl310_cache_map_failed; |
522 | } | 518 | } |
523 | 519 | ||
524 | pm_info->cpu_type = socdata->cpu_type; | 520 | pm_info->ddr_type = imx_mmdc_get_ddr_type(); |
525 | pm_info->mmdc_io_num = socdata->mmdc_io_num; | 521 | pm_info->mmdc_io_num = socdata->mmdc_io_num; |
526 | mmdc_offset_array = socdata->mmdc_io_offset; | 522 | mmdc_offset_array = socdata->mmdc_io_offset; |
527 | 523 | ||
diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S index ca4ea2daf25b..b99987b023fa 100644 --- a/arch/arm/mach-imx/suspend-imx6.S +++ b/arch/arm/mach-imx/suspend-imx6.S | |||
@@ -45,7 +45,7 @@ | |||
45 | */ | 45 | */ |
46 | #define PM_INFO_PBASE_OFFSET 0x0 | 46 | #define PM_INFO_PBASE_OFFSET 0x0 |
47 | #define PM_INFO_RESUME_ADDR_OFFSET 0x4 | 47 | #define PM_INFO_RESUME_ADDR_OFFSET 0x4 |
48 | #define PM_INFO_CPU_TYPE_OFFSET 0x8 | 48 | #define PM_INFO_DDR_TYPE_OFFSET 0x8 |
49 | #define PM_INFO_PM_INFO_SIZE_OFFSET 0xC | 49 | #define PM_INFO_PM_INFO_SIZE_OFFSET 0xC |
50 | #define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10 | 50 | #define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10 |
51 | #define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14 | 51 | #define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14 |
@@ -110,7 +110,7 @@ | |||
110 | ldreq r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET] | 110 | ldreq r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET] |
111 | ldrne r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET] | 111 | ldrne r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET] |
112 | 112 | ||
113 | cmp r3, #MXC_CPU_IMX6SL | 113 | cmp r3, #IMX_DDR_TYPE_LPDDR2 |
114 | bne 4f | 114 | bne 4f |
115 | 115 | ||
116 | /* reset read FIFO, RST_RD_FIFO */ | 116 | /* reset read FIFO, RST_RD_FIFO */ |
@@ -151,7 +151,7 @@ | |||
151 | ENTRY(imx6_suspend) | 151 | ENTRY(imx6_suspend) |
152 | ldr r1, [r0, #PM_INFO_PBASE_OFFSET] | 152 | ldr r1, [r0, #PM_INFO_PBASE_OFFSET] |
153 | ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET] | 153 | ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET] |
154 | ldr r3, [r0, #PM_INFO_CPU_TYPE_OFFSET] | 154 | ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET] |
155 | ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET] | 155 | ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET] |
156 | 156 | ||
157 | /* | 157 | /* |
@@ -209,8 +209,8 @@ poll_dvfs_set: | |||
209 | ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET] | 209 | ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET] |
210 | ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET | 210 | ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET |
211 | add r8, r8, r0 | 211 | add r8, r8, r0 |
212 | /* i.MX6SL's last 3 IOs need special setting */ | 212 | /* LPDDR2's last 3 IOs need special setting */ |
213 | cmp r3, #MXC_CPU_IMX6SL | 213 | cmp r3, #IMX_DDR_TYPE_LPDDR2 |
214 | subeq r7, r7, #0x3 | 214 | subeq r7, r7, #0x3 |
215 | set_mmdc_io_lpm: | 215 | set_mmdc_io_lpm: |
216 | ldr r9, [r8], #0x8 | 216 | ldr r9, [r8], #0x8 |
@@ -218,7 +218,7 @@ set_mmdc_io_lpm: | |||
218 | subs r7, r7, #0x1 | 218 | subs r7, r7, #0x1 |
219 | bne set_mmdc_io_lpm | 219 | bne set_mmdc_io_lpm |
220 | 220 | ||
221 | cmp r3, #MXC_CPU_IMX6SL | 221 | cmp r3, #IMX_DDR_TYPE_LPDDR2 |
222 | bne set_mmdc_io_lpm_done | 222 | bne set_mmdc_io_lpm_done |
223 | ldr r6, =0x1000 | 223 | ldr r6, =0x1000 |
224 | ldr r9, [r8], #0x8 | 224 | ldr r9, [r8], #0x8 |
@@ -324,7 +324,7 @@ resume: | |||
324 | str r7, [r11, #MX6Q_SRC_GPR1] | 324 | str r7, [r11, #MX6Q_SRC_GPR1] |
325 | str r7, [r11, #MX6Q_SRC_GPR2] | 325 | str r7, [r11, #MX6Q_SRC_GPR2] |
326 | 326 | ||
327 | ldr r3, [r0, #PM_INFO_CPU_TYPE_OFFSET] | 327 | ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET] |
328 | mov r5, #0x1 | 328 | mov r5, #0x1 |
329 | resume_mmdc | 329 | resume_mmdc |
330 | 330 | ||
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig index c455e974bbfe..02d083489a26 100644 --- a/arch/arm/mach-integrator/Kconfig +++ b/arch/arm/mach-integrator/Kconfig | |||
@@ -1,3 +1,26 @@ | |||
1 | config ARCH_INTEGRATOR | ||
2 | bool "ARM Ltd. Integrator family" if (ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6) | ||
3 | select ARM_AMBA | ||
4 | select ARM_PATCH_PHYS_VIRT if MMU | ||
5 | select AUTO_ZRELADDR | ||
6 | select COMMON_CLK | ||
7 | select COMMON_CLK_VERSATILE | ||
8 | select GENERIC_CLOCKEVENTS | ||
9 | select HAVE_TCM | ||
10 | select ICST | ||
11 | select MFD_SYSCON | ||
12 | select MULTI_IRQ_HANDLER | ||
13 | select PLAT_VERSATILE | ||
14 | select POWER_RESET | ||
15 | select POWER_RESET_VERSATILE | ||
16 | select POWER_SUPPLY | ||
17 | select SOC_INTEGRATOR_CM | ||
18 | select SPARSE_IRQ | ||
19 | select USE_OF | ||
20 | select VERSATILE_FPGA_IRQ | ||
21 | help | ||
22 | Support for ARM's Integrator platform. | ||
23 | |||
1 | if ARCH_INTEGRATOR | 24 | if ARCH_INTEGRATOR |
2 | 25 | ||
3 | menu "Integrator Options" | 26 | menu "Integrator Options" |
diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile index ec759ded7b60..1ebe45356b09 100644 --- a/arch/arm/mach-integrator/Makefile +++ b/arch/arm/mach-integrator/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | # Object file lists. | 5 | # Object file lists. |
6 | 6 | ||
7 | obj-y := core.o lm.o leds.o | 7 | obj-y := core.o lm.o |
8 | obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o | 8 | obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o |
9 | obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o | 9 | obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o |
10 | 10 | ||
diff --git a/arch/arm/mach-integrator/cm.h b/arch/arm/mach-integrator/cm.h index 4ecff7bff482..5b8ba8247f45 100644 --- a/arch/arm/mach-integrator/cm.h +++ b/arch/arm/mach-integrator/cm.h | |||
@@ -11,7 +11,6 @@ void cm_clear_irqs(void); | |||
11 | #define CM_CTRL_LED (1 << 0) | 11 | #define CM_CTRL_LED (1 << 0) |
12 | #define CM_CTRL_nMBDET (1 << 1) | 12 | #define CM_CTRL_nMBDET (1 << 1) |
13 | #define CM_CTRL_REMAP (1 << 2) | 13 | #define CM_CTRL_REMAP (1 << 2) |
14 | #define CM_CTRL_RESET (1 << 3) | ||
15 | 14 | ||
16 | /* | 15 | /* |
17 | * Integrator/AP,PP2 specific | 16 | * Integrator/AP,PP2 specific |
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h index ad0ac5547b2c..96c9dc56cabf 100644 --- a/arch/arm/mach-integrator/common.h +++ b/arch/arm/mach-integrator/common.h | |||
@@ -4,5 +4,3 @@ extern struct amba_pl010_data ap_uart_data; | |||
4 | void integrator_init_early(void); | 4 | void integrator_init_early(void); |
5 | int integrator_init(bool is_cp); | 5 | int integrator_init(bool is_cp); |
6 | void integrator_reserve(void); | 6 | void integrator_reserve(void); |
7 | void integrator_restart(enum reboot_mode, const char *); | ||
8 | void integrator_init_sysfs(struct device *parent, u32 id); | ||
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index e3f3aca43efb..948872a419c1 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c | |||
@@ -60,40 +60,6 @@ void cm_control(u32 mask, u32 set) | |||
60 | raw_spin_unlock_irqrestore(&cm_lock, flags); | 60 | raw_spin_unlock_irqrestore(&cm_lock, flags); |
61 | } | 61 | } |
62 | 62 | ||
63 | static const char *integrator_arch_str(u32 id) | ||
64 | { | ||
65 | switch ((id >> 16) & 0xff) { | ||
66 | case 0x00: | ||
67 | return "ASB little-endian"; | ||
68 | case 0x01: | ||
69 | return "AHB little-endian"; | ||
70 | case 0x03: | ||
71 | return "AHB-Lite system bus, bi-endian"; | ||
72 | case 0x04: | ||
73 | return "AHB"; | ||
74 | case 0x08: | ||
75 | return "AHB system bus, ASB processor bus"; | ||
76 | default: | ||
77 | return "Unknown"; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | static const char *integrator_fpga_str(u32 id) | ||
82 | { | ||
83 | switch ((id >> 12) & 0xf) { | ||
84 | case 0x01: | ||
85 | return "XC4062"; | ||
86 | case 0x02: | ||
87 | return "XC4085"; | ||
88 | case 0x03: | ||
89 | return "XVC600"; | ||
90 | case 0x04: | ||
91 | return "EPM7256AE (Altera PLD)"; | ||
92 | default: | ||
93 | return "Unknown"; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | void cm_clear_irqs(void) | 63 | void cm_clear_irqs(void) |
98 | { | 64 | { |
99 | /* disable core module IRQs */ | 65 | /* disable core module IRQs */ |
@@ -109,7 +75,6 @@ static const struct of_device_id cm_match[] = { | |||
109 | void cm_init(void) | 75 | void cm_init(void) |
110 | { | 76 | { |
111 | struct device_node *cm = of_find_matching_node(NULL, cm_match); | 77 | struct device_node *cm = of_find_matching_node(NULL, cm_match); |
112 | u32 val; | ||
113 | 78 | ||
114 | if (!cm) { | 79 | if (!cm) { |
115 | pr_crit("no core module node found in device tree\n"); | 80 | pr_crit("no core module node found in device tree\n"); |
@@ -121,13 +86,6 @@ void cm_init(void) | |||
121 | return; | 86 | return; |
122 | } | 87 | } |
123 | cm_clear_irqs(); | 88 | cm_clear_irqs(); |
124 | val = readl(cm_base + INTEGRATOR_HDR_ID_OFFSET); | ||
125 | pr_info("Detected ARM core module:\n"); | ||
126 | pr_info(" Manufacturer: %02x\n", (val >> 24)); | ||
127 | pr_info(" Architecture: %s\n", integrator_arch_str(val)); | ||
128 | pr_info(" FPGA: %s\n", integrator_fpga_str(val)); | ||
129 | pr_info(" Build: %02x\n", (val >> 4) & 0xFF); | ||
130 | pr_info(" Rev: %c\n", ('A' + (val & 0x03))); | ||
131 | } | 89 | } |
132 | 90 | ||
133 | /* | 91 | /* |
@@ -139,64 +97,3 @@ void __init integrator_reserve(void) | |||
139 | { | 97 | { |
140 | memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET); | 98 | memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET); |
141 | } | 99 | } |
142 | |||
143 | /* | ||
144 | * To reset, we hit the on-board reset register in the system FPGA | ||
145 | */ | ||
146 | void integrator_restart(enum reboot_mode mode, const char *cmd) | ||
147 | { | ||
148 | cm_control(CM_CTRL_RESET, CM_CTRL_RESET); | ||
149 | } | ||
150 | |||
151 | static u32 integrator_id; | ||
152 | |||
153 | static ssize_t intcp_get_manf(struct device *dev, | ||
154 | struct device_attribute *attr, | ||
155 | char *buf) | ||
156 | { | ||
157 | return sprintf(buf, "%02x\n", integrator_id >> 24); | ||
158 | } | ||
159 | |||
160 | static struct device_attribute intcp_manf_attr = | ||
161 | __ATTR(manufacturer, S_IRUGO, intcp_get_manf, NULL); | ||
162 | |||
163 | static ssize_t intcp_get_arch(struct device *dev, | ||
164 | struct device_attribute *attr, | ||
165 | char *buf) | ||
166 | { | ||
167 | return sprintf(buf, "%s\n", integrator_arch_str(integrator_id)); | ||
168 | } | ||
169 | |||
170 | static struct device_attribute intcp_arch_attr = | ||
171 | __ATTR(architecture, S_IRUGO, intcp_get_arch, NULL); | ||
172 | |||
173 | static ssize_t intcp_get_fpga(struct device *dev, | ||
174 | struct device_attribute *attr, | ||
175 | char *buf) | ||
176 | { | ||
177 | return sprintf(buf, "%s\n", integrator_fpga_str(integrator_id)); | ||
178 | } | ||
179 | |||
180 | static struct device_attribute intcp_fpga_attr = | ||
181 | __ATTR(fpga, S_IRUGO, intcp_get_fpga, NULL); | ||
182 | |||
183 | static ssize_t intcp_get_build(struct device *dev, | ||
184 | struct device_attribute *attr, | ||
185 | char *buf) | ||
186 | { | ||
187 | return sprintf(buf, "%02x\n", (integrator_id >> 4) & 0xFF); | ||
188 | } | ||
189 | |||
190 | static struct device_attribute intcp_build_attr = | ||
191 | __ATTR(build, S_IRUGO, intcp_get_build, NULL); | ||
192 | |||
193 | |||
194 | |||
195 | void integrator_init_sysfs(struct device *parent, u32 id) | ||
196 | { | ||
197 | integrator_id = id; | ||
198 | device_create_file(parent, &intcp_manf_attr); | ||
199 | device_create_file(parent, &intcp_arch_attr); | ||
200 | device_create_file(parent, &intcp_fpga_attr); | ||
201 | device_create_file(parent, &intcp_build_attr); | ||
202 | } | ||
diff --git a/arch/arm/mach-integrator/include/mach/uncompress.h b/arch/arm/mach-integrator/include/mach/uncompress.h deleted file mode 100644 index 8f3cc9954c16..000000000000 --- a/arch/arm/mach-integrator/include/mach/uncompress.h +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-integrator/include/mach/uncompress.h | ||
3 | * | ||
4 | * Copyright (C) 1999 ARM Limited | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #define AMBA_UART_DR (*(volatile unsigned char *)0x16000000) | ||
22 | #define AMBA_UART_LCRH (*(volatile unsigned char *)0x16000008) | ||
23 | #define AMBA_UART_LCRM (*(volatile unsigned char *)0x1600000c) | ||
24 | #define AMBA_UART_LCRL (*(volatile unsigned char *)0x16000010) | ||
25 | #define AMBA_UART_CR (*(volatile unsigned char *)0x16000014) | ||
26 | #define AMBA_UART_FR (*(volatile unsigned char *)0x16000018) | ||
27 | |||
28 | /* | ||
29 | * This does not append a newline | ||
30 | */ | ||
31 | static void putc(int c) | ||
32 | { | ||
33 | while (AMBA_UART_FR & (1 << 5)) | ||
34 | barrier(); | ||
35 | |||
36 | AMBA_UART_DR = c; | ||
37 | } | ||
38 | |||
39 | static inline void flush(void) | ||
40 | { | ||
41 | while (AMBA_UART_FR & (1 << 3)) | ||
42 | barrier(); | ||
43 | } | ||
44 | |||
45 | /* | ||
46 | * nothing to do | ||
47 | */ | ||
48 | #define arch_decomp_setup() | ||
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 8ca290b479b1..30003ba447a5 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c | |||
@@ -27,22 +27,15 @@ | |||
27 | #include <linux/syscore_ops.h> | 27 | #include <linux/syscore_ops.h> |
28 | #include <linux/amba/bus.h> | 28 | #include <linux/amba/bus.h> |
29 | #include <linux/amba/kmi.h> | 29 | #include <linux/amba/kmi.h> |
30 | #include <linux/clocksource.h> | ||
31 | #include <linux/clockchips.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/io.h> | 30 | #include <linux/io.h> |
34 | #include <linux/irqchip.h> | 31 | #include <linux/irqchip.h> |
35 | #include <linux/mtd/physmap.h> | 32 | #include <linux/mtd/physmap.h> |
36 | #include <linux/clk.h> | ||
37 | #include <linux/platform_data/clk-integrator.h> | 33 | #include <linux/platform_data/clk-integrator.h> |
38 | #include <linux/of_irq.h> | 34 | #include <linux/of_irq.h> |
39 | #include <linux/of_address.h> | 35 | #include <linux/of_address.h> |
40 | #include <linux/of_platform.h> | 36 | #include <linux/of_platform.h> |
41 | #include <linux/stat.h> | 37 | #include <linux/stat.h> |
42 | #include <linux/sys_soc.h> | ||
43 | #include <linux/termios.h> | 38 | #include <linux/termios.h> |
44 | #include <linux/sched_clock.h> | ||
45 | #include <linux/clk-provider.h> | ||
46 | 39 | ||
47 | #include <asm/hardware/arm_timer.h> | 40 | #include <asm/hardware/arm_timer.h> |
48 | #include <asm/setup.h> | 41 | #include <asm/setup.h> |
@@ -89,11 +82,6 @@ static void __iomem *ebi_base; | |||
89 | 82 | ||
90 | static struct map_desc ap_io_desc[] __initdata __maybe_unused = { | 83 | static struct map_desc ap_io_desc[] __initdata __maybe_unused = { |
91 | { | 84 | { |
92 | .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE), | ||
93 | .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE), | ||
94 | .length = SZ_4K, | ||
95 | .type = MT_DEVICE | ||
96 | }, { | ||
97 | .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE), | 85 | .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE), |
98 | .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE), | 86 | .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE), |
99 | .length = SZ_4K, | 87 | .length = SZ_4K, |
@@ -257,188 +245,10 @@ struct amba_pl010_data ap_uart_data = { | |||
257 | .set_mctrl = integrator_uart_set_mctrl, | 245 | .set_mctrl = integrator_uart_set_mctrl, |
258 | }; | 246 | }; |
259 | 247 | ||
260 | /* | ||
261 | * Where is the timer (VA)? | ||
262 | */ | ||
263 | #define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE) | ||
264 | #define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE) | ||
265 | #define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE) | ||
266 | |||
267 | static unsigned long timer_reload; | ||
268 | |||
269 | static u64 notrace integrator_read_sched_clock(void) | ||
270 | { | ||
271 | return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE); | ||
272 | } | ||
273 | |||
274 | static void integrator_clocksource_init(unsigned long inrate, | ||
275 | void __iomem *base) | ||
276 | { | ||
277 | u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; | ||
278 | unsigned long rate = inrate; | ||
279 | |||
280 | if (rate >= 1500000) { | ||
281 | rate /= 16; | ||
282 | ctrl |= TIMER_CTRL_DIV16; | ||
283 | } | ||
284 | |||
285 | writel(0xffff, base + TIMER_LOAD); | ||
286 | writel(ctrl, base + TIMER_CTRL); | ||
287 | |||
288 | clocksource_mmio_init(base + TIMER_VALUE, "timer2", | ||
289 | rate, 200, 16, clocksource_mmio_readl_down); | ||
290 | sched_clock_register(integrator_read_sched_clock, 16, rate); | ||
291 | } | ||
292 | |||
293 | static void __iomem * clkevt_base; | ||
294 | |||
295 | /* | ||
296 | * IRQ handler for the timer | ||
297 | */ | ||
298 | static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id) | ||
299 | { | ||
300 | struct clock_event_device *evt = dev_id; | ||
301 | |||
302 | /* clear the interrupt */ | ||
303 | writel(1, clkevt_base + TIMER_INTCLR); | ||
304 | |||
305 | evt->event_handler(evt); | ||
306 | |||
307 | return IRQ_HANDLED; | ||
308 | } | ||
309 | |||
310 | static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) | ||
311 | { | ||
312 | u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE; | ||
313 | |||
314 | /* Disable timer */ | ||
315 | writel(ctrl, clkevt_base + TIMER_CTRL); | ||
316 | |||
317 | switch (mode) { | ||
318 | case CLOCK_EVT_MODE_PERIODIC: | ||
319 | /* Enable the timer and start the periodic tick */ | ||
320 | writel(timer_reload, clkevt_base + TIMER_LOAD); | ||
321 | ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; | ||
322 | writel(ctrl, clkevt_base + TIMER_CTRL); | ||
323 | break; | ||
324 | case CLOCK_EVT_MODE_ONESHOT: | ||
325 | /* Leave the timer disabled, .set_next_event will enable it */ | ||
326 | ctrl &= ~TIMER_CTRL_PERIODIC; | ||
327 | writel(ctrl, clkevt_base + TIMER_CTRL); | ||
328 | break; | ||
329 | case CLOCK_EVT_MODE_UNUSED: | ||
330 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
331 | case CLOCK_EVT_MODE_RESUME: | ||
332 | default: | ||
333 | /* Just leave in disabled state */ | ||
334 | break; | ||
335 | } | ||
336 | |||
337 | } | ||
338 | |||
339 | static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt) | ||
340 | { | ||
341 | unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); | ||
342 | |||
343 | writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); | ||
344 | writel(next, clkevt_base + TIMER_LOAD); | ||
345 | writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static struct clock_event_device integrator_clockevent = { | ||
351 | .name = "timer1", | ||
352 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
353 | .set_mode = clkevt_set_mode, | ||
354 | .set_next_event = clkevt_set_next_event, | ||
355 | .rating = 300, | ||
356 | }; | ||
357 | |||
358 | static struct irqaction integrator_timer_irq = { | ||
359 | .name = "timer", | ||
360 | .flags = IRQF_TIMER | IRQF_IRQPOLL, | ||
361 | .handler = integrator_timer_interrupt, | ||
362 | .dev_id = &integrator_clockevent, | ||
363 | }; | ||
364 | |||
365 | static void integrator_clockevent_init(unsigned long inrate, | ||
366 | void __iomem *base, int irq) | ||
367 | { | ||
368 | unsigned long rate = inrate; | ||
369 | unsigned int ctrl = 0; | ||
370 | |||
371 | clkevt_base = base; | ||
372 | /* Calculate and program a divisor */ | ||
373 | if (rate > 0x100000 * HZ) { | ||
374 | rate /= 256; | ||
375 | ctrl |= TIMER_CTRL_DIV256; | ||
376 | } else if (rate > 0x10000 * HZ) { | ||
377 | rate /= 16; | ||
378 | ctrl |= TIMER_CTRL_DIV16; | ||
379 | } | ||
380 | timer_reload = rate / HZ; | ||
381 | writel(ctrl, clkevt_base + TIMER_CTRL); | ||
382 | |||
383 | setup_irq(irq, &integrator_timer_irq); | ||
384 | clockevents_config_and_register(&integrator_clockevent, | ||
385 | rate, | ||
386 | 1, | ||
387 | 0xffffU); | ||
388 | } | ||
389 | |||
390 | void __init ap_init_early(void) | 248 | void __init ap_init_early(void) |
391 | { | 249 | { |
392 | } | 250 | } |
393 | 251 | ||
394 | static void __init ap_of_timer_init(void) | ||
395 | { | ||
396 | struct device_node *node; | ||
397 | const char *path; | ||
398 | void __iomem *base; | ||
399 | int err; | ||
400 | int irq; | ||
401 | struct clk *clk; | ||
402 | unsigned long rate; | ||
403 | |||
404 | of_clk_init(NULL); | ||
405 | |||
406 | err = of_property_read_string(of_aliases, | ||
407 | "arm,timer-primary", &path); | ||
408 | if (WARN_ON(err)) | ||
409 | return; | ||
410 | node = of_find_node_by_path(path); | ||
411 | base = of_iomap(node, 0); | ||
412 | if (WARN_ON(!base)) | ||
413 | return; | ||
414 | |||
415 | clk = of_clk_get(node, 0); | ||
416 | BUG_ON(IS_ERR(clk)); | ||
417 | clk_prepare_enable(clk); | ||
418 | rate = clk_get_rate(clk); | ||
419 | |||
420 | writel(0, base + TIMER_CTRL); | ||
421 | integrator_clocksource_init(rate, base); | ||
422 | |||
423 | err = of_property_read_string(of_aliases, | ||
424 | "arm,timer-secondary", &path); | ||
425 | if (WARN_ON(err)) | ||
426 | return; | ||
427 | node = of_find_node_by_path(path); | ||
428 | base = of_iomap(node, 0); | ||
429 | if (WARN_ON(!base)) | ||
430 | return; | ||
431 | irq = irq_of_parse_and_map(node, 0); | ||
432 | |||
433 | clk = of_clk_get(node, 0); | ||
434 | BUG_ON(IS_ERR(clk)); | ||
435 | clk_prepare_enable(clk); | ||
436 | rate = clk_get_rate(clk); | ||
437 | |||
438 | writel(0, base + TIMER_CTRL); | ||
439 | integrator_clockevent_init(rate, base, irq); | ||
440 | } | ||
441 | |||
442 | static void __init ap_init_irq_of(void) | 252 | static void __init ap_init_irq_of(void) |
443 | { | 253 | { |
444 | cm_init(); | 254 | cm_init(); |
@@ -477,10 +287,6 @@ static void __init ap_init_of(void) | |||
477 | unsigned long sc_dec; | 287 | unsigned long sc_dec; |
478 | struct device_node *syscon; | 288 | struct device_node *syscon; |
479 | struct device_node *ebi; | 289 | struct device_node *ebi; |
480 | struct device *parent; | ||
481 | struct soc_device *soc_dev; | ||
482 | struct soc_device_attribute *soc_dev_attr; | ||
483 | u32 ap_sc_id; | ||
484 | int i; | 290 | int i; |
485 | 291 | ||
486 | syscon = of_find_matching_node(NULL, ap_syscon_match); | 292 | syscon = of_find_matching_node(NULL, ap_syscon_match); |
@@ -500,28 +306,6 @@ static void __init ap_init_of(void) | |||
500 | of_platform_populate(NULL, of_default_bus_match_table, | 306 | of_platform_populate(NULL, of_default_bus_match_table, |
501 | ap_auxdata_lookup, NULL); | 307 | ap_auxdata_lookup, NULL); |
502 | 308 | ||
503 | ap_sc_id = readl(ap_syscon_base); | ||
504 | |||
505 | soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); | ||
506 | if (!soc_dev_attr) | ||
507 | return; | ||
508 | |||
509 | soc_dev_attr->soc_id = "XVC"; | ||
510 | soc_dev_attr->machine = "Integrator/AP"; | ||
511 | soc_dev_attr->family = "Integrator"; | ||
512 | soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c", | ||
513 | 'A' + (ap_sc_id & 0x0f)); | ||
514 | |||
515 | soc_dev = soc_device_register(soc_dev_attr); | ||
516 | if (IS_ERR(soc_dev)) { | ||
517 | kfree(soc_dev_attr->revision); | ||
518 | kfree(soc_dev_attr); | ||
519 | return; | ||
520 | } | ||
521 | |||
522 | parent = soc_device_to_device(soc_dev); | ||
523 | integrator_init_sysfs(parent, ap_sc_id); | ||
524 | |||
525 | sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET); | 309 | sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET); |
526 | for (i = 0; i < 4; i++) { | 310 | for (i = 0; i < 4; i++) { |
527 | struct lm_device *lmdev; | 311 | struct lm_device *lmdev; |
@@ -553,8 +337,6 @@ DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)") | |||
553 | .map_io = ap_map_io, | 337 | .map_io = ap_map_io, |
554 | .init_early = ap_init_early, | 338 | .init_early = ap_init_early, |
555 | .init_irq = ap_init_irq_of, | 339 | .init_irq = ap_init_irq_of, |
556 | .init_time = ap_of_timer_init, | ||
557 | .init_machine = ap_init_of, | 340 | .init_machine = ap_init_of, |
558 | .restart = integrator_restart, | ||
559 | .dt_compat = ap_dt_board_compat, | 341 | .dt_compat = ap_dt_board_compat, |
560 | MACHINE_END | 342 | MACHINE_END |
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index cca02eb75eb5..b5fb71a36ee6 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/of_irq.h> | 27 | #include <linux/of_irq.h> |
28 | #include <linux/of_address.h> | 28 | #include <linux/of_address.h> |
29 | #include <linux/of_platform.h> | 29 | #include <linux/of_platform.h> |
30 | #include <linux/sys_soc.h> | ||
31 | #include <linux/sched_clock.h> | 30 | #include <linux/sched_clock.h> |
32 | 31 | ||
33 | #include <asm/setup.h> | 32 | #include <asm/setup.h> |
@@ -274,10 +273,6 @@ static const struct of_device_id intcp_syscon_match[] = { | |||
274 | static void __init intcp_init_of(void) | 273 | static void __init intcp_init_of(void) |
275 | { | 274 | { |
276 | struct device_node *cpcon; | 275 | struct device_node *cpcon; |
277 | struct device *parent; | ||
278 | struct soc_device *soc_dev; | ||
279 | struct soc_device_attribute *soc_dev_attr; | ||
280 | u32 intcp_sc_id; | ||
281 | 276 | ||
282 | cpcon = of_find_matching_node(NULL, intcp_syscon_match); | 277 | cpcon = of_find_matching_node(NULL, intcp_syscon_match); |
283 | if (!cpcon) | 278 | if (!cpcon) |
@@ -289,28 +284,6 @@ static void __init intcp_init_of(void) | |||
289 | 284 | ||
290 | of_platform_populate(NULL, of_default_bus_match_table, | 285 | of_platform_populate(NULL, of_default_bus_match_table, |
291 | intcp_auxdata_lookup, NULL); | 286 | intcp_auxdata_lookup, NULL); |
292 | |||
293 | intcp_sc_id = readl(intcp_con_base); | ||
294 | |||
295 | soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); | ||
296 | if (!soc_dev_attr) | ||
297 | return; | ||
298 | |||
299 | soc_dev_attr->soc_id = "XCV"; | ||
300 | soc_dev_attr->machine = "Integrator/CP"; | ||
301 | soc_dev_attr->family = "Integrator"; | ||
302 | soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c", | ||
303 | 'A' + (intcp_sc_id & 0x0f)); | ||
304 | |||
305 | soc_dev = soc_device_register(soc_dev_attr); | ||
306 | if (IS_ERR(soc_dev)) { | ||
307 | kfree(soc_dev_attr->revision); | ||
308 | kfree(soc_dev_attr); | ||
309 | return; | ||
310 | } | ||
311 | |||
312 | parent = soc_device_to_device(soc_dev); | ||
313 | integrator_init_sysfs(parent, intcp_sc_id); | ||
314 | } | 287 | } |
315 | 288 | ||
316 | static const char * intcp_dt_board_compat[] = { | 289 | static const char * intcp_dt_board_compat[] = { |
@@ -324,6 +297,5 @@ DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)") | |||
324 | .init_early = intcp_init_early, | 297 | .init_early = intcp_init_early, |
325 | .init_irq = intcp_init_irq_of, | 298 | .init_irq = intcp_init_irq_of, |
326 | .init_machine = intcp_init_of, | 299 | .init_machine = intcp_init_of, |
327 | .restart = integrator_restart, | ||
328 | .dt_compat = intcp_dt_board_compat, | 300 | .dt_compat = intcp_dt_board_compat, |
329 | MACHINE_END | 301 | MACHINE_END |
diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c deleted file mode 100644 index f1dcb57a59e2..000000000000 --- a/arch/arm/mach-integrator/leds.c +++ /dev/null | |||
@@ -1,124 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for the 4 user LEDs found on the Integrator AP/CP baseboard | ||
3 | * Based on Versatile and RealView machine LED code | ||
4 | * | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | * Author: Bryan Wu <bryan.wu@canonical.com> | ||
7 | */ | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/io.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/leds.h> | ||
13 | |||
14 | #include "hardware.h" | ||
15 | #include "cm.h" | ||
16 | |||
17 | #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) | ||
18 | |||
19 | #define ALPHA_REG __io_address(INTEGRATOR_DBG_BASE) | ||
20 | #define LEDREG (__io_address(INTEGRATOR_DBG_BASE) + INTEGRATOR_DBG_LEDS_OFFSET) | ||
21 | |||
22 | struct integrator_led { | ||
23 | struct led_classdev cdev; | ||
24 | u8 mask; | ||
25 | }; | ||
26 | |||
27 | /* | ||
28 | * The triggers lines up below will only be used if the | ||
29 | * LED triggers are compiled in. | ||
30 | */ | ||
31 | static const struct { | ||
32 | const char *name; | ||
33 | const char *trigger; | ||
34 | } integrator_leds[] = { | ||
35 | { "integrator:green0", "heartbeat", }, | ||
36 | { "integrator:yellow", }, | ||
37 | { "integrator:red", }, | ||
38 | { "integrator:green1", }, | ||
39 | { "integrator:core_module", "cpu0", }, | ||
40 | }; | ||
41 | |||
42 | static void integrator_led_set(struct led_classdev *cdev, | ||
43 | enum led_brightness b) | ||
44 | { | ||
45 | struct integrator_led *led = container_of(cdev, | ||
46 | struct integrator_led, cdev); | ||
47 | u32 reg = __raw_readl(LEDREG); | ||
48 | |||
49 | if (b != LED_OFF) | ||
50 | reg |= led->mask; | ||
51 | else | ||
52 | reg &= ~led->mask; | ||
53 | |||
54 | while (__raw_readl(ALPHA_REG) & 1) | ||
55 | cpu_relax(); | ||
56 | |||
57 | __raw_writel(reg, LEDREG); | ||
58 | } | ||
59 | |||
60 | static enum led_brightness integrator_led_get(struct led_classdev *cdev) | ||
61 | { | ||
62 | struct integrator_led *led = container_of(cdev, | ||
63 | struct integrator_led, cdev); | ||
64 | u32 reg = __raw_readl(LEDREG); | ||
65 | |||
66 | return (reg & led->mask) ? LED_FULL : LED_OFF; | ||
67 | } | ||
68 | |||
69 | static void cm_led_set(struct led_classdev *cdev, | ||
70 | enum led_brightness b) | ||
71 | { | ||
72 | if (b != LED_OFF) | ||
73 | cm_control(CM_CTRL_LED, CM_CTRL_LED); | ||
74 | else | ||
75 | cm_control(CM_CTRL_LED, 0); | ||
76 | } | ||
77 | |||
78 | static enum led_brightness cm_led_get(struct led_classdev *cdev) | ||
79 | { | ||
80 | u32 reg = cm_get(); | ||
81 | |||
82 | return (reg & CM_CTRL_LED) ? LED_FULL : LED_OFF; | ||
83 | } | ||
84 | |||
85 | static int __init integrator_leds_init(void) | ||
86 | { | ||
87 | int i; | ||
88 | |||
89 | for (i = 0; i < ARRAY_SIZE(integrator_leds); i++) { | ||
90 | struct integrator_led *led; | ||
91 | |||
92 | led = kzalloc(sizeof(*led), GFP_KERNEL); | ||
93 | if (!led) | ||
94 | break; | ||
95 | |||
96 | |||
97 | led->cdev.name = integrator_leds[i].name; | ||
98 | |||
99 | if (i == 4) { /* Setting for LED in core module */ | ||
100 | led->cdev.brightness_set = cm_led_set; | ||
101 | led->cdev.brightness_get = cm_led_get; | ||
102 | } else { | ||
103 | led->cdev.brightness_set = integrator_led_set; | ||
104 | led->cdev.brightness_get = integrator_led_get; | ||
105 | } | ||
106 | |||
107 | led->cdev.default_trigger = integrator_leds[i].trigger; | ||
108 | led->mask = BIT(i); | ||
109 | |||
110 | if (led_classdev_register(NULL, &led->cdev) < 0) { | ||
111 | kfree(led); | ||
112 | break; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Since we may have triggers on any subsystem, defer registration | ||
121 | * until after subsystem_init. | ||
122 | */ | ||
123 | fs_initcall(integrator_leds_init); | ||
124 | #endif | ||
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig index 2c043a210db0..f73f588f649c 100644 --- a/arch/arm/mach-mediatek/Kconfig +++ b/arch/arm/mach-mediatek/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config ARCH_MEDIATEK | 1 | config ARCH_MEDIATEK |
2 | bool "Mediatek MT6589 SoC" if ARCH_MULTI_V7 | 2 | bool "Mediatek MT65xx & MT81xx SoC" if ARCH_MULTI_V7 |
3 | select ARM_GIC | 3 | select ARM_GIC |
4 | select MTK_TIMER | 4 | select MTK_TIMER |
5 | help | 5 | help |
6 | Support for Mediatek Cortex-A7 Quad-Core-SoC MT6589. | 6 | Support for Mediatek MT65xx & MT81xx SoCs |
diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig index 2c1154e1794a..18301dc9d2e7 100644 --- a/arch/arm/mach-meson/Kconfig +++ b/arch/arm/mach-meson/Kconfig | |||
@@ -2,6 +2,7 @@ menuconfig ARCH_MESON | |||
2 | bool "Amlogic Meson SoCs" if ARCH_MULTI_V7 | 2 | bool "Amlogic Meson SoCs" if ARCH_MULTI_V7 |
3 | select GENERIC_IRQ_CHIP | 3 | select GENERIC_IRQ_CHIP |
4 | select ARM_GIC | 4 | select ARM_GIC |
5 | select CACHE_L2X0 | ||
5 | 6 | ||
6 | if ARCH_MESON | 7 | if ARCH_MESON |
7 | 8 | ||
@@ -10,4 +11,9 @@ config MACH_MESON6 | |||
10 | default ARCH_MESON | 11 | default ARCH_MESON |
11 | select MESON6_TIMER | 12 | select MESON6_TIMER |
12 | 13 | ||
14 | config MACH_MESON8 | ||
15 | bool "Amlogic Meson8 SoCs support" | ||
16 | default ARCH_MESON | ||
17 | select MESON6_TIMER | ||
18 | |||
13 | endif | 19 | endif |
diff --git a/arch/arm/mach-meson/meson.c b/arch/arm/mach-meson/meson.c index 5ee064f5a89f..5d6affe6a694 100644 --- a/arch/arm/mach-meson/meson.c +++ b/arch/arm/mach-meson/meson.c | |||
@@ -16,12 +16,14 @@ | |||
16 | #include <linux/of_platform.h> | 16 | #include <linux/of_platform.h> |
17 | #include <asm/mach/arch.h> | 17 | #include <asm/mach/arch.h> |
18 | 18 | ||
19 | static const char * const m6_common_board_compat[] = { | 19 | static const char * const meson_common_board_compat[] = { |
20 | "amlogic,meson6", | 20 | "amlogic,meson6", |
21 | "amlogic,meson8", | ||
21 | NULL, | 22 | NULL, |
22 | }; | 23 | }; |
23 | 24 | ||
24 | DT_MACHINE_START(AML8726_MX, "Amlogic Meson6 platform") | 25 | DT_MACHINE_START(MESON, "Amlogic Meson platform") |
25 | .dt_compat = m6_common_board_compat, | 26 | .dt_compat = meson_common_board_compat, |
27 | .l2c_aux_val = 0, | ||
28 | .l2c_aux_mask = ~0, | ||
26 | MACHINE_END | 29 | MACHINE_END |
27 | |||
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index e24136b42765..b4f01497ce0b 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile | |||
@@ -7,7 +7,7 @@ CFLAGS_pmsu.o := -march=armv7-a | |||
7 | obj-$(CONFIG_MACH_MVEBU_ANY) += system-controller.o mvebu-soc-id.o | 7 | obj-$(CONFIG_MACH_MVEBU_ANY) += system-controller.o mvebu-soc-id.o |
8 | 8 | ||
9 | ifeq ($(CONFIG_MACH_MVEBU_V7),y) | 9 | ifeq ($(CONFIG_MACH_MVEBU_V7),y) |
10 | obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o | 10 | obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o pm.o pm-board.o |
11 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o | 11 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o |
12 | endif | 12 | endif |
13 | 13 | ||
diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h index 84cd90d9b860..c55bbf81de0e 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.h +++ b/arch/arm/mach-mvebu/armada-370-xp.h | |||
@@ -16,14 +16,8 @@ | |||
16 | #define __MACH_ARMADA_370_XP_H | 16 | #define __MACH_ARMADA_370_XP_H |
17 | 17 | ||
18 | #ifdef CONFIG_SMP | 18 | #ifdef CONFIG_SMP |
19 | #include <linux/cpumask.h> | ||
20 | |||
21 | #define ARMADA_XP_MAX_CPUS 4 | ||
22 | |||
23 | void armada_xp_secondary_startup(void); | 19 | void armada_xp_secondary_startup(void); |
24 | extern struct smp_operations armada_xp_smp_ops; | 20 | extern struct smp_operations armada_xp_smp_ops; |
25 | #endif | 21 | #endif |
26 | 22 | ||
27 | int armada_370_xp_pmsu_idle_enter(unsigned long deepidle); | ||
28 | |||
29 | #endif /* __MACH_ARMADA_370_XP_H */ | 23 | #endif /* __MACH_ARMADA_370_XP_H */ |
diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c index d0d39f150fab..89a139ed7d5b 100644 --- a/arch/arm/mach-mvebu/board-v7.c +++ b/arch/arm/mach-mvebu/board-v7.c | |||
@@ -16,10 +16,12 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/clk-provider.h> | 17 | #include <linux/clk-provider.h> |
18 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
19 | #include <linux/of_fdt.h> | ||
19 | #include <linux/of_platform.h> | 20 | #include <linux/of_platform.h> |
20 | #include <linux/io.h> | 21 | #include <linux/io.h> |
21 | #include <linux/clocksource.h> | 22 | #include <linux/clocksource.h> |
22 | #include <linux/dma-mapping.h> | 23 | #include <linux/dma-mapping.h> |
24 | #include <linux/memblock.h> | ||
23 | #include <linux/mbus.h> | 25 | #include <linux/mbus.h> |
24 | #include <linux/signal.h> | 26 | #include <linux/signal.h> |
25 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
@@ -57,6 +59,54 @@ void __iomem *mvebu_get_scu_base(void) | |||
57 | } | 59 | } |
58 | 60 | ||
59 | /* | 61 | /* |
62 | * When returning from suspend, the platform goes through the | ||
63 | * bootloader, which executes its DDR3 training code. This code has | ||
64 | * the unfortunate idea of using the first 10 KB of each DRAM bank to | ||
65 | * exercise the RAM and calculate the optimal timings. Therefore, this | ||
66 | * area of RAM is overwritten, and shouldn't be used by the kernel if | ||
67 | * suspend/resume is supported. | ||
68 | */ | ||
69 | |||
70 | #ifdef CONFIG_SUSPEND | ||
71 | #define MVEBU_DDR_TRAINING_AREA_SZ (10 * SZ_1K) | ||
72 | static int __init mvebu_scan_mem(unsigned long node, const char *uname, | ||
73 | int depth, void *data) | ||
74 | { | ||
75 | const char *type = of_get_flat_dt_prop(node, "device_type", NULL); | ||
76 | const __be32 *reg, *endp; | ||
77 | int l; | ||
78 | |||
79 | if (type == NULL || strcmp(type, "memory")) | ||
80 | return 0; | ||
81 | |||
82 | reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l); | ||
83 | if (reg == NULL) | ||
84 | reg = of_get_flat_dt_prop(node, "reg", &l); | ||
85 | if (reg == NULL) | ||
86 | return 0; | ||
87 | |||
88 | endp = reg + (l / sizeof(__be32)); | ||
89 | while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { | ||
90 | u64 base, size; | ||
91 | |||
92 | base = dt_mem_next_cell(dt_root_addr_cells, ®); | ||
93 | size = dt_mem_next_cell(dt_root_size_cells, ®); | ||
94 | |||
95 | memblock_reserve(base, MVEBU_DDR_TRAINING_AREA_SZ); | ||
96 | } | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static void __init mvebu_memblock_reserve(void) | ||
102 | { | ||
103 | of_scan_flat_dt(mvebu_scan_mem, NULL); | ||
104 | } | ||
105 | #else | ||
106 | static void __init mvebu_memblock_reserve(void) {} | ||
107 | #endif | ||
108 | |||
109 | /* | ||
60 | * Early versions of Armada 375 SoC have a bug where the BootROM | 110 | * Early versions of Armada 375 SoC have a bug where the BootROM |
61 | * leaves an external data abort pending. The kernel is hit by this | 111 | * leaves an external data abort pending. The kernel is hit by this |
62 | * data abort as soon as it enters userspace, because it unmasks the | 112 | * data abort as soon as it enters userspace, because it unmasks the |
@@ -124,76 +174,12 @@ static void __init i2c_quirk(void) | |||
124 | return; | 174 | return; |
125 | } | 175 | } |
126 | 176 | ||
127 | #define A375_Z1_THERMAL_FIXUP_OFFSET 0xc | ||
128 | |||
129 | static void __init thermal_quirk(void) | ||
130 | { | ||
131 | struct device_node *np; | ||
132 | u32 dev, rev; | ||
133 | int res; | ||
134 | |||
135 | /* | ||
136 | * The early SoC Z1 revision needs a quirk to be applied in order | ||
137 | * for the thermal controller to work properly. This quirk breaks | ||
138 | * the thermal support if applied on a SoC that doesn't need it, | ||
139 | * so we enforce the SoC revision to be known. | ||
140 | */ | ||
141 | res = mvebu_get_soc_id(&dev, &rev); | ||
142 | if (res < 0 || (res == 0 && rev > ARMADA_375_Z1_REV)) | ||
143 | return; | ||
144 | |||
145 | for_each_compatible_node(np, NULL, "marvell,armada375-thermal") { | ||
146 | struct property *prop; | ||
147 | __be32 newval, *newprop, *oldprop; | ||
148 | int len; | ||
149 | |||
150 | /* | ||
151 | * The register offset is at a wrong location. This quirk | ||
152 | * creates a new reg property as a clone of the previous | ||
153 | * one and corrects the offset. | ||
154 | */ | ||
155 | oldprop = (__be32 *)of_get_property(np, "reg", &len); | ||
156 | if (!oldprop) | ||
157 | continue; | ||
158 | |||
159 | /* Create a duplicate of the 'reg' property */ | ||
160 | prop = kzalloc(sizeof(*prop), GFP_KERNEL); | ||
161 | prop->length = len; | ||
162 | prop->name = kstrdup("reg", GFP_KERNEL); | ||
163 | prop->value = kzalloc(len, GFP_KERNEL); | ||
164 | memcpy(prop->value, oldprop, len); | ||
165 | |||
166 | /* Fixup the register offset of the second entry */ | ||
167 | oldprop += 2; | ||
168 | newprop = (__be32 *)prop->value + 2; | ||
169 | newval = cpu_to_be32(be32_to_cpu(*oldprop) - | ||
170 | A375_Z1_THERMAL_FIXUP_OFFSET); | ||
171 | *newprop = newval; | ||
172 | of_update_property(np, prop); | ||
173 | |||
174 | /* | ||
175 | * The thermal controller needs some quirk too, so let's change | ||
176 | * the compatible string to reflect this and allow the driver | ||
177 | * the take the necessary action. | ||
178 | */ | ||
179 | prop = kzalloc(sizeof(*prop), GFP_KERNEL); | ||
180 | prop->name = kstrdup("compatible", GFP_KERNEL); | ||
181 | prop->length = sizeof("marvell,armada375-z1-thermal"); | ||
182 | prop->value = kstrdup("marvell,armada375-z1-thermal", | ||
183 | GFP_KERNEL); | ||
184 | of_update_property(np, prop); | ||
185 | } | ||
186 | return; | ||
187 | } | ||
188 | |||
189 | static void __init mvebu_dt_init(void) | 177 | static void __init mvebu_dt_init(void) |
190 | { | 178 | { |
191 | if (of_machine_is_compatible("marvell,armadaxp")) | 179 | if (of_machine_is_compatible("marvell,armadaxp")) |
192 | i2c_quirk(); | 180 | i2c_quirk(); |
193 | if (of_machine_is_compatible("marvell,a375-db")) { | 181 | if (of_machine_is_compatible("marvell,a375-db")) |
194 | external_abort_quirk(); | 182 | external_abort_quirk(); |
195 | thermal_quirk(); | ||
196 | } | ||
197 | 183 | ||
198 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 184 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
199 | } | 185 | } |
@@ -206,10 +192,16 @@ static const char * const armada_370_xp_dt_compat[] = { | |||
206 | DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)") | 192 | DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)") |
207 | .l2c_aux_val = 0, | 193 | .l2c_aux_val = 0, |
208 | .l2c_aux_mask = ~0, | 194 | .l2c_aux_mask = ~0, |
195 | /* | ||
196 | * The following field (.smp) is still needed to ensure backward | ||
197 | * compatibility with old Device Trees that were not specifying the | ||
198 | * cpus enable-method property. | ||
199 | */ | ||
209 | .smp = smp_ops(armada_xp_smp_ops), | 200 | .smp = smp_ops(armada_xp_smp_ops), |
210 | .init_machine = mvebu_dt_init, | 201 | .init_machine = mvebu_dt_init, |
211 | .init_irq = mvebu_init_irq, | 202 | .init_irq = mvebu_init_irq, |
212 | .restart = mvebu_restart, | 203 | .restart = mvebu_restart, |
204 | .reserve = mvebu_memblock_reserve, | ||
213 | .dt_compat = armada_370_xp_dt_compat, | 205 | .dt_compat = armada_370_xp_dt_compat, |
214 | MACHINE_END | 206 | MACHINE_END |
215 | 207 | ||
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index 044b51185fcc..3585cb394e9b 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Coherency fabric (Aurora) support for Armada 370 and XP platforms. | 2 | * Coherency fabric (Aurora) support for Armada 370, 375, 38x and XP |
3 | * platforms. | ||
3 | * | 4 | * |
4 | * Copyright (C) 2012 Marvell | 5 | * Copyright (C) 2012 Marvell |
5 | * | 6 | * |
@@ -11,7 +12,7 @@ | |||
11 | * License version 2. This program is licensed "as is" without any | 12 | * License version 2. This program is licensed "as is" without any |
12 | * warranty of any kind, whether express or implied. | 13 | * warranty of any kind, whether express or implied. |
13 | * | 14 | * |
14 | * The Armada 370 and Armada XP SOCs have a coherency fabric which is | 15 | * The Armada 370, 375, 38x and XP SOCs have a coherency fabric which is |
15 | * responsible for ensuring hardware coherency between all CPUs and between | 16 | * responsible for ensuring hardware coherency between all CPUs and between |
16 | * CPUs and I/O masters. This file initializes the coherency fabric and | 17 | * CPUs and I/O masters. This file initializes the coherency fabric and |
17 | * supplies basic routines for configuring and controlling hardware coherency | 18 | * supplies basic routines for configuring and controlling hardware coherency |
@@ -28,12 +29,10 @@ | |||
28 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
30 | #include <linux/mbus.h> | 31 | #include <linux/mbus.h> |
31 | #include <linux/clk.h> | ||
32 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
33 | #include <asm/smp_plat.h> | 33 | #include <asm/smp_plat.h> |
34 | #include <asm/cacheflush.h> | 34 | #include <asm/cacheflush.h> |
35 | #include <asm/mach/map.h> | 35 | #include <asm/mach/map.h> |
36 | #include "armada-370-xp.h" | ||
37 | #include "coherency.h" | 36 | #include "coherency.h" |
38 | #include "mvebu-soc-id.h" | 37 | #include "mvebu-soc-id.h" |
39 | 38 | ||
@@ -42,8 +41,6 @@ void __iomem *coherency_base; | |||
42 | static void __iomem *coherency_cpu_base; | 41 | static void __iomem *coherency_cpu_base; |
43 | 42 | ||
44 | /* Coherency fabric registers */ | 43 | /* Coherency fabric registers */ |
45 | #define COHERENCY_FABRIC_CFG_OFFSET 0x4 | ||
46 | |||
47 | #define IO_SYNC_BARRIER_CTL_OFFSET 0x0 | 44 | #define IO_SYNC_BARRIER_CTL_OFFSET 0x0 |
48 | 45 | ||
49 | enum { | 46 | enum { |
@@ -79,157 +76,8 @@ int set_cpu_coherent(void) | |||
79 | return ll_enable_coherency(); | 76 | return ll_enable_coherency(); |
80 | } | 77 | } |
81 | 78 | ||
82 | /* | ||
83 | * The below code implements the I/O coherency workaround on Armada | ||
84 | * 375. This workaround consists in using the two channels of the | ||
85 | * first XOR engine to trigger a XOR transaction that serves as the | ||
86 | * I/O coherency barrier. | ||
87 | */ | ||
88 | |||
89 | static void __iomem *xor_base, *xor_high_base; | ||
90 | static dma_addr_t coherency_wa_buf_phys[CONFIG_NR_CPUS]; | ||
91 | static void *coherency_wa_buf[CONFIG_NR_CPUS]; | ||
92 | static bool coherency_wa_enabled; | ||
93 | |||
94 | #define XOR_CONFIG(chan) (0x10 + (chan * 4)) | ||
95 | #define XOR_ACTIVATION(chan) (0x20 + (chan * 4)) | ||
96 | #define WINDOW_BAR_ENABLE(chan) (0x240 + ((chan) << 2)) | ||
97 | #define WINDOW_BASE(w) (0x250 + ((w) << 2)) | ||
98 | #define WINDOW_SIZE(w) (0x270 + ((w) << 2)) | ||
99 | #define WINDOW_REMAP_HIGH(w) (0x290 + ((w) << 2)) | ||
100 | #define WINDOW_OVERRIDE_CTRL(chan) (0x2A0 + ((chan) << 2)) | ||
101 | #define XOR_DEST_POINTER(chan) (0x2B0 + (chan * 4)) | ||
102 | #define XOR_BLOCK_SIZE(chan) (0x2C0 + (chan * 4)) | ||
103 | #define XOR_INIT_VALUE_LOW 0x2E0 | ||
104 | #define XOR_INIT_VALUE_HIGH 0x2E4 | ||
105 | |||
106 | static inline void mvebu_hwcc_armada375_sync_io_barrier_wa(void) | ||
107 | { | ||
108 | int idx = smp_processor_id(); | ||
109 | |||
110 | /* Write '1' to the first word of the buffer */ | ||
111 | writel(0x1, coherency_wa_buf[idx]); | ||
112 | |||
113 | /* Wait until the engine is idle */ | ||
114 | while ((readl(xor_base + XOR_ACTIVATION(idx)) >> 4) & 0x3) | ||
115 | ; | ||
116 | |||
117 | dmb(); | ||
118 | |||
119 | /* Trigger channel */ | ||
120 | writel(0x1, xor_base + XOR_ACTIVATION(idx)); | ||
121 | |||
122 | /* Poll the data until it is cleared by the XOR transaction */ | ||
123 | while (readl(coherency_wa_buf[idx])) | ||
124 | ; | ||
125 | } | ||
126 | |||
127 | static void __init armada_375_coherency_init_wa(void) | ||
128 | { | ||
129 | const struct mbus_dram_target_info *dram; | ||
130 | struct device_node *xor_node; | ||
131 | struct property *xor_status; | ||
132 | struct clk *xor_clk; | ||
133 | u32 win_enable = 0; | ||
134 | int i; | ||
135 | |||
136 | pr_warn("enabling coherency workaround for Armada 375 Z1, one XOR engine disabled\n"); | ||
137 | |||
138 | /* | ||
139 | * Since the workaround uses one XOR engine, we grab a | ||
140 | * reference to its Device Tree node first. | ||
141 | */ | ||
142 | xor_node = of_find_compatible_node(NULL, NULL, "marvell,orion-xor"); | ||
143 | BUG_ON(!xor_node); | ||
144 | |||
145 | /* | ||
146 | * Then we mark it as disabled so that the real XOR driver | ||
147 | * will not use it. | ||
148 | */ | ||
149 | xor_status = kzalloc(sizeof(struct property), GFP_KERNEL); | ||
150 | BUG_ON(!xor_status); | ||
151 | |||
152 | xor_status->value = kstrdup("disabled", GFP_KERNEL); | ||
153 | BUG_ON(!xor_status->value); | ||
154 | |||
155 | xor_status->length = 8; | ||
156 | xor_status->name = kstrdup("status", GFP_KERNEL); | ||
157 | BUG_ON(!xor_status->name); | ||
158 | |||
159 | of_update_property(xor_node, xor_status); | ||
160 | |||
161 | /* | ||
162 | * And we remap the registers, get the clock, and do the | ||
163 | * initial configuration of the XOR engine. | ||
164 | */ | ||
165 | xor_base = of_iomap(xor_node, 0); | ||
166 | xor_high_base = of_iomap(xor_node, 1); | ||
167 | |||
168 | xor_clk = of_clk_get_by_name(xor_node, NULL); | ||
169 | BUG_ON(!xor_clk); | ||
170 | |||
171 | clk_prepare_enable(xor_clk); | ||
172 | |||
173 | dram = mv_mbus_dram_info(); | ||
174 | |||
175 | for (i = 0; i < 8; i++) { | ||
176 | writel(0, xor_base + WINDOW_BASE(i)); | ||
177 | writel(0, xor_base + WINDOW_SIZE(i)); | ||
178 | if (i < 4) | ||
179 | writel(0, xor_base + WINDOW_REMAP_HIGH(i)); | ||
180 | } | ||
181 | |||
182 | for (i = 0; i < dram->num_cs; i++) { | ||
183 | const struct mbus_dram_window *cs = dram->cs + i; | ||
184 | writel((cs->base & 0xffff0000) | | ||
185 | (cs->mbus_attr << 8) | | ||
186 | dram->mbus_dram_target_id, xor_base + WINDOW_BASE(i)); | ||
187 | writel((cs->size - 1) & 0xffff0000, xor_base + WINDOW_SIZE(i)); | ||
188 | |||
189 | win_enable |= (1 << i); | ||
190 | win_enable |= 3 << (16 + (2 * i)); | ||
191 | } | ||
192 | |||
193 | writel(win_enable, xor_base + WINDOW_BAR_ENABLE(0)); | ||
194 | writel(win_enable, xor_base + WINDOW_BAR_ENABLE(1)); | ||
195 | writel(0, xor_base + WINDOW_OVERRIDE_CTRL(0)); | ||
196 | writel(0, xor_base + WINDOW_OVERRIDE_CTRL(1)); | ||
197 | |||
198 | for (i = 0; i < CONFIG_NR_CPUS; i++) { | ||
199 | coherency_wa_buf[i] = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
200 | BUG_ON(!coherency_wa_buf[i]); | ||
201 | |||
202 | /* | ||
203 | * We can't use the DMA mapping API, since we don't | ||
204 | * have a valid 'struct device' pointer | ||
205 | */ | ||
206 | coherency_wa_buf_phys[i] = | ||
207 | virt_to_phys(coherency_wa_buf[i]); | ||
208 | BUG_ON(!coherency_wa_buf_phys[i]); | ||
209 | |||
210 | /* | ||
211 | * Configure the XOR engine for memset operation, with | ||
212 | * a 128 bytes block size | ||
213 | */ | ||
214 | writel(0x444, xor_base + XOR_CONFIG(i)); | ||
215 | writel(128, xor_base + XOR_BLOCK_SIZE(i)); | ||
216 | writel(coherency_wa_buf_phys[i], | ||
217 | xor_base + XOR_DEST_POINTER(i)); | ||
218 | } | ||
219 | |||
220 | writel(0x0, xor_base + XOR_INIT_VALUE_LOW); | ||
221 | writel(0x0, xor_base + XOR_INIT_VALUE_HIGH); | ||
222 | |||
223 | coherency_wa_enabled = true; | ||
224 | } | ||
225 | |||
226 | static inline void mvebu_hwcc_sync_io_barrier(void) | 79 | static inline void mvebu_hwcc_sync_io_barrier(void) |
227 | { | 80 | { |
228 | if (coherency_wa_enabled) { | ||
229 | mvebu_hwcc_armada375_sync_io_barrier_wa(); | ||
230 | return; | ||
231 | } | ||
232 | |||
233 | writel(0x1, coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET); | 81 | writel(0x1, coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET); |
234 | while (readl(coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET) & 0x1); | 82 | while (readl(coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET) & 0x1); |
235 | } | 83 | } |
@@ -361,25 +209,41 @@ static int coherency_type(void) | |||
361 | { | 209 | { |
362 | struct device_node *np; | 210 | struct device_node *np; |
363 | const struct of_device_id *match; | 211 | const struct of_device_id *match; |
212 | int type; | ||
364 | 213 | ||
365 | np = of_find_matching_node_and_match(NULL, of_coherency_table, &match); | 214 | /* |
366 | if (np) { | 215 | * The coherency fabric is needed: |
367 | int type = (int) match->data; | 216 | * - For coherency between processors on Armada XP, so only |
217 | * when SMP is enabled. | ||
218 | * - For coherency between the processor and I/O devices, but | ||
219 | * this coherency requires many pre-requisites (write | ||
220 | * allocate cache policy, shareable pages, SMP bit set) that | ||
221 | * are only meant in SMP situations. | ||
222 | * | ||
223 | * Note that this means that on Armada 370, there is currently | ||
224 | * no way to use hardware I/O coherency, because even when | ||
225 | * CONFIG_SMP is enabled, is_smp() returns false due to the | ||
226 | * Armada 370 being a single-core processor. To lift this | ||
227 | * limitation, we would have to find a way to make the cache | ||
228 | * policy set to write-allocate (on all Armada SoCs), and to | ||
229 | * set the shareable attribute in page tables (on all Armada | ||
230 | * SoCs except the Armada 370). Unfortunately, such decisions | ||
231 | * are taken very early in the kernel boot process, at a point | ||
232 | * where we don't know yet on which SoC we are running. | ||
368 | 233 | ||
369 | /* Armada 370/XP coherency works in both UP and SMP */ | 234 | */ |
370 | if (type == COHERENCY_FABRIC_TYPE_ARMADA_370_XP) | 235 | if (!is_smp()) |
371 | return type; | 236 | return COHERENCY_FABRIC_TYPE_NONE; |
372 | 237 | ||
373 | /* Armada 375 coherency works only on SMP */ | 238 | np = of_find_matching_node_and_match(NULL, of_coherency_table, &match); |
374 | else if (type == COHERENCY_FABRIC_TYPE_ARMADA_375 && is_smp()) | 239 | if (!np) |
375 | return type; | 240 | return COHERENCY_FABRIC_TYPE_NONE; |
376 | 241 | ||
377 | /* Armada 380 coherency works only on SMP */ | 242 | type = (int) match->data; |
378 | else if (type == COHERENCY_FABRIC_TYPE_ARMADA_380 && is_smp()) | ||
379 | return type; | ||
380 | } | ||
381 | 243 | ||
382 | return COHERENCY_FABRIC_TYPE_NONE; | 244 | of_node_put(np); |
245 | |||
246 | return type; | ||
383 | } | 247 | } |
384 | 248 | ||
385 | int coherency_available(void) | 249 | int coherency_available(void) |
@@ -407,22 +271,9 @@ int __init coherency_init(void) | |||
407 | 271 | ||
408 | static int __init coherency_late_init(void) | 272 | static int __init coherency_late_init(void) |
409 | { | 273 | { |
410 | int type = coherency_type(); | 274 | if (coherency_available()) |
411 | 275 | bus_register_notifier(&platform_bus_type, | |
412 | if (type == COHERENCY_FABRIC_TYPE_NONE) | 276 | &mvebu_hwcc_nb); |
413 | return 0; | ||
414 | |||
415 | if (type == COHERENCY_FABRIC_TYPE_ARMADA_375) { | ||
416 | u32 dev, rev; | ||
417 | |||
418 | if (mvebu_get_soc_id(&dev, &rev) == 0 && | ||
419 | rev == ARMADA_375_Z1_REV) | ||
420 | armada_375_coherency_init_wa(); | ||
421 | } | ||
422 | |||
423 | bus_register_notifier(&platform_bus_type, | ||
424 | &mvebu_hwcc_nb); | ||
425 | |||
426 | return 0; | 277 | return 0; |
427 | } | 278 | } |
428 | 279 | ||
diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S index f5d881b5d0f7..8b2fbc8b6bc6 100644 --- a/arch/arm/mach-mvebu/coherency_ll.S +++ b/arch/arm/mach-mvebu/coherency_ll.S | |||
@@ -24,7 +24,10 @@ | |||
24 | #include <asm/cp15.h> | 24 | #include <asm/cp15.h> |
25 | 25 | ||
26 | .text | 26 | .text |
27 | /* Returns the coherency base address in r1 (r0 is untouched) */ | 27 | /* |
28 | * Returns the coherency base address in r1 (r0 is untouched), or 0 if | ||
29 | * the coherency fabric is not enabled. | ||
30 | */ | ||
28 | ENTRY(ll_get_coherency_base) | 31 | ENTRY(ll_get_coherency_base) |
29 | mrc p15, 0, r1, c1, c0, 0 | 32 | mrc p15, 0, r1, c1, c0, 0 |
30 | tst r1, #CR_M @ Check MMU bit enabled | 33 | tst r1, #CR_M @ Check MMU bit enabled |
@@ -32,8 +35,13 @@ ENTRY(ll_get_coherency_base) | |||
32 | 35 | ||
33 | /* | 36 | /* |
34 | * MMU is disabled, use the physical address of the coherency | 37 | * MMU is disabled, use the physical address of the coherency |
35 | * base address. | 38 | * base address. However, if the coherency fabric isn't mapped |
39 | * (i.e its virtual address is zero), it means coherency is | ||
40 | * not enabled, so we return 0. | ||
36 | */ | 41 | */ |
42 | ldr r1, =coherency_base | ||
43 | cmp r1, #0 | ||
44 | beq 2f | ||
37 | adr r1, 3f | 45 | adr r1, 3f |
38 | ldr r3, [r1] | 46 | ldr r3, [r1] |
39 | ldr r1, [r1, r3] | 47 | ldr r1, [r1, r3] |
@@ -85,6 +93,9 @@ ENTRY(ll_add_cpu_to_smp_group) | |||
85 | */ | 93 | */ |
86 | mov r0, lr | 94 | mov r0, lr |
87 | bl ll_get_coherency_base | 95 | bl ll_get_coherency_base |
96 | /* Bail out if the coherency is not enabled */ | ||
97 | cmp r1, #0 | ||
98 | reteq r0 | ||
88 | bl ll_get_coherency_cpumask | 99 | bl ll_get_coherency_cpumask |
89 | mov lr, r0 | 100 | mov lr, r0 |
90 | add r0, r1, #ARMADA_XP_CFB_CFG_REG_OFFSET | 101 | add r0, r1, #ARMADA_XP_CFB_CFG_REG_OFFSET |
@@ -107,6 +118,9 @@ ENTRY(ll_enable_coherency) | |||
107 | */ | 118 | */ |
108 | mov r0, lr | 119 | mov r0, lr |
109 | bl ll_get_coherency_base | 120 | bl ll_get_coherency_base |
121 | /* Bail out if the coherency is not enabled */ | ||
122 | cmp r1, #0 | ||
123 | reteq r0 | ||
110 | bl ll_get_coherency_cpumask | 124 | bl ll_get_coherency_cpumask |
111 | mov lr, r0 | 125 | mov lr, r0 |
112 | add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET | 126 | add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET |
@@ -131,6 +145,9 @@ ENTRY(ll_disable_coherency) | |||
131 | */ | 145 | */ |
132 | mov r0, lr | 146 | mov r0, lr |
133 | bl ll_get_coherency_base | 147 | bl ll_get_coherency_base |
148 | /* Bail out if the coherency is not enabled */ | ||
149 | cmp r1, #0 | ||
150 | reteq r0 | ||
134 | bl ll_get_coherency_cpumask | 151 | bl ll_get_coherency_cpumask |
135 | mov lr, r0 | 152 | mov lr, r0 |
136 | add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET | 153 | add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET |
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h index 3ccb40c3bf94..3e0aca1f288a 100644 --- a/arch/arm/mach-mvebu/common.h +++ b/arch/arm/mach-mvebu/common.h | |||
@@ -25,4 +25,6 @@ int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev); | |||
25 | 25 | ||
26 | void __iomem *mvebu_get_scu_base(void); | 26 | void __iomem *mvebu_get_scu_base(void); |
27 | 27 | ||
28 | int mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd)); | ||
29 | |||
28 | #endif | 30 | #endif |
diff --git a/arch/arm/mach-mvebu/cpu-reset.c b/arch/arm/mach-mvebu/cpu-reset.c index 60fb53787004..4a2cadd6b48e 100644 --- a/arch/arm/mach-mvebu/cpu-reset.c +++ b/arch/arm/mach-mvebu/cpu-reset.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/resource.h> | 17 | #include <linux/resource.h> |
18 | #include "armada-370-xp.h" | ||
19 | 18 | ||
20 | static void __iomem *cpu_reset_base; | 19 | static void __iomem *cpu_reset_base; |
21 | static size_t cpu_reset_size; | 20 | static size_t cpu_reset_size; |
diff --git a/arch/arm/mach-mvebu/headsmp-a9.S b/arch/arm/mach-mvebu/headsmp-a9.S index be51c998c0cd..08d5ed46b996 100644 --- a/arch/arm/mach-mvebu/headsmp-a9.S +++ b/arch/arm/mach-mvebu/headsmp-a9.S | |||
@@ -22,5 +22,6 @@ | |||
22 | ENTRY(mvebu_cortex_a9_secondary_startup) | 22 | ENTRY(mvebu_cortex_a9_secondary_startup) |
23 | ARM_BE8(setend be) | 23 | ARM_BE8(setend be) |
24 | bl v7_invalidate_l1 | 24 | bl v7_invalidate_l1 |
25 | bl armada_38x_scu_power_up | ||
25 | b secondary_startup | 26 | b secondary_startup |
26 | ENDPROC(mvebu_cortex_a9_secondary_startup) | 27 | ENDPROC(mvebu_cortex_a9_secondary_startup) |
diff --git a/arch/arm/mach-mvebu/platsmp-a9.c b/arch/arm/mach-mvebu/platsmp-a9.c index 47a71a924b96..2ec1a42b4321 100644 --- a/arch/arm/mach-mvebu/platsmp-a9.c +++ b/arch/arm/mach-mvebu/platsmp-a9.c | |||
@@ -43,21 +43,70 @@ static int __cpuinit mvebu_cortex_a9_boot_secondary(unsigned int cpu, | |||
43 | else | 43 | else |
44 | mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cortex_a9_secondary_startup); | 44 | mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cortex_a9_secondary_startup); |
45 | smp_wmb(); | 45 | smp_wmb(); |
46 | |||
47 | /* | ||
48 | * Doing this before deasserting the CPUs is needed to wake up CPUs | ||
49 | * in the offline state after using CPU hotplug. | ||
50 | */ | ||
51 | arch_send_wakeup_ipi_mask(cpumask_of(cpu)); | ||
52 | |||
46 | ret = mvebu_cpu_reset_deassert(hw_cpu); | 53 | ret = mvebu_cpu_reset_deassert(hw_cpu); |
47 | if (ret) { | 54 | if (ret) { |
48 | pr_err("Could not start the secondary CPU: %d\n", ret); | 55 | pr_err("Could not start the secondary CPU: %d\n", ret); |
49 | return ret; | 56 | return ret; |
50 | } | 57 | } |
51 | arch_send_wakeup_ipi_mask(cpumask_of(cpu)); | ||
52 | 58 | ||
53 | return 0; | 59 | return 0; |
54 | } | 60 | } |
61 | /* | ||
62 | * When a CPU is brought back online, either through CPU hotplug, or | ||
63 | * because of the boot of a kexec'ed kernel, the PMSU configuration | ||
64 | * for this CPU might be in the deep idle state, preventing this CPU | ||
65 | * from receiving interrupts. Here, we therefore take out the current | ||
66 | * CPU from this state, which was entered by armada_38x_cpu_die() | ||
67 | * below. | ||
68 | */ | ||
69 | static void armada_38x_secondary_init(unsigned int cpu) | ||
70 | { | ||
71 | mvebu_v7_pmsu_idle_exit(); | ||
72 | } | ||
73 | |||
74 | #ifdef CONFIG_HOTPLUG_CPU | ||
75 | static void armada_38x_cpu_die(unsigned int cpu) | ||
76 | { | ||
77 | /* | ||
78 | * CPU hotplug is implemented by putting offline CPUs into the | ||
79 | * deep idle sleep state. | ||
80 | */ | ||
81 | armada_38x_do_cpu_suspend(true); | ||
82 | } | ||
83 | |||
84 | /* | ||
85 | * We need a dummy function, so that platform_can_cpu_hotplug() knows | ||
86 | * we support CPU hotplug. However, the function does not need to do | ||
87 | * anything, because CPUs going offline can enter the deep idle state | ||
88 | * by themselves, without any help from a still alive CPU. | ||
89 | */ | ||
90 | static int armada_38x_cpu_kill(unsigned int cpu) | ||
91 | { | ||
92 | return 1; | ||
93 | } | ||
94 | #endif | ||
55 | 95 | ||
56 | static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = { | 96 | static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = { |
57 | .smp_boot_secondary = mvebu_cortex_a9_boot_secondary, | 97 | .smp_boot_secondary = mvebu_cortex_a9_boot_secondary, |
58 | }; | 98 | }; |
59 | 99 | ||
100 | static struct smp_operations armada_38x_smp_ops __initdata = { | ||
101 | .smp_boot_secondary = mvebu_cortex_a9_boot_secondary, | ||
102 | .smp_secondary_init = armada_38x_secondary_init, | ||
103 | #ifdef CONFIG_HOTPLUG_CPU | ||
104 | .cpu_die = armada_38x_cpu_die, | ||
105 | .cpu_kill = armada_38x_cpu_kill, | ||
106 | #endif | ||
107 | }; | ||
108 | |||
60 | CPU_METHOD_OF_DECLARE(mvebu_armada_375_smp, "marvell,armada-375-smp", | 109 | CPU_METHOD_OF_DECLARE(mvebu_armada_375_smp, "marvell,armada-375-smp", |
61 | &mvebu_cortex_a9_smp_ops); | 110 | &mvebu_cortex_a9_smp_ops); |
62 | CPU_METHOD_OF_DECLARE(mvebu_armada_380_smp, "marvell,armada-380-smp", | 111 | CPU_METHOD_OF_DECLARE(mvebu_armada_380_smp, "marvell,armada-380-smp", |
63 | &mvebu_cortex_a9_smp_ops); | 112 | &armada_38x_smp_ops); |
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index 895dc373c8a1..58cc8c1575eb 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c | |||
@@ -30,10 +30,12 @@ | |||
30 | #include "pmsu.h" | 30 | #include "pmsu.h" |
31 | #include "coherency.h" | 31 | #include "coherency.h" |
32 | 32 | ||
33 | #define ARMADA_XP_MAX_CPUS 4 | ||
34 | |||
33 | #define AXP_BOOTROM_BASE 0xfff00000 | 35 | #define AXP_BOOTROM_BASE 0xfff00000 |
34 | #define AXP_BOOTROM_SIZE 0x100000 | 36 | #define AXP_BOOTROM_SIZE 0x100000 |
35 | 37 | ||
36 | static struct clk *__init get_cpu_clk(int cpu) | 38 | static struct clk *get_cpu_clk(int cpu) |
37 | { | 39 | { |
38 | struct clk *cpu_clk; | 40 | struct clk *cpu_clk; |
39 | struct device_node *np = of_get_cpu_node(cpu, NULL); | 41 | struct device_node *np = of_get_cpu_node(cpu, NULL); |
@@ -46,29 +48,28 @@ static struct clk *__init get_cpu_clk(int cpu) | |||
46 | return cpu_clk; | 48 | return cpu_clk; |
47 | } | 49 | } |
48 | 50 | ||
49 | static void __init set_secondary_cpus_clock(void) | 51 | static void set_secondary_cpu_clock(unsigned int cpu) |
50 | { | 52 | { |
51 | int thiscpu, cpu; | 53 | int thiscpu; |
52 | unsigned long rate; | 54 | unsigned long rate; |
53 | struct clk *cpu_clk; | 55 | struct clk *cpu_clk; |
54 | 56 | ||
55 | thiscpu = smp_processor_id(); | 57 | thiscpu = get_cpu(); |
58 | |||
56 | cpu_clk = get_cpu_clk(thiscpu); | 59 | cpu_clk = get_cpu_clk(thiscpu); |
57 | if (!cpu_clk) | 60 | if (!cpu_clk) |
58 | return; | 61 | goto out; |
59 | clk_prepare_enable(cpu_clk); | 62 | clk_prepare_enable(cpu_clk); |
60 | rate = clk_get_rate(cpu_clk); | 63 | rate = clk_get_rate(cpu_clk); |
61 | 64 | ||
62 | /* set all the other CPU clk to the same rate than the boot CPU */ | 65 | cpu_clk = get_cpu_clk(cpu); |
63 | for_each_possible_cpu(cpu) { | 66 | if (!cpu_clk) |
64 | if (cpu == thiscpu) | 67 | goto out; |
65 | continue; | 68 | clk_set_rate(cpu_clk, rate); |
66 | cpu_clk = get_cpu_clk(cpu); | 69 | clk_prepare_enable(cpu_clk); |
67 | if (!cpu_clk) | 70 | |
68 | return; | 71 | out: |
69 | clk_set_rate(cpu_clk, rate); | 72 | put_cpu(); |
70 | clk_prepare_enable(cpu_clk); | ||
71 | } | ||
72 | } | 73 | } |
73 | 74 | ||
74 | static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle) | 75 | static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle) |
@@ -78,6 +79,7 @@ static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
78 | pr_info("Booting CPU %d\n", cpu); | 79 | pr_info("Booting CPU %d\n", cpu); |
79 | 80 | ||
80 | hw_cpu = cpu_logical_map(cpu); | 81 | hw_cpu = cpu_logical_map(cpu); |
82 | set_secondary_cpu_clock(hw_cpu); | ||
81 | mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_xp_secondary_startup); | 83 | mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_xp_secondary_startup); |
82 | 84 | ||
83 | /* | 85 | /* |
@@ -126,7 +128,6 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus) | |||
126 | struct resource res; | 128 | struct resource res; |
127 | int err; | 129 | int err; |
128 | 130 | ||
129 | set_secondary_cpus_clock(); | ||
130 | flush_cache_all(); | 131 | flush_cache_all(); |
131 | set_cpu_coherent(); | 132 | set_cpu_coherent(); |
132 | 133 | ||
diff --git a/arch/arm/mach-mvebu/pm-board.c b/arch/arm/mach-mvebu/pm-board.c new file mode 100644 index 000000000000..6dfd4ab97b2a --- /dev/null +++ b/arch/arm/mach-mvebu/pm-board.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /* | ||
2 | * Board-level suspend/resume support. | ||
3 | * | ||
4 | * Copyright (C) 2014 Marvell | ||
5 | * | ||
6 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/delay.h> | ||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <linux/of_gpio.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include "common.h" | ||
22 | |||
23 | #define ARMADA_XP_GP_PIC_NR_GPIOS 3 | ||
24 | |||
25 | static void __iomem *gpio_ctrl; | ||
26 | static int pic_gpios[ARMADA_XP_GP_PIC_NR_GPIOS]; | ||
27 | static int pic_raw_gpios[ARMADA_XP_GP_PIC_NR_GPIOS]; | ||
28 | |||
29 | static void mvebu_armada_xp_gp_pm_enter(void __iomem *sdram_reg, u32 srcmd) | ||
30 | { | ||
31 | u32 reg, ackcmd; | ||
32 | int i; | ||
33 | |||
34 | /* Put 001 as value on the GPIOs */ | ||
35 | reg = readl(gpio_ctrl); | ||
36 | for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++) | ||
37 | reg &= ~BIT(pic_raw_gpios[i]); | ||
38 | reg |= BIT(pic_raw_gpios[0]); | ||
39 | writel(reg, gpio_ctrl); | ||
40 | |||
41 | /* Prepare writing 111 to the GPIOs */ | ||
42 | ackcmd = readl(gpio_ctrl); | ||
43 | for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++) | ||
44 | ackcmd |= BIT(pic_raw_gpios[i]); | ||
45 | |||
46 | /* | ||
47 | * Wait a while, the PIC needs quite a bit of time between the | ||
48 | * two GPIO commands. | ||
49 | */ | ||
50 | mdelay(3000); | ||
51 | |||
52 | asm volatile ( | ||
53 | /* Align to a cache line */ | ||
54 | ".balign 32\n\t" | ||
55 | |||
56 | /* Enter self refresh */ | ||
57 | "str %[srcmd], [%[sdram_reg]]\n\t" | ||
58 | |||
59 | /* | ||
60 | * Wait 100 cycles for DDR to enter self refresh, by | ||
61 | * doing 50 times two instructions. | ||
62 | */ | ||
63 | "mov r1, #50\n\t" | ||
64 | "1: subs r1, r1, #1\n\t" | ||
65 | "bne 1b\n\t" | ||
66 | |||
67 | /* Issue the command ACK */ | ||
68 | "str %[ackcmd], [%[gpio_ctrl]]\n\t" | ||
69 | |||
70 | /* Trap the processor */ | ||
71 | "b .\n\t" | ||
72 | : : [srcmd] "r" (srcmd), [sdram_reg] "r" (sdram_reg), | ||
73 | [ackcmd] "r" (ackcmd), [gpio_ctrl] "r" (gpio_ctrl) : "r1"); | ||
74 | } | ||
75 | |||
76 | static int mvebu_armada_xp_gp_pm_init(void) | ||
77 | { | ||
78 | struct device_node *np; | ||
79 | struct device_node *gpio_ctrl_np; | ||
80 | int ret = 0, i; | ||
81 | |||
82 | if (!of_machine_is_compatible("marvell,axp-gp")) | ||
83 | return -ENODEV; | ||
84 | |||
85 | np = of_find_node_by_name(NULL, "pm_pic"); | ||
86 | if (!np) | ||
87 | return -ENODEV; | ||
88 | |||
89 | for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++) { | ||
90 | char *name; | ||
91 | struct of_phandle_args args; | ||
92 | |||
93 | pic_gpios[i] = of_get_named_gpio(np, "ctrl-gpios", i); | ||
94 | if (pic_gpios[i] < 0) { | ||
95 | ret = -ENODEV; | ||
96 | goto out; | ||
97 | } | ||
98 | |||
99 | name = kasprintf(GFP_KERNEL, "pic-pin%d", i); | ||
100 | if (!name) { | ||
101 | ret = -ENOMEM; | ||
102 | goto out; | ||
103 | } | ||
104 | |||
105 | ret = gpio_request(pic_gpios[i], name); | ||
106 | if (ret < 0) { | ||
107 | kfree(name); | ||
108 | goto out; | ||
109 | } | ||
110 | |||
111 | ret = gpio_direction_output(pic_gpios[i], 0); | ||
112 | if (ret < 0) { | ||
113 | gpio_free(pic_gpios[i]); | ||
114 | kfree(name); | ||
115 | goto out; | ||
116 | } | ||
117 | |||
118 | ret = of_parse_phandle_with_fixed_args(np, "ctrl-gpios", 2, | ||
119 | i, &args); | ||
120 | if (ret < 0) { | ||
121 | gpio_free(pic_gpios[i]); | ||
122 | kfree(name); | ||
123 | goto out; | ||
124 | } | ||
125 | |||
126 | gpio_ctrl_np = args.np; | ||
127 | pic_raw_gpios[i] = args.args[0]; | ||
128 | } | ||
129 | |||
130 | gpio_ctrl = of_iomap(gpio_ctrl_np, 0); | ||
131 | if (!gpio_ctrl) | ||
132 | return -ENOMEM; | ||
133 | |||
134 | mvebu_pm_init(mvebu_armada_xp_gp_pm_enter); | ||
135 | |||
136 | out: | ||
137 | of_node_put(np); | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | late_initcall(mvebu_armada_xp_gp_pm_init); | ||
diff --git a/arch/arm/mach-mvebu/pm.c b/arch/arm/mach-mvebu/pm.c new file mode 100644 index 000000000000..6573a8f11f70 --- /dev/null +++ b/arch/arm/mach-mvebu/pm.c | |||
@@ -0,0 +1,218 @@ | |||
1 | /* | ||
2 | * Suspend/resume support. Currently supporting Armada XP only. | ||
3 | * | ||
4 | * Copyright (C) 2014 Marvell | ||
5 | * | ||
6 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/cpu_pm.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/gpio.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/mbus.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <linux/suspend.h> | ||
21 | #include <asm/cacheflush.h> | ||
22 | #include <asm/outercache.h> | ||
23 | #include <asm/suspend.h> | ||
24 | |||
25 | #include "coherency.h" | ||
26 | #include "pmsu.h" | ||
27 | |||
28 | #define SDRAM_CONFIG_OFFS 0x0 | ||
29 | #define SDRAM_CONFIG_SR_MODE_BIT BIT(24) | ||
30 | #define SDRAM_OPERATION_OFFS 0x18 | ||
31 | #define SDRAM_OPERATION_SELF_REFRESH 0x7 | ||
32 | #define SDRAM_DLB_EVICTION_OFFS 0x30c | ||
33 | #define SDRAM_DLB_EVICTION_THRESHOLD_MASK 0xff | ||
34 | |||
35 | static void (*mvebu_board_pm_enter)(void __iomem *sdram_reg, u32 srcmd); | ||
36 | static void __iomem *sdram_ctrl; | ||
37 | |||
38 | static int mvebu_pm_powerdown(unsigned long data) | ||
39 | { | ||
40 | u32 reg, srcmd; | ||
41 | |||
42 | flush_cache_all(); | ||
43 | outer_flush_all(); | ||
44 | |||
45 | /* | ||
46 | * Issue a Data Synchronization Barrier instruction to ensure | ||
47 | * that all state saving has been completed. | ||
48 | */ | ||
49 | dsb(); | ||
50 | |||
51 | /* Flush the DLB and wait ~7 usec */ | ||
52 | reg = readl(sdram_ctrl + SDRAM_DLB_EVICTION_OFFS); | ||
53 | reg &= ~SDRAM_DLB_EVICTION_THRESHOLD_MASK; | ||
54 | writel(reg, sdram_ctrl + SDRAM_DLB_EVICTION_OFFS); | ||
55 | |||
56 | udelay(7); | ||
57 | |||
58 | /* Set DRAM in battery backup mode */ | ||
59 | reg = readl(sdram_ctrl + SDRAM_CONFIG_OFFS); | ||
60 | reg &= ~SDRAM_CONFIG_SR_MODE_BIT; | ||
61 | writel(reg, sdram_ctrl + SDRAM_CONFIG_OFFS); | ||
62 | |||
63 | /* Prepare to go to self-refresh */ | ||
64 | |||
65 | srcmd = readl(sdram_ctrl + SDRAM_OPERATION_OFFS); | ||
66 | srcmd &= ~0x1F; | ||
67 | srcmd |= SDRAM_OPERATION_SELF_REFRESH; | ||
68 | |||
69 | mvebu_board_pm_enter(sdram_ctrl + SDRAM_OPERATION_OFFS, srcmd); | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | #define BOOT_INFO_ADDR 0x3000 | ||
75 | #define BOOT_MAGIC_WORD 0xdeadb002 | ||
76 | #define BOOT_MAGIC_LIST_END 0xffffffff | ||
77 | |||
78 | /* | ||
79 | * Those registers are accessed before switching the internal register | ||
80 | * base, which is why we hardcode the 0xd0000000 base address, the one | ||
81 | * used by the SoC out of reset. | ||
82 | */ | ||
83 | #define MBUS_WINDOW_12_CTRL 0xd00200b0 | ||
84 | #define MBUS_INTERNAL_REG_ADDRESS 0xd0020080 | ||
85 | |||
86 | #define SDRAM_WIN_BASE_REG(x) (0x20180 + (0x8*x)) | ||
87 | #define SDRAM_WIN_CTRL_REG(x) (0x20184 + (0x8*x)) | ||
88 | |||
89 | static phys_addr_t mvebu_internal_reg_base(void) | ||
90 | { | ||
91 | struct device_node *np; | ||
92 | __be32 in_addr[2]; | ||
93 | |||
94 | np = of_find_node_by_name(NULL, "internal-regs"); | ||
95 | BUG_ON(!np); | ||
96 | |||
97 | /* | ||
98 | * Ask the DT what is the internal register address on this | ||
99 | * platform. In the mvebu-mbus DT binding, 0xf0010000 | ||
100 | * corresponds to the internal register window. | ||
101 | */ | ||
102 | in_addr[0] = cpu_to_be32(0xf0010000); | ||
103 | in_addr[1] = 0x0; | ||
104 | |||
105 | return of_translate_address(np, in_addr); | ||
106 | } | ||
107 | |||
108 | static void mvebu_pm_store_bootinfo(void) | ||
109 | { | ||
110 | u32 *store_addr; | ||
111 | phys_addr_t resume_pc; | ||
112 | |||
113 | store_addr = phys_to_virt(BOOT_INFO_ADDR); | ||
114 | resume_pc = virt_to_phys(armada_370_xp_cpu_resume); | ||
115 | |||
116 | /* | ||
117 | * The bootloader expects the first two words to be a magic | ||
118 | * value (BOOT_MAGIC_WORD), followed by the address of the | ||
119 | * resume code to jump to. Then, it expects a sequence of | ||
120 | * (address, value) pairs, which can be used to restore the | ||
121 | * value of certain registers. This sequence must end with the | ||
122 | * BOOT_MAGIC_LIST_END magic value. | ||
123 | */ | ||
124 | |||
125 | writel(BOOT_MAGIC_WORD, store_addr++); | ||
126 | writel(resume_pc, store_addr++); | ||
127 | |||
128 | /* | ||
129 | * Some platforms remap their internal register base address | ||
130 | * to 0xf1000000. However, out of reset, window 12 starts at | ||
131 | * 0xf0000000 and ends at 0xf7ffffff, which would overlap with | ||
132 | * the internal registers. Therefore, disable window 12. | ||
133 | */ | ||
134 | writel(MBUS_WINDOW_12_CTRL, store_addr++); | ||
135 | writel(0x0, store_addr++); | ||
136 | |||
137 | /* | ||
138 | * Set the internal register base address to the value | ||
139 | * expected by Linux, as read from the Device Tree. | ||
140 | */ | ||
141 | writel(MBUS_INTERNAL_REG_ADDRESS, store_addr++); | ||
142 | writel(mvebu_internal_reg_base(), store_addr++); | ||
143 | |||
144 | /* | ||
145 | * Ask the mvebu-mbus driver to store the SDRAM window | ||
146 | * configuration, which has to be restored by the bootloader | ||
147 | * before re-entering the kernel on resume. | ||
148 | */ | ||
149 | store_addr += mvebu_mbus_save_cpu_target(store_addr); | ||
150 | |||
151 | writel(BOOT_MAGIC_LIST_END, store_addr); | ||
152 | } | ||
153 | |||
154 | static int mvebu_pm_enter(suspend_state_t state) | ||
155 | { | ||
156 | if (state != PM_SUSPEND_MEM) | ||
157 | return -EINVAL; | ||
158 | |||
159 | cpu_pm_enter(); | ||
160 | |||
161 | mvebu_pm_store_bootinfo(); | ||
162 | cpu_suspend(0, mvebu_pm_powerdown); | ||
163 | |||
164 | outer_resume(); | ||
165 | |||
166 | mvebu_v7_pmsu_idle_exit(); | ||
167 | |||
168 | set_cpu_coherent(); | ||
169 | |||
170 | cpu_pm_exit(); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static const struct platform_suspend_ops mvebu_pm_ops = { | ||
176 | .enter = mvebu_pm_enter, | ||
177 | .valid = suspend_valid_only_mem, | ||
178 | }; | ||
179 | |||
180 | int mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd)) | ||
181 | { | ||
182 | struct device_node *np; | ||
183 | struct resource res; | ||
184 | |||
185 | if (!of_machine_is_compatible("marvell,armadaxp")) | ||
186 | return -ENODEV; | ||
187 | |||
188 | np = of_find_compatible_node(NULL, NULL, | ||
189 | "marvell,armada-xp-sdram-controller"); | ||
190 | if (!np) | ||
191 | return -ENODEV; | ||
192 | |||
193 | if (of_address_to_resource(np, 0, &res)) { | ||
194 | of_node_put(np); | ||
195 | return -ENODEV; | ||
196 | } | ||
197 | |||
198 | if (!request_mem_region(res.start, resource_size(&res), | ||
199 | np->full_name)) { | ||
200 | of_node_put(np); | ||
201 | return -EBUSY; | ||
202 | } | ||
203 | |||
204 | sdram_ctrl = ioremap(res.start, resource_size(&res)); | ||
205 | if (!sdram_ctrl) { | ||
206 | release_mem_region(res.start, resource_size(&res)); | ||
207 | of_node_put(np); | ||
208 | return -ENOMEM; | ||
209 | } | ||
210 | |||
211 | of_node_put(np); | ||
212 | |||
213 | mvebu_board_pm_enter = board_pm_enter; | ||
214 | |||
215 | suspend_set_ops(&mvebu_pm_ops); | ||
216 | |||
217 | return 0; | ||
218 | } | ||
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c index bbd8664d1bac..d8ab605a44fa 100644 --- a/arch/arm/mach-mvebu/pmsu.c +++ b/arch/arm/mach-mvebu/pmsu.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
22 | #include <linux/cpu_pm.h> | 22 | #include <linux/cpu_pm.h> |
23 | #include <linux/cpufreq-dt.h> | ||
23 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
24 | #include <linux/init.h> | 25 | #include <linux/init.h> |
25 | #include <linux/io.h> | 26 | #include <linux/io.h> |
@@ -39,7 +40,6 @@ | |||
39 | #include <asm/suspend.h> | 40 | #include <asm/suspend.h> |
40 | #include <asm/tlbflush.h> | 41 | #include <asm/tlbflush.h> |
41 | #include "common.h" | 42 | #include "common.h" |
42 | #include "armada-370-xp.h" | ||
43 | 43 | ||
44 | 44 | ||
45 | #define PMSU_BASE_OFFSET 0x100 | 45 | #define PMSU_BASE_OFFSET 0x100 |
@@ -312,7 +312,7 @@ static int armada_370_xp_cpu_suspend(unsigned long deepidle) | |||
312 | return cpu_suspend(deepidle, armada_370_xp_pmsu_idle_enter); | 312 | return cpu_suspend(deepidle, armada_370_xp_pmsu_idle_enter); |
313 | } | 313 | } |
314 | 314 | ||
315 | static int armada_38x_do_cpu_suspend(unsigned long deepidle) | 315 | int armada_38x_do_cpu_suspend(unsigned long deepidle) |
316 | { | 316 | { |
317 | unsigned long flags = 0; | 317 | unsigned long flags = 0; |
318 | 318 | ||
@@ -572,6 +572,10 @@ int mvebu_pmsu_dfs_request(int cpu) | |||
572 | return 0; | 572 | return 0; |
573 | } | 573 | } |
574 | 574 | ||
575 | struct cpufreq_dt_platform_data cpufreq_dt_pd = { | ||
576 | .independent_clocks = true, | ||
577 | }; | ||
578 | |||
575 | static int __init armada_xp_pmsu_cpufreq_init(void) | 579 | static int __init armada_xp_pmsu_cpufreq_init(void) |
576 | { | 580 | { |
577 | struct device_node *np; | 581 | struct device_node *np; |
@@ -644,7 +648,8 @@ static int __init armada_xp_pmsu_cpufreq_init(void) | |||
644 | } | 648 | } |
645 | } | 649 | } |
646 | 650 | ||
647 | platform_device_register_simple("cpufreq-dt", -1, NULL, 0); | 651 | platform_device_register_data(NULL, "cpufreq-dt", -1, |
652 | &cpufreq_dt_pd, sizeof(cpufreq_dt_pd)); | ||
648 | return 0; | 653 | return 0; |
649 | } | 654 | } |
650 | 655 | ||
diff --git a/arch/arm/mach-mvebu/pmsu.h b/arch/arm/mach-mvebu/pmsu.h index 6b58c1fe2b0d..ea79269c2702 100644 --- a/arch/arm/mach-mvebu/pmsu.h +++ b/arch/arm/mach-mvebu/pmsu.h | |||
@@ -17,5 +17,8 @@ int mvebu_setup_boot_addr_wa(unsigned int crypto_eng_target, | |||
17 | phys_addr_t resume_addr_reg); | 17 | phys_addr_t resume_addr_reg); |
18 | 18 | ||
19 | void mvebu_v7_pmsu_idle_exit(void); | 19 | void mvebu_v7_pmsu_idle_exit(void); |
20 | void armada_370_xp_cpu_resume(void); | ||
20 | 21 | ||
22 | int armada_370_xp_pmsu_idle_enter(unsigned long deepidle); | ||
23 | int armada_38x_do_cpu_suspend(unsigned long deepidle); | ||
21 | #endif /* __MACH_370_XP_PMSU_H */ | 24 | #endif /* __MACH_370_XP_PMSU_H */ |
diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S index a945756cfb45..88651221dbdd 100644 --- a/arch/arm/mach-mvebu/pmsu_ll.S +++ b/arch/arm/mach-mvebu/pmsu_ll.S | |||
@@ -12,12 +12,32 @@ | |||
12 | #include <linux/linkage.h> | 12 | #include <linux/linkage.h> |
13 | #include <asm/assembler.h> | 13 | #include <asm/assembler.h> |
14 | 14 | ||
15 | |||
16 | ENTRY(armada_38x_scu_power_up) | ||
17 | mrc p15, 4, r1, c15, c0 @ get SCU base address | ||
18 | orr r1, r1, #0x8 @ SCU CPU Power Status Register | ||
19 | mrc 15, 0, r0, cr0, cr0, 5 @ get the CPU ID | ||
20 | and r0, r0, #15 | ||
21 | add r1, r1, r0 | ||
22 | mov r0, #0x0 | ||
23 | strb r0, [r1] @ switch SCU power state to Normal mode | ||
24 | ret lr | ||
25 | ENDPROC(armada_38x_scu_power_up) | ||
26 | |||
15 | /* | 27 | /* |
16 | * This is the entry point through which CPUs exiting cpuidle deep | 28 | * This is the entry point through which CPUs exiting cpuidle deep |
17 | * idle state are going. | 29 | * idle state are going. |
18 | */ | 30 | */ |
19 | ENTRY(armada_370_xp_cpu_resume) | 31 | ENTRY(armada_370_xp_cpu_resume) |
20 | ARM_BE8(setend be ) @ go BE8 if entered LE | 32 | ARM_BE8(setend be ) @ go BE8 if entered LE |
33 | /* | ||
34 | * Disable the MMU that might have been enabled in BootROM if | ||
35 | * this code is used in the resume path of a suspend/resume | ||
36 | * cycle. | ||
37 | */ | ||
38 | mrc p15, 0, r1, c1, c0, 0 | ||
39 | bic r1, #1 | ||
40 | mcr p15, 0, r1, c1, c0, 0 | ||
21 | bl ll_add_cpu_to_smp_group | 41 | bl ll_add_cpu_to_smp_group |
22 | bl ll_enable_coherency | 42 | bl ll_enable_coherency |
23 | b cpu_resume | 43 | b cpu_resume |
@@ -27,13 +47,7 @@ ENTRY(armada_38x_cpu_resume) | |||
27 | /* do we need it for Armada 38x*/ | 47 | /* do we need it for Armada 38x*/ |
28 | ARM_BE8(setend be ) @ go BE8 if entered LE | 48 | ARM_BE8(setend be ) @ go BE8 if entered LE |
29 | bl v7_invalidate_l1 | 49 | bl v7_invalidate_l1 |
30 | mrc p15, 4, r1, c15, c0 @ get SCU base address | 50 | bl armada_38x_scu_power_up |
31 | orr r1, r1, #0x8 @ SCU CPU Power Status Register | ||
32 | mrc 15, 0, r0, cr0, cr0, 5 @ get the CPU ID | ||
33 | and r0, r0, #15 | ||
34 | add r1, r1, r0 | ||
35 | mov r0, #0x0 | ||
36 | strb r0, [r1] @ switch SCU power state to Normal mode | ||
37 | b cpu_resume | 51 | b cpu_resume |
38 | ENDPROC(armada_38x_cpu_resume) | 52 | ENDPROC(armada_38x_cpu_resume) |
39 | 53 | ||
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index d9e94122073e..3b653b3ac268 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -113,7 +113,7 @@ obj-y += prm_common.o cm_common.o | |||
113 | obj-$(CONFIG_ARCH_OMAP2) += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o | 113 | obj-$(CONFIG_ARCH_OMAP2) += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o |
114 | obj-$(CONFIG_ARCH_OMAP3) += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o | 114 | obj-$(CONFIG_ARCH_OMAP3) += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o |
115 | obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o | 115 | obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o |
116 | omap-prcm-4-5-common = cminst44xx.o cm44xx.o prm44xx.o \ | 116 | omap-prcm-4-5-common = cminst44xx.o prm44xx.o \ |
117 | prcm_mpu44xx.o prminst44xx.o \ | 117 | prcm_mpu44xx.o prminst44xx.o \ |
118 | vc44xx_data.o vp44xx_data.o | 118 | vc44xx_data.o vp44xx_data.o |
119 | obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common) | 119 | obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common) |
diff --git a/arch/arm/mach-omap2/am33xx-restart.c b/arch/arm/mach-omap2/am33xx-restart.c index c88d8df753c2..5bace6a45ffb 100644 --- a/arch/arm/mach-omap2/am33xx-restart.c +++ b/arch/arm/mach-omap2/am33xx-restart.c | |||
@@ -9,8 +9,7 @@ | |||
9 | #include <linux/reboot.h> | 9 | #include <linux/reboot.h> |
10 | 10 | ||
11 | #include "common.h" | 11 | #include "common.h" |
12 | #include "prm-regbits-33xx.h" | 12 | #include "prm.h" |
13 | #include "prm33xx.h" | ||
14 | 13 | ||
15 | /** | 14 | /** |
16 | * am3xx_restart - trigger a software restart of the SoC | 15 | * am3xx_restart - trigger a software restart of the SoC |
@@ -24,12 +23,5 @@ void am33xx_restart(enum reboot_mode mode, const char *cmd) | |||
24 | { | 23 | { |
25 | /* TODO: Handle mode and cmd if necessary */ | 24 | /* TODO: Handle mode and cmd if necessary */ |
26 | 25 | ||
27 | am33xx_prm_rmw_reg_bits(AM33XX_RST_GLOBAL_WARM_SW_MASK, | 26 | omap_prm_reset_system(); |
28 | AM33XX_RST_GLOBAL_WARM_SW_MASK, | ||
29 | AM33XX_PRM_DEVICE_MOD, | ||
30 | AM33XX_PRM_RSTCTRL_OFFSET); | ||
31 | |||
32 | /* OCP barrier */ | ||
33 | (void)am33xx_prm_read_reg(AM33XX_PRM_DEVICE_MOD, | ||
34 | AM33XX_PRM_RSTCTRL_OFFSET); | ||
35 | } | 27 | } |
diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c index eb8c75ec3b1a..5c5ebb4db5f7 100644 --- a/arch/arm/mach-omap2/cclock3xxx_data.c +++ b/arch/arm/mach-omap2/cclock3xxx_data.c | |||
@@ -257,6 +257,9 @@ static const struct clk_ops dpll1_ck_ops = { | |||
257 | .get_parent = &omap2_init_dpll_parent, | 257 | .get_parent = &omap2_init_dpll_parent, |
258 | .recalc_rate = &omap3_dpll_recalc, | 258 | .recalc_rate = &omap3_dpll_recalc, |
259 | .set_rate = &omap3_noncore_dpll_set_rate, | 259 | .set_rate = &omap3_noncore_dpll_set_rate, |
260 | .set_parent = &omap3_noncore_dpll_set_parent, | ||
261 | .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, | ||
262 | .determine_rate = &omap3_noncore_dpll_determine_rate, | ||
260 | .round_rate = &omap2_dpll_round_rate, | 263 | .round_rate = &omap2_dpll_round_rate, |
261 | }; | 264 | }; |
262 | 265 | ||
@@ -367,6 +370,9 @@ static const struct clk_ops dpll4_ck_ops = { | |||
367 | .get_parent = &omap2_init_dpll_parent, | 370 | .get_parent = &omap2_init_dpll_parent, |
368 | .recalc_rate = &omap3_dpll_recalc, | 371 | .recalc_rate = &omap3_dpll_recalc, |
369 | .set_rate = &omap3_dpll4_set_rate, | 372 | .set_rate = &omap3_dpll4_set_rate, |
373 | .set_parent = &omap3_noncore_dpll_set_parent, | ||
374 | .set_rate_and_parent = &omap3_dpll4_set_rate_and_parent, | ||
375 | .determine_rate = &omap3_noncore_dpll_determine_rate, | ||
370 | .round_rate = &omap2_dpll_round_rate, | 376 | .round_rate = &omap2_dpll_round_rate, |
371 | }; | 377 | }; |
372 | 378 | ||
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 500530d1364a..6ad5b4dbd33e 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c | |||
@@ -171,7 +171,8 @@ static void _omap2_module_wait_ready(struct clk_hw_omap *clk) | |||
171 | _wait_idlest_generic(clk, idlest_reg, (1 << idlest_bit), | 171 | _wait_idlest_generic(clk, idlest_reg, (1 << idlest_bit), |
172 | idlest_val, __clk_get_name(clk->hw.clk)); | 172 | idlest_val, __clk_get_name(clk->hw.clk)); |
173 | } else { | 173 | } else { |
174 | cm_wait_module_ready(prcm_mod, idlest_reg_id, idlest_bit); | 174 | omap_cm_wait_module_ready(0, prcm_mod, idlest_reg_id, |
175 | idlest_bit); | ||
175 | }; | 176 | }; |
176 | } | 177 | } |
177 | 178 | ||
@@ -771,4 +772,8 @@ void __init ti_clk_init_features(void) | |||
771 | ti_clk_features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL; | 772 | ti_clk_features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL; |
772 | else if (cpu_is_omap34xx()) | 773 | else if (cpu_is_omap34xx()) |
773 | ti_clk_features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL; | 774 | ti_clk_features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL; |
775 | |||
776 | /* On OMAP3430 ES1.0, DPLL4 can't be re-programmed */ | ||
777 | if (omap_rev() == OMAP3430_REV_ES1_0) | ||
778 | ti_clk_features.flags |= TI_CLK_DPLL4_DENY_REPROGRAM; | ||
774 | } | 779 | } |
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 4592a2762592..641337c6cde9 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h | |||
@@ -234,6 +234,7 @@ struct ti_clk_features { | |||
234 | }; | 234 | }; |
235 | 235 | ||
236 | #define TI_CLK_DPLL_HAS_FREQSEL (1 << 0) | 236 | #define TI_CLK_DPLL_HAS_FREQSEL (1 << 0) |
237 | #define TI_CLK_DPLL4_DENY_REPROGRAM (1 << 1) | ||
237 | 238 | ||
238 | extern struct ti_clk_features ti_clk_features; | 239 | extern struct ti_clk_features ti_clk_features; |
239 | 240 | ||
diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c index 0b02b4161d71..a9e86db5daf9 100644 --- a/arch/arm/mach-omap2/clock3xxx.c +++ b/arch/arm/mach-omap2/clock3xxx.c | |||
@@ -38,6 +38,18 @@ | |||
38 | 38 | ||
39 | /* needed by omap3_core_dpll_m2_set_rate() */ | 39 | /* needed by omap3_core_dpll_m2_set_rate() */ |
40 | struct clk *sdrc_ick_p, *arm_fck_p; | 40 | struct clk *sdrc_ick_p, *arm_fck_p; |
41 | |||
42 | /** | ||
43 | * omap3_dpll4_set_rate - set rate for omap3 per-dpll | ||
44 | * @hw: clock to change | ||
45 | * @rate: target rate for clock | ||
46 | * @parent_rate: rate of the parent clock | ||
47 | * | ||
48 | * Check if the current SoC supports the per-dpll reprogram operation | ||
49 | * or not, and then do the rate change if supported. Returns -EINVAL | ||
50 | * if not supported, 0 for success, and potential error codes from the | ||
51 | * clock rate change. | ||
52 | */ | ||
41 | int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate, | 53 | int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate, |
42 | unsigned long parent_rate) | 54 | unsigned long parent_rate) |
43 | { | 55 | { |
@@ -46,7 +58,7 @@ int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate, | |||
46 | * on 3430ES1 prevents us from changing DPLL multipliers or dividers | 58 | * on 3430ES1 prevents us from changing DPLL multipliers or dividers |
47 | * on DPLL4. | 59 | * on DPLL4. |
48 | */ | 60 | */ |
49 | if (omap_rev() == OMAP3430_REV_ES1_0) { | 61 | if (ti_clk_features.flags & TI_CLK_DPLL4_DENY_REPROGRAM) { |
50 | pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n"); | 62 | pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n"); |
51 | return -EINVAL; | 63 | return -EINVAL; |
52 | } | 64 | } |
@@ -54,6 +66,30 @@ int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate, | |||
54 | return omap3_noncore_dpll_set_rate(hw, rate, parent_rate); | 66 | return omap3_noncore_dpll_set_rate(hw, rate, parent_rate); |
55 | } | 67 | } |
56 | 68 | ||
69 | /** | ||
70 | * omap3_dpll4_set_rate_and_parent - set rate and parent for omap3 per-dpll | ||
71 | * @hw: clock to change | ||
72 | * @rate: target rate for clock | ||
73 | * @parent_rate: rate of the parent clock | ||
74 | * @index: parent index, 0 - reference clock, 1 - bypass clock | ||
75 | * | ||
76 | * Check if the current SoC support the per-dpll reprogram operation | ||
77 | * or not, and then do the rate + parent change if supported. Returns | ||
78 | * -EINVAL if not supported, 0 for success, and potential error codes | ||
79 | * from the clock rate change. | ||
80 | */ | ||
81 | int omap3_dpll4_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, | ||
82 | unsigned long parent_rate, u8 index) | ||
83 | { | ||
84 | if (ti_clk_features.flags & TI_CLK_DPLL4_DENY_REPROGRAM) { | ||
85 | pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n"); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | |||
89 | return omap3_noncore_dpll_set_rate_and_parent(hw, rate, parent_rate, | ||
90 | index); | ||
91 | } | ||
92 | |||
57 | void __init omap3_clk_lock_dpll5(void) | 93 | void __init omap3_clk_lock_dpll5(void) |
58 | { | 94 | { |
59 | struct clk *dpll5_clk; | 95 | struct clk *dpll5_clk; |
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index 93473f9a551c..6222e87a79b6 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h | |||
@@ -45,17 +45,29 @@ extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2); | |||
45 | * struct cm_ll_data - fn ptrs to per-SoC CM function implementations | 45 | * struct cm_ll_data - fn ptrs to per-SoC CM function implementations |
46 | * @split_idlest_reg: ptr to the SoC CM-specific split_idlest_reg impl | 46 | * @split_idlest_reg: ptr to the SoC CM-specific split_idlest_reg impl |
47 | * @wait_module_ready: ptr to the SoC CM-specific wait_module_ready impl | 47 | * @wait_module_ready: ptr to the SoC CM-specific wait_module_ready impl |
48 | * @wait_module_idle: ptr to the SoC CM-specific wait_module_idle impl | ||
49 | * @module_enable: ptr to the SoC CM-specific module_enable impl | ||
50 | * @module_disable: ptr to the SoC CM-specific module_disable impl | ||
48 | */ | 51 | */ |
49 | struct cm_ll_data { | 52 | struct cm_ll_data { |
50 | int (*split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst, | 53 | int (*split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst, |
51 | u8 *idlest_reg_id); | 54 | u8 *idlest_reg_id); |
52 | int (*wait_module_ready)(s16 prcm_mod, u8 idlest_id, u8 idlest_shift); | 55 | int (*wait_module_ready)(u8 part, s16 prcm_mod, u16 idlest_reg, |
56 | u8 idlest_shift); | ||
57 | int (*wait_module_idle)(u8 part, s16 prcm_mod, u16 idlest_reg, | ||
58 | u8 idlest_shift); | ||
59 | void (*module_enable)(u8 mode, u8 part, u16 inst, u16 clkctrl_offs); | ||
60 | void (*module_disable)(u8 part, u16 inst, u16 clkctrl_offs); | ||
53 | }; | 61 | }; |
54 | 62 | ||
55 | extern int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, | 63 | extern int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, |
56 | u8 *idlest_reg_id); | 64 | u8 *idlest_reg_id); |
57 | extern int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift); | 65 | int omap_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_reg, |
58 | 66 | u8 idlest_shift); | |
67 | int omap_cm_wait_module_idle(u8 part, s16 prcm_mod, u16 idlest_reg, | ||
68 | u8 idlest_shift); | ||
69 | int omap_cm_module_enable(u8 mode, u8 part, u16 inst, u16 clkctrl_offs); | ||
70 | int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs); | ||
59 | extern int cm_register(struct cm_ll_data *cld); | 71 | extern int cm_register(struct cm_ll_data *cld); |
60 | extern int cm_unregister(struct cm_ll_data *cld); | 72 | extern int cm_unregister(struct cm_ll_data *cld); |
61 | 73 | ||
diff --git a/arch/arm/mach-omap2/cm1_44xx.h b/arch/arm/mach-omap2/cm1_44xx.h index 5ae8fe39d6ee..a5949927b661 100644 --- a/arch/arm/mach-omap2/cm1_44xx.h +++ b/arch/arm/mach-omap2/cm1_44xx.h | |||
@@ -25,8 +25,6 @@ | |||
25 | #ifndef __ARCH_ARM_MACH_OMAP2_CM1_44XX_H | 25 | #ifndef __ARCH_ARM_MACH_OMAP2_CM1_44XX_H |
26 | #define __ARCH_ARM_MACH_OMAP2_CM1_44XX_H | 26 | #define __ARCH_ARM_MACH_OMAP2_CM1_44XX_H |
27 | 27 | ||
28 | #include "cm_44xx_54xx.h" | ||
29 | |||
30 | /* CM1 base address */ | 28 | /* CM1 base address */ |
31 | #define OMAP4430_CM1_BASE 0x4a004000 | 29 | #define OMAP4430_CM1_BASE 0x4a004000 |
32 | 30 | ||
diff --git a/arch/arm/mach-omap2/cm1_54xx.h b/arch/arm/mach-omap2/cm1_54xx.h index 90b3348e6672..fd245dfa7391 100644 --- a/arch/arm/mach-omap2/cm1_54xx.h +++ b/arch/arm/mach-omap2/cm1_54xx.h | |||
@@ -22,8 +22,6 @@ | |||
22 | #ifndef __ARCH_ARM_MACH_OMAP2_CM1_54XX_H | 22 | #ifndef __ARCH_ARM_MACH_OMAP2_CM1_54XX_H |
23 | #define __ARCH_ARM_MACH_OMAP2_CM1_54XX_H | 23 | #define __ARCH_ARM_MACH_OMAP2_CM1_54XX_H |
24 | 24 | ||
25 | #include "cm_44xx_54xx.h" | ||
26 | |||
27 | /* CM1 base address */ | 25 | /* CM1 base address */ |
28 | #define OMAP54XX_CM_CORE_AON_BASE 0x4a004000 | 26 | #define OMAP54XX_CM_CORE_AON_BASE 0x4a004000 |
29 | 27 | ||
diff --git a/arch/arm/mach-omap2/cm1_7xx.h b/arch/arm/mach-omap2/cm1_7xx.h index ca6fa1febaac..2f1c09eea021 100644 --- a/arch/arm/mach-omap2/cm1_7xx.h +++ b/arch/arm/mach-omap2/cm1_7xx.h | |||
@@ -23,8 +23,6 @@ | |||
23 | #ifndef __ARCH_ARM_MACH_OMAP2_CM1_7XX_H | 23 | #ifndef __ARCH_ARM_MACH_OMAP2_CM1_7XX_H |
24 | #define __ARCH_ARM_MACH_OMAP2_CM1_7XX_H | 24 | #define __ARCH_ARM_MACH_OMAP2_CM1_7XX_H |
25 | 25 | ||
26 | #include "cm_44xx_54xx.h" | ||
27 | |||
28 | /* CM1 base address */ | 26 | /* CM1 base address */ |
29 | #define DRA7XX_CM_CORE_AON_BASE 0x4a005000 | 27 | #define DRA7XX_CM_CORE_AON_BASE 0x4a005000 |
30 | 28 | ||
diff --git a/arch/arm/mach-omap2/cm2_44xx.h b/arch/arm/mach-omap2/cm2_44xx.h index ee5136d7cdda..7521abf3d830 100644 --- a/arch/arm/mach-omap2/cm2_44xx.h +++ b/arch/arm/mach-omap2/cm2_44xx.h | |||
@@ -25,8 +25,6 @@ | |||
25 | #ifndef __ARCH_ARM_MACH_OMAP2_CM2_44XX_H | 25 | #ifndef __ARCH_ARM_MACH_OMAP2_CM2_44XX_H |
26 | #define __ARCH_ARM_MACH_OMAP2_CM2_44XX_H | 26 | #define __ARCH_ARM_MACH_OMAP2_CM2_44XX_H |
27 | 27 | ||
28 | #include "cm_44xx_54xx.h" | ||
29 | |||
30 | /* CM2 base address */ | 28 | /* CM2 base address */ |
31 | #define OMAP4430_CM2_BASE 0x4a008000 | 29 | #define OMAP4430_CM2_BASE 0x4a008000 |
32 | 30 | ||
diff --git a/arch/arm/mach-omap2/cm2_54xx.h b/arch/arm/mach-omap2/cm2_54xx.h index 2683231b299b..ff4040c196d8 100644 --- a/arch/arm/mach-omap2/cm2_54xx.h +++ b/arch/arm/mach-omap2/cm2_54xx.h | |||
@@ -21,8 +21,6 @@ | |||
21 | #ifndef __ARCH_ARM_MACH_OMAP2_CM2_54XX_H | 21 | #ifndef __ARCH_ARM_MACH_OMAP2_CM2_54XX_H |
22 | #define __ARCH_ARM_MACH_OMAP2_CM2_54XX_H | 22 | #define __ARCH_ARM_MACH_OMAP2_CM2_54XX_H |
23 | 23 | ||
24 | #include "cm_44xx_54xx.h" | ||
25 | |||
26 | /* CM2 base address */ | 24 | /* CM2 base address */ |
27 | #define OMAP54XX_CM_CORE_BASE 0x4a008000 | 25 | #define OMAP54XX_CM_CORE_BASE 0x4a008000 |
28 | 26 | ||
diff --git a/arch/arm/mach-omap2/cm2_7xx.h b/arch/arm/mach-omap2/cm2_7xx.h index e966e3a3c931..ce63fdb68056 100644 --- a/arch/arm/mach-omap2/cm2_7xx.h +++ b/arch/arm/mach-omap2/cm2_7xx.h | |||
@@ -22,8 +22,6 @@ | |||
22 | #ifndef __ARCH_ARM_MACH_OMAP2_CM2_7XX_H | 22 | #ifndef __ARCH_ARM_MACH_OMAP2_CM2_7XX_H |
23 | #define __ARCH_ARM_MACH_OMAP2_CM2_7XX_H | 23 | #define __ARCH_ARM_MACH_OMAP2_CM2_7XX_H |
24 | 24 | ||
25 | #include "cm_44xx_54xx.h" | ||
26 | |||
27 | /* CM2 base address */ | 25 | /* CM2 base address */ |
28 | #define DRA7XX_CM_CORE_BASE 0x4a008000 | 26 | #define DRA7XX_CM_CORE_BASE 0x4a008000 |
29 | 27 | ||
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c index 8be6ea50c092..a96d901b1d5d 100644 --- a/arch/arm/mach-omap2/cm2xxx.c +++ b/arch/arm/mach-omap2/cm2xxx.c | |||
@@ -53,7 +53,7 @@ static void _write_clktrctrl(u8 c, s16 module, u32 mask) | |||
53 | omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL); | 53 | omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL); |
54 | } | 54 | } |
55 | 55 | ||
56 | bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) | 56 | static bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) |
57 | { | 57 | { |
58 | u32 v; | 58 | u32 v; |
59 | 59 | ||
@@ -64,12 +64,12 @@ bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) | |||
64 | return (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0; | 64 | return (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0; |
65 | } | 65 | } |
66 | 66 | ||
67 | void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) | 67 | static void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) |
68 | { | 68 | { |
69 | _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask); | 69 | _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask); |
70 | } | 70 | } |
71 | 71 | ||
72 | void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask) | 72 | static void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask) |
73 | { | 73 | { |
74 | _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask); | 74 | _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask); |
75 | } | 75 | } |
@@ -150,7 +150,7 @@ static int _omap2xxx_apll_enable(u8 enable_bit, u8 status_bit) | |||
150 | v |= m; | 150 | v |= m; |
151 | omap2_cm_write_mod_reg(v, PLL_MOD, CM_CLKEN); | 151 | omap2_cm_write_mod_reg(v, PLL_MOD, CM_CLKEN); |
152 | 152 | ||
153 | omap2xxx_cm_wait_module_ready(PLL_MOD, 1, status_bit); | 153 | omap2xxx_cm_wait_module_ready(0, PLL_MOD, 1, status_bit); |
154 | 154 | ||
155 | /* | 155 | /* |
156 | * REVISIT: Should we return an error code if | 156 | * REVISIT: Should we return an error code if |
@@ -204,8 +204,9 @@ void omap2xxx_cm_apll96_disable(void) | |||
204 | * XXX This function is only needed until absolute register addresses are | 204 | * XXX This function is only needed until absolute register addresses are |
205 | * removed from the OMAP struct clk records. | 205 | * removed from the OMAP struct clk records. |
206 | */ | 206 | */ |
207 | int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, | 207 | static int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, |
208 | u8 *idlest_reg_id) | 208 | s16 *prcm_inst, |
209 | u8 *idlest_reg_id) | ||
209 | { | 210 | { |
210 | unsigned long offs; | 211 | unsigned long offs; |
211 | u8 idlest_offs; | 212 | u8 idlest_offs; |
@@ -238,6 +239,7 @@ int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, | |||
238 | 239 | ||
239 | /** | 240 | /** |
240 | * omap2xxx_cm_wait_module_ready - wait for a module to leave idle or standby | 241 | * omap2xxx_cm_wait_module_ready - wait for a module to leave idle or standby |
242 | * @part: PRCM partition, ignored for OMAP2 | ||
241 | * @prcm_mod: PRCM module offset | 243 | * @prcm_mod: PRCM module offset |
242 | * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) | 244 | * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) |
243 | * @idlest_shift: shift of the bit in the CM_IDLEST* register to check | 245 | * @idlest_shift: shift of the bit in the CM_IDLEST* register to check |
@@ -246,7 +248,8 @@ int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, | |||
246 | * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon | 248 | * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon |
247 | * success or -EBUSY if the module doesn't enable in time. | 249 | * success or -EBUSY if the module doesn't enable in time. |
248 | */ | 250 | */ |
249 | int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) | 251 | int omap2xxx_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_id, |
252 | u8 idlest_shift) | ||
250 | { | 253 | { |
251 | int ena = 0, i = 0; | 254 | int ena = 0, i = 0; |
252 | u8 cm_idlest_reg; | 255 | u8 cm_idlest_reg; |
diff --git a/arch/arm/mach-omap2/cm2xxx.h b/arch/arm/mach-omap2/cm2xxx.h index 891d81c3c8f4..c89502b168ae 100644 --- a/arch/arm/mach-omap2/cm2xxx.h +++ b/arch/arm/mach-omap2/cm2xxx.h | |||
@@ -46,9 +46,6 @@ | |||
46 | 46 | ||
47 | #ifndef __ASSEMBLER__ | 47 | #ifndef __ASSEMBLER__ |
48 | 48 | ||
49 | extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask); | ||
50 | extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask); | ||
51 | |||
52 | extern void omap2xxx_cm_set_dpll_disable_autoidle(void); | 49 | extern void omap2xxx_cm_set_dpll_disable_autoidle(void); |
53 | extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void); | 50 | extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void); |
54 | 51 | ||
@@ -57,11 +54,8 @@ extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void); | |||
57 | extern void omap2xxx_cm_set_apll96_disable_autoidle(void); | 54 | extern void omap2xxx_cm_set_apll96_disable_autoidle(void); |
58 | extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void); | 55 | extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void); |
59 | 56 | ||
60 | extern bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask); | 57 | int omap2xxx_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_id, |
61 | extern int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, | 58 | u8 idlest_shift); |
62 | u8 idlest_shift); | ||
63 | extern int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, | ||
64 | s16 *prcm_inst, u8 *idlest_reg_id); | ||
65 | extern int omap2xxx_cm_fclks_active(void); | 59 | extern int omap2xxx_cm_fclks_active(void); |
66 | extern int omap2xxx_cm_mpu_retention_allowed(void); | 60 | extern int omap2xxx_cm_mpu_retention_allowed(void); |
67 | extern u32 omap2xxx_cm_get_core_clk_src(void); | 61 | extern u32 omap2xxx_cm_get_core_clk_src(void); |
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index b3f99e93def0..b9ad463a368a 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c | |||
@@ -96,13 +96,12 @@ static inline u32 am33xx_cm_read_reg_bits(u16 inst, s16 idx, u32 mask) | |||
96 | /** | 96 | /** |
97 | * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield | 97 | * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield |
98 | * @inst: CM instance register offset (*_INST macro) | 98 | * @inst: CM instance register offset (*_INST macro) |
99 | * @cdoffs: Clockdomain register offset (*_CDOFFS macro) | ||
100 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 99 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
101 | * | 100 | * |
102 | * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to | 101 | * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to |
103 | * bit 0. | 102 | * bit 0. |
104 | */ | 103 | */ |
105 | static u32 _clkctrl_idlest(u16 inst, s16 cdoffs, u16 clkctrl_offs) | 104 | static u32 _clkctrl_idlest(u16 inst, u16 clkctrl_offs) |
106 | { | 105 | { |
107 | u32 v = am33xx_cm_read_reg(inst, clkctrl_offs); | 106 | u32 v = am33xx_cm_read_reg(inst, clkctrl_offs); |
108 | v &= AM33XX_IDLEST_MASK; | 107 | v &= AM33XX_IDLEST_MASK; |
@@ -113,17 +112,16 @@ static u32 _clkctrl_idlest(u16 inst, s16 cdoffs, u16 clkctrl_offs) | |||
113 | /** | 112 | /** |
114 | * _is_module_ready - can module registers be accessed without causing an abort? | 113 | * _is_module_ready - can module registers be accessed without causing an abort? |
115 | * @inst: CM instance register offset (*_INST macro) | 114 | * @inst: CM instance register offset (*_INST macro) |
116 | * @cdoffs: Clockdomain register offset (*_CDOFFS macro) | ||
117 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 115 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
118 | * | 116 | * |
119 | * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either | 117 | * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either |
120 | * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. | 118 | * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. |
121 | */ | 119 | */ |
122 | static bool _is_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) | 120 | static bool _is_module_ready(u16 inst, u16 clkctrl_offs) |
123 | { | 121 | { |
124 | u32 v; | 122 | u32 v; |
125 | 123 | ||
126 | v = _clkctrl_idlest(inst, cdoffs, clkctrl_offs); | 124 | v = _clkctrl_idlest(inst, clkctrl_offs); |
127 | 125 | ||
128 | return (v == CLKCTRL_IDLEST_FUNCTIONAL || | 126 | return (v == CLKCTRL_IDLEST_FUNCTIONAL || |
129 | v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false; | 127 | v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false; |
@@ -158,7 +156,7 @@ static void _clktrctrl_write(u8 c, u16 inst, u16 cdoffs) | |||
158 | * Returns true if the clockdomain referred to by (@inst, @cdoffs) | 156 | * Returns true if the clockdomain referred to by (@inst, @cdoffs) |
159 | * is in hardware-supervised idle mode, or 0 otherwise. | 157 | * is in hardware-supervised idle mode, or 0 otherwise. |
160 | */ | 158 | */ |
161 | bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs) | 159 | static bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs) |
162 | { | 160 | { |
163 | u32 v; | 161 | u32 v; |
164 | 162 | ||
@@ -177,7 +175,7 @@ bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs) | |||
177 | * Put a clockdomain referred to by (@inst, @cdoffs) into | 175 | * Put a clockdomain referred to by (@inst, @cdoffs) into |
178 | * hardware-supervised idle mode. No return value. | 176 | * hardware-supervised idle mode. No return value. |
179 | */ | 177 | */ |
180 | void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs) | 178 | static void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs) |
181 | { | 179 | { |
182 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, inst, cdoffs); | 180 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, inst, cdoffs); |
183 | } | 181 | } |
@@ -191,7 +189,7 @@ void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs) | |||
191 | * software-supervised idle mode, i.e., controlled manually by the | 189 | * software-supervised idle mode, i.e., controlled manually by the |
192 | * Linux OMAP clockdomain code. No return value. | 190 | * Linux OMAP clockdomain code. No return value. |
193 | */ | 191 | */ |
194 | void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs) | 192 | static void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs) |
195 | { | 193 | { |
196 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, inst, cdoffs); | 194 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, inst, cdoffs); |
197 | } | 195 | } |
@@ -204,7 +202,7 @@ void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs) | |||
204 | * Put a clockdomain referred to by (@inst, @cdoffs) into idle | 202 | * Put a clockdomain referred to by (@inst, @cdoffs) into idle |
205 | * No return value. | 203 | * No return value. |
206 | */ | 204 | */ |
207 | void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs) | 205 | static void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs) |
208 | { | 206 | { |
209 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, inst, cdoffs); | 207 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, inst, cdoffs); |
210 | } | 208 | } |
@@ -217,7 +215,7 @@ void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs) | |||
217 | * Take a clockdomain referred to by (@inst, @cdoffs) out of idle, | 215 | * Take a clockdomain referred to by (@inst, @cdoffs) out of idle, |
218 | * waking it up. No return value. | 216 | * waking it up. No return value. |
219 | */ | 217 | */ |
220 | void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs) | 218 | static void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs) |
221 | { | 219 | { |
222 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, inst, cdoffs); | 220 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, inst, cdoffs); |
223 | } | 221 | } |
@@ -228,20 +226,22 @@ void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs) | |||
228 | 226 | ||
229 | /** | 227 | /** |
230 | * am33xx_cm_wait_module_ready - wait for a module to be in 'func' state | 228 | * am33xx_cm_wait_module_ready - wait for a module to be in 'func' state |
229 | * @part: PRCM partition, ignored for AM33xx | ||
231 | * @inst: CM instance register offset (*_INST macro) | 230 | * @inst: CM instance register offset (*_INST macro) |
232 | * @cdoffs: Clockdomain register offset (*_CDOFFS macro) | ||
233 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 231 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
232 | * @bit_shift: bit shift for the register, ignored for AM33xx | ||
234 | * | 233 | * |
235 | * Wait for the module IDLEST to be functional. If the idle state is in any | 234 | * Wait for the module IDLEST to be functional. If the idle state is in any |
236 | * the non functional state (trans, idle or disabled), module and thus the | 235 | * the non functional state (trans, idle or disabled), module and thus the |
237 | * sysconfig cannot be accessed and will probably lead to an "imprecise | 236 | * sysconfig cannot be accessed and will probably lead to an "imprecise |
238 | * external abort" | 237 | * external abort" |
239 | */ | 238 | */ |
240 | int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) | 239 | static int am33xx_cm_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs, |
240 | u8 bit_shift) | ||
241 | { | 241 | { |
242 | int i = 0; | 242 | int i = 0; |
243 | 243 | ||
244 | omap_test_timeout(_is_module_ready(inst, cdoffs, clkctrl_offs), | 244 | omap_test_timeout(_is_module_ready(inst, clkctrl_offs), |
245 | MAX_MODULE_READY_TIME, i); | 245 | MAX_MODULE_READY_TIME, i); |
246 | 246 | ||
247 | return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; | 247 | return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; |
@@ -250,22 +250,24 @@ int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) | |||
250 | /** | 250 | /** |
251 | * am33xx_cm_wait_module_idle - wait for a module to be in 'disabled' | 251 | * am33xx_cm_wait_module_idle - wait for a module to be in 'disabled' |
252 | * state | 252 | * state |
253 | * @part: CM partition, ignored for AM33xx | ||
253 | * @inst: CM instance register offset (*_INST macro) | 254 | * @inst: CM instance register offset (*_INST macro) |
254 | * @cdoffs: Clockdomain register offset (*_CDOFFS macro) | ||
255 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 255 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
256 | * @bit_shift: bit shift for the register, ignored for AM33xx | ||
256 | * | 257 | * |
257 | * Wait for the module IDLEST to be disabled. Some PRCM transition, | 258 | * Wait for the module IDLEST to be disabled. Some PRCM transition, |
258 | * like reset assertion or parent clock de-activation must wait the | 259 | * like reset assertion or parent clock de-activation must wait the |
259 | * module to be fully disabled. | 260 | * module to be fully disabled. |
260 | */ | 261 | */ |
261 | int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, u16 clkctrl_offs) | 262 | static int am33xx_cm_wait_module_idle(u8 part, s16 inst, u16 clkctrl_offs, |
263 | u8 bit_shift) | ||
262 | { | 264 | { |
263 | int i = 0; | 265 | int i = 0; |
264 | 266 | ||
265 | if (!clkctrl_offs) | 267 | if (!clkctrl_offs) |
266 | return 0; | 268 | return 0; |
267 | 269 | ||
268 | omap_test_timeout((_clkctrl_idlest(inst, cdoffs, clkctrl_offs) == | 270 | omap_test_timeout((_clkctrl_idlest(inst, clkctrl_offs) == |
269 | CLKCTRL_IDLEST_DISABLED), | 271 | CLKCTRL_IDLEST_DISABLED), |
270 | MAX_MODULE_READY_TIME, i); | 272 | MAX_MODULE_READY_TIME, i); |
271 | 273 | ||
@@ -275,13 +277,14 @@ int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, u16 clkctrl_offs) | |||
275 | /** | 277 | /** |
276 | * am33xx_cm_module_enable - Enable the modulemode inside CLKCTRL | 278 | * am33xx_cm_module_enable - Enable the modulemode inside CLKCTRL |
277 | * @mode: Module mode (SW or HW) | 279 | * @mode: Module mode (SW or HW) |
280 | * @part: CM partition, ignored for AM33xx | ||
278 | * @inst: CM instance register offset (*_INST macro) | 281 | * @inst: CM instance register offset (*_INST macro) |
279 | * @cdoffs: Clockdomain register offset (*_CDOFFS macro) | ||
280 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 282 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
281 | * | 283 | * |
282 | * No return value. | 284 | * No return value. |
283 | */ | 285 | */ |
284 | void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, u16 clkctrl_offs) | 286 | static void am33xx_cm_module_enable(u8 mode, u8 part, u16 inst, |
287 | u16 clkctrl_offs) | ||
285 | { | 288 | { |
286 | u32 v; | 289 | u32 v; |
287 | 290 | ||
@@ -293,13 +296,13 @@ void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, u16 clkctrl_offs) | |||
293 | 296 | ||
294 | /** | 297 | /** |
295 | * am33xx_cm_module_disable - Disable the module inside CLKCTRL | 298 | * am33xx_cm_module_disable - Disable the module inside CLKCTRL |
299 | * @part: CM partition, ignored for AM33xx | ||
296 | * @inst: CM instance register offset (*_INST macro) | 300 | * @inst: CM instance register offset (*_INST macro) |
297 | * @cdoffs: Clockdomain register offset (*_CDOFFS macro) | ||
298 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 301 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
299 | * | 302 | * |
300 | * No return value. | 303 | * No return value. |
301 | */ | 304 | */ |
302 | void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs) | 305 | static void am33xx_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs) |
303 | { | 306 | { |
304 | u32 v; | 307 | u32 v; |
305 | 308 | ||
@@ -362,3 +365,21 @@ struct clkdm_ops am33xx_clkdm_operations = { | |||
362 | .clkdm_clk_enable = am33xx_clkdm_clk_enable, | 365 | .clkdm_clk_enable = am33xx_clkdm_clk_enable, |
363 | .clkdm_clk_disable = am33xx_clkdm_clk_disable, | 366 | .clkdm_clk_disable = am33xx_clkdm_clk_disable, |
364 | }; | 367 | }; |
368 | |||
369 | static struct cm_ll_data am33xx_cm_ll_data = { | ||
370 | .wait_module_ready = &am33xx_cm_wait_module_ready, | ||
371 | .wait_module_idle = &am33xx_cm_wait_module_idle, | ||
372 | .module_enable = &am33xx_cm_module_enable, | ||
373 | .module_disable = &am33xx_cm_module_disable, | ||
374 | }; | ||
375 | |||
376 | int __init am33xx_cm_init(void) | ||
377 | { | ||
378 | return cm_register(&am33xx_cm_ll_data); | ||
379 | } | ||
380 | |||
381 | static void __exit am33xx_cm_exit(void) | ||
382 | { | ||
383 | cm_unregister(&am33xx_cm_ll_data); | ||
384 | } | ||
385 | __exitcall(am33xx_cm_exit); | ||
diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h index bd2441790779..046b4b2bc9d9 100644 --- a/arch/arm/mach-omap2/cm33xx.h +++ b/arch/arm/mach-omap2/cm33xx.h | |||
@@ -374,41 +374,6 @@ | |||
374 | 374 | ||
375 | 375 | ||
376 | #ifndef __ASSEMBLER__ | 376 | #ifndef __ASSEMBLER__ |
377 | bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs); | 377 | int am33xx_cm_init(void); |
378 | void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs); | ||
379 | void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs); | ||
380 | void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs); | ||
381 | void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs); | ||
382 | |||
383 | #if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) | ||
384 | extern int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, | ||
385 | u16 clkctrl_offs); | ||
386 | extern void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, | ||
387 | u16 clkctrl_offs); | ||
388 | extern void am33xx_cm_module_disable(u16 inst, s16 cdoffs, | ||
389 | u16 clkctrl_offs); | ||
390 | extern int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, | ||
391 | u16 clkctrl_offs); | ||
392 | #else | ||
393 | static inline int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, | ||
394 | u16 clkctrl_offs) | ||
395 | { | ||
396 | return 0; | ||
397 | } | ||
398 | static inline void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, | ||
399 | u16 clkctrl_offs) | ||
400 | { | ||
401 | } | ||
402 | static inline void am33xx_cm_module_disable(u16 inst, s16 cdoffs, | ||
403 | u16 clkctrl_offs) | ||
404 | { | ||
405 | } | ||
406 | static inline int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, | ||
407 | u16 clkctrl_offs) | ||
408 | { | ||
409 | return 0; | ||
410 | } | ||
411 | #endif | ||
412 | |||
413 | #endif /* ASSEMBLER */ | 378 | #endif /* ASSEMBLER */ |
414 | #endif | 379 | #endif |
diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c index 129a4e7f6ef5..ebead8f035f9 100644 --- a/arch/arm/mach-omap2/cm3xxx.c +++ b/arch/arm/mach-omap2/cm3xxx.c | |||
@@ -42,7 +42,7 @@ static void _write_clktrctrl(u8 c, s16 module, u32 mask) | |||
42 | omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL); | 42 | omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL); |
43 | } | 43 | } |
44 | 44 | ||
45 | bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) | 45 | static bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) |
46 | { | 46 | { |
47 | u32 v; | 47 | u32 v; |
48 | 48 | ||
@@ -53,22 +53,22 @@ bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) | |||
53 | return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0; | 53 | return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0; |
54 | } | 54 | } |
55 | 55 | ||
56 | void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) | 56 | static void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) |
57 | { | 57 | { |
58 | _write_clktrctrl(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, module, mask); | 58 | _write_clktrctrl(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, module, mask); |
59 | } | 59 | } |
60 | 60 | ||
61 | void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask) | 61 | static void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask) |
62 | { | 62 | { |
63 | _write_clktrctrl(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, module, mask); | 63 | _write_clktrctrl(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, module, mask); |
64 | } | 64 | } |
65 | 65 | ||
66 | void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask) | 66 | static void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask) |
67 | { | 67 | { |
68 | _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, module, mask); | 68 | _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, module, mask); |
69 | } | 69 | } |
70 | 70 | ||
71 | void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask) | 71 | static void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask) |
72 | { | 72 | { |
73 | _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask); | 73 | _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask); |
74 | } | 74 | } |
@@ -79,6 +79,7 @@ void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask) | |||
79 | 79 | ||
80 | /** | 80 | /** |
81 | * omap3xxx_cm_wait_module_ready - wait for a module to leave idle or standby | 81 | * omap3xxx_cm_wait_module_ready - wait for a module to leave idle or standby |
82 | * @part: PRCM partition, ignored for OMAP3 | ||
82 | * @prcm_mod: PRCM module offset | 83 | * @prcm_mod: PRCM module offset |
83 | * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) | 84 | * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) |
84 | * @idlest_shift: shift of the bit in the CM_IDLEST* register to check | 85 | * @idlest_shift: shift of the bit in the CM_IDLEST* register to check |
@@ -87,7 +88,8 @@ void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask) | |||
87 | * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon | 88 | * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon |
88 | * success or -EBUSY if the module doesn't enable in time. | 89 | * success or -EBUSY if the module doesn't enable in time. |
89 | */ | 90 | */ |
90 | int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) | 91 | static int omap3xxx_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_id, |
92 | u8 idlest_shift) | ||
91 | { | 93 | { |
92 | int ena = 0, i = 0; | 94 | int ena = 0, i = 0; |
93 | u8 cm_idlest_reg; | 95 | u8 cm_idlest_reg; |
@@ -116,8 +118,9 @@ int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) | |||
116 | * XXX This function is only needed until absolute register addresses are | 118 | * XXX This function is only needed until absolute register addresses are |
117 | * removed from the OMAP struct clk records. | 119 | * removed from the OMAP struct clk records. |
118 | */ | 120 | */ |
119 | int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, | 121 | static int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg, |
120 | u8 *idlest_reg_id) | 122 | s16 *prcm_inst, |
123 | u8 *idlest_reg_id) | ||
121 | { | 124 | { |
122 | unsigned long offs; | 125 | unsigned long offs; |
123 | u8 idlest_offs; | 126 | u8 idlest_offs; |
diff --git a/arch/arm/mach-omap2/cm3xxx.h b/arch/arm/mach-omap2/cm3xxx.h index 7a16b5598127..734a8581c0c4 100644 --- a/arch/arm/mach-omap2/cm3xxx.h +++ b/arch/arm/mach-omap2/cm3xxx.h | |||
@@ -68,18 +68,6 @@ | |||
68 | 68 | ||
69 | #ifndef __ASSEMBLER__ | 69 | #ifndef __ASSEMBLER__ |
70 | 70 | ||
71 | extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask); | ||
72 | extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask); | ||
73 | extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask); | ||
74 | extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask); | ||
75 | |||
76 | extern bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask); | ||
77 | extern int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, | ||
78 | u8 idlest_shift); | ||
79 | |||
80 | extern int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg, | ||
81 | s16 *prcm_inst, u8 *idlest_reg_id); | ||
82 | |||
83 | extern void omap3_cm_save_context(void); | 71 | extern void omap3_cm_save_context(void); |
84 | extern void omap3_cm_restore_context(void); | 72 | extern void omap3_cm_restore_context(void); |
85 | extern void omap3_cm_save_scratchpad_contents(u32 *ptr); | 73 | extern void omap3_cm_save_scratchpad_contents(u32 *ptr); |
diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c deleted file mode 100644 index fe5cc7bae489..000000000000 --- a/arch/arm/mach-omap2/cm44xx.c +++ /dev/null | |||
@@ -1,49 +0,0 @@ | |||
1 | /* | ||
2 | * OMAP4 CM1, CM2 module low-level functions | ||
3 | * | ||
4 | * Copyright (C) 2010 Nokia Corporation | ||
5 | * Paul Walmsley | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * These functions are intended to be used only by the cminst44xx.c file. | ||
12 | * XXX Perhaps we should just move them there and make them static. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/io.h> | ||
20 | |||
21 | #include "cm.h" | ||
22 | #include "cm1_44xx.h" | ||
23 | #include "cm2_44xx.h" | ||
24 | |||
25 | /* CM1 hardware module low-level functions */ | ||
26 | |||
27 | /* Read a register in CM1 */ | ||
28 | u32 omap4_cm1_read_inst_reg(s16 inst, u16 reg) | ||
29 | { | ||
30 | return readl_relaxed(cm_base + inst + reg); | ||
31 | } | ||
32 | |||
33 | /* Write into a register in CM1 */ | ||
34 | void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 reg) | ||
35 | { | ||
36 | writel_relaxed(val, cm_base + inst + reg); | ||
37 | } | ||
38 | |||
39 | /* Read a register in CM2 */ | ||
40 | u32 omap4_cm2_read_inst_reg(s16 inst, u16 reg) | ||
41 | { | ||
42 | return readl_relaxed(cm2_base + inst + reg); | ||
43 | } | ||
44 | |||
45 | /* Write into a register in CM2 */ | ||
46 | void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) | ||
47 | { | ||
48 | writel_relaxed(val, cm2_base + inst + reg); | ||
49 | } | ||
diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h index 3380beeace6e..728d06a4af19 100644 --- a/arch/arm/mach-omap2/cm44xx.h +++ b/arch/arm/mach-omap2/cm44xx.h | |||
@@ -23,4 +23,7 @@ | |||
23 | #define OMAP4_CM_CLKSTCTRL 0x0000 | 23 | #define OMAP4_CM_CLKSTCTRL 0x0000 |
24 | #define OMAP4_CM_STATICDEP 0x0004 | 24 | #define OMAP4_CM_STATICDEP 0x0004 |
25 | 25 | ||
26 | void omap_cm_base_init(void); | ||
27 | int omap4_cm_init(void); | ||
28 | |||
26 | #endif | 29 | #endif |
diff --git a/arch/arm/mach-omap2/cm_44xx_54xx.h b/arch/arm/mach-omap2/cm_44xx_54xx.h deleted file mode 100644 index cbb211690321..000000000000 --- a/arch/arm/mach-omap2/cm_44xx_54xx.h +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | /* | ||
2 | * OMAP44xx and OMAP54xx CM1/CM2 function prototypes | ||
3 | * | ||
4 | * Copyright (C) 2009-2013 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2009-2010 Nokia Corporation | ||
6 | * | ||
7 | * Paul Walmsley (paul@pwsan.com) | ||
8 | * Rajendra Nayak (rnayak@ti.com) | ||
9 | * Benoit Cousson (b-cousson@ti.com) | ||
10 | * | ||
11 | * This file is automatically generated from the OMAP hardware databases. | ||
12 | * We respectfully ask that any modifications to this file be coordinated | ||
13 | * with the public linux-omap@vger.kernel.org mailing list and the | ||
14 | * authors above to ensure that the autogeneration scripts are kept | ||
15 | * up-to-date with the file contents. | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or modify | ||
18 | * it under the terms of the GNU General Public License version 2 as | ||
19 | * published by the Free Software Foundation. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __ARCH_ARM_MACH_OMAP2_CM_44XX_54XX_H | ||
24 | #define __ARCH_ARM_MACH_OMAP2_CM_44XX_55XX_H | ||
25 | |||
26 | /* CM1 Function prototypes */ | ||
27 | extern u32 omap4_cm1_read_inst_reg(s16 inst, u16 idx); | ||
28 | extern void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 idx); | ||
29 | extern u32 omap4_cm1_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); | ||
30 | |||
31 | /* CM2 Function prototypes */ | ||
32 | extern u32 omap4_cm2_read_inst_reg(s16 inst, u16 idx); | ||
33 | extern void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 idx); | ||
34 | extern u32 omap4_cm2_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); | ||
35 | |||
36 | #endif | ||
diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c index 8f6c4710877e..8fe02fcedc48 100644 --- a/arch/arm/mach-omap2/cm_common.c +++ b/arch/arm/mach-omap2/cm_common.c | |||
@@ -72,9 +72,10 @@ int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | /** | 74 | /** |
75 | * cm_wait_module_ready - wait for a module to leave idle or standby | 75 | * omap_cm_wait_module_ready - wait for a module to leave idle or standby |
76 | * @part: PRCM partition | ||
76 | * @prcm_mod: PRCM module offset | 77 | * @prcm_mod: PRCM module offset |
77 | * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) | 78 | * @idlest_reg: CM_IDLESTx register |
78 | * @idlest_shift: shift of the bit in the CM_IDLEST* register to check | 79 | * @idlest_shift: shift of the bit in the CM_IDLEST* register to check |
79 | * | 80 | * |
80 | * Wait for the PRCM to indicate that the module identified by | 81 | * Wait for the PRCM to indicate that the module identified by |
@@ -83,7 +84,8 @@ int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, | |||
83 | * no per-SoC wait_module_ready() function pointer has been registered | 84 | * no per-SoC wait_module_ready() function pointer has been registered |
84 | * or if the idlest register is unknown on the SoC. | 85 | * or if the idlest register is unknown on the SoC. |
85 | */ | 86 | */ |
86 | int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) | 87 | int omap_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_reg, |
88 | u8 idlest_shift) | ||
87 | { | 89 | { |
88 | if (!cm_ll_data->wait_module_ready) { | 90 | if (!cm_ll_data->wait_module_ready) { |
89 | WARN_ONCE(1, "cm: %s: no low-level function defined\n", | 91 | WARN_ONCE(1, "cm: %s: no low-level function defined\n", |
@@ -91,7 +93,79 @@ int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) | |||
91 | return -EINVAL; | 93 | return -EINVAL; |
92 | } | 94 | } |
93 | 95 | ||
94 | return cm_ll_data->wait_module_ready(prcm_mod, idlest_id, idlest_shift); | 96 | return cm_ll_data->wait_module_ready(part, prcm_mod, idlest_reg, |
97 | idlest_shift); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * omap_cm_wait_module_idle - wait for a module to enter idle or standby | ||
102 | * @part: PRCM partition | ||
103 | * @prcm_mod: PRCM module offset | ||
104 | * @idlest_reg: CM_IDLESTx register | ||
105 | * @idlest_shift: shift of the bit in the CM_IDLEST* register to check | ||
106 | * | ||
107 | * Wait for the PRCM to indicate that the module identified by | ||
108 | * (@prcm_mod, @idlest_id, @idlest_shift) is no longer clocked. Return | ||
109 | * 0 upon success, -EBUSY if the module doesn't enable in time, or | ||
110 | * -EINVAL if no per-SoC wait_module_idle() function pointer has been | ||
111 | * registered or if the idlest register is unknown on the SoC. | ||
112 | */ | ||
113 | int omap_cm_wait_module_idle(u8 part, s16 prcm_mod, u16 idlest_reg, | ||
114 | u8 idlest_shift) | ||
115 | { | ||
116 | if (!cm_ll_data->wait_module_idle) { | ||
117 | WARN_ONCE(1, "cm: %s: no low-level function defined\n", | ||
118 | __func__); | ||
119 | return -EINVAL; | ||
120 | } | ||
121 | |||
122 | return cm_ll_data->wait_module_idle(part, prcm_mod, idlest_reg, | ||
123 | idlest_shift); | ||
124 | } | ||
125 | |||
126 | /** | ||
127 | * omap_cm_module_enable - enable a module | ||
128 | * @mode: target mode for the module | ||
129 | * @part: PRCM partition | ||
130 | * @inst: PRCM instance | ||
131 | * @clkctrl_offs: CM_CLKCTRL register offset for the module | ||
132 | * | ||
133 | * Enables clocks for a module identified by (@part, @inst, @clkctrl_offs) | ||
134 | * making its IO space accessible. Return 0 upon success, -EINVAL if no | ||
135 | * per-SoC module_enable() function pointer has been registered. | ||
136 | */ | ||
137 | int omap_cm_module_enable(u8 mode, u8 part, u16 inst, u16 clkctrl_offs) | ||
138 | { | ||
139 | if (!cm_ll_data->module_enable) { | ||
140 | WARN_ONCE(1, "cm: %s: no low-level function defined\n", | ||
141 | __func__); | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | |||
145 | cm_ll_data->module_enable(mode, part, inst, clkctrl_offs); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | /** | ||
150 | * omap_cm_module_disable - disable a module | ||
151 | * @part: PRCM partition | ||
152 | * @inst: PRCM instance | ||
153 | * @clkctrl_offs: CM_CLKCTRL register offset for the module | ||
154 | * | ||
155 | * Disables clocks for a module identified by (@part, @inst, @clkctrl_offs) | ||
156 | * makings its IO space inaccessible. Return 0 upon success, -EINVAL if | ||
157 | * no per-SoC module_disable() function pointer has been registered. | ||
158 | */ | ||
159 | int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs) | ||
160 | { | ||
161 | if (!cm_ll_data->module_disable) { | ||
162 | WARN_ONCE(1, "cm: %s: no low-level function defined\n", | ||
163 | __func__); | ||
164 | return -EINVAL; | ||
165 | } | ||
166 | |||
167 | cm_ll_data->module_disable(part, inst, clkctrl_offs); | ||
168 | return 0; | ||
95 | } | 169 | } |
96 | 170 | ||
97 | /** | 171 | /** |
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index 12aca56942c0..95a8cff66aff 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include "cm1_44xx.h" | 26 | #include "cm1_44xx.h" |
27 | #include "cm2_44xx.h" | 27 | #include "cm2_44xx.h" |
28 | #include "cm44xx.h" | 28 | #include "cm44xx.h" |
29 | #include "cminst44xx.h" | ||
30 | #include "cm-regbits-34xx.h" | 29 | #include "cm-regbits-34xx.h" |
31 | #include "prcm44xx.h" | 30 | #include "prcm44xx.h" |
32 | #include "prm44xx.h" | 31 | #include "prm44xx.h" |
@@ -74,17 +73,18 @@ void omap_cm_base_init(void) | |||
74 | 73 | ||
75 | /* Private functions */ | 74 | /* Private functions */ |
76 | 75 | ||
76 | static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx); | ||
77 | |||
77 | /** | 78 | /** |
78 | * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield | 79 | * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield |
79 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in | 80 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in |
80 | * @inst: CM instance register offset (*_INST macro) | 81 | * @inst: CM instance register offset (*_INST macro) |
81 | * @cdoffs: Clockdomain register offset (*_CDOFFS macro) | ||
82 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 82 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
83 | * | 83 | * |
84 | * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to | 84 | * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to |
85 | * bit 0. | 85 | * bit 0. |
86 | */ | 86 | */ |
87 | static u32 _clkctrl_idlest(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) | 87 | static u32 _clkctrl_idlest(u8 part, u16 inst, u16 clkctrl_offs) |
88 | { | 88 | { |
89 | u32 v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs); | 89 | u32 v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs); |
90 | v &= OMAP4430_IDLEST_MASK; | 90 | v &= OMAP4430_IDLEST_MASK; |
@@ -96,26 +96,23 @@ static u32 _clkctrl_idlest(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) | |||
96 | * _is_module_ready - can module registers be accessed without causing an abort? | 96 | * _is_module_ready - can module registers be accessed without causing an abort? |
97 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in | 97 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in |
98 | * @inst: CM instance register offset (*_INST macro) | 98 | * @inst: CM instance register offset (*_INST macro) |
99 | * @cdoffs: Clockdomain register offset (*_CDOFFS macro) | ||
100 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 99 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
101 | * | 100 | * |
102 | * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either | 101 | * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either |
103 | * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. | 102 | * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. |
104 | */ | 103 | */ |
105 | static bool _is_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) | 104 | static bool _is_module_ready(u8 part, u16 inst, u16 clkctrl_offs) |
106 | { | 105 | { |
107 | u32 v; | 106 | u32 v; |
108 | 107 | ||
109 | v = _clkctrl_idlest(part, inst, cdoffs, clkctrl_offs); | 108 | v = _clkctrl_idlest(part, inst, clkctrl_offs); |
110 | 109 | ||
111 | return (v == CLKCTRL_IDLEST_FUNCTIONAL || | 110 | return (v == CLKCTRL_IDLEST_FUNCTIONAL || |
112 | v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false; | 111 | v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false; |
113 | } | 112 | } |
114 | 113 | ||
115 | /* Public functions */ | ||
116 | |||
117 | /* Read a register in a CM instance */ | 114 | /* Read a register in a CM instance */ |
118 | u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) | 115 | static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) |
119 | { | 116 | { |
120 | BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || | 117 | BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || |
121 | part == OMAP4430_INVALID_PRCM_PARTITION || | 118 | part == OMAP4430_INVALID_PRCM_PARTITION || |
@@ -124,7 +121,7 @@ u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) | |||
124 | } | 121 | } |
125 | 122 | ||
126 | /* Write into a register in a CM instance */ | 123 | /* Write into a register in a CM instance */ |
127 | void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) | 124 | static void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) |
128 | { | 125 | { |
129 | BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || | 126 | BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || |
130 | part == OMAP4430_INVALID_PRCM_PARTITION || | 127 | part == OMAP4430_INVALID_PRCM_PARTITION || |
@@ -133,8 +130,8 @@ void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) | |||
133 | } | 130 | } |
134 | 131 | ||
135 | /* Read-modify-write a register in CM1. Caller must lock */ | 132 | /* Read-modify-write a register in CM1. Caller must lock */ |
136 | u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, u16 inst, | 133 | static u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, u16 inst, |
137 | s16 idx) | 134 | s16 idx) |
138 | { | 135 | { |
139 | u32 v; | 136 | u32 v; |
140 | 137 | ||
@@ -146,17 +143,18 @@ u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, u16 inst, | |||
146 | return v; | 143 | return v; |
147 | } | 144 | } |
148 | 145 | ||
149 | u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx) | 146 | static u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx) |
150 | { | 147 | { |
151 | return omap4_cminst_rmw_inst_reg_bits(bits, bits, part, inst, idx); | 148 | return omap4_cminst_rmw_inst_reg_bits(bits, bits, part, inst, idx); |
152 | } | 149 | } |
153 | 150 | ||
154 | u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx) | 151 | static u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst, |
152 | s16 idx) | ||
155 | { | 153 | { |
156 | return omap4_cminst_rmw_inst_reg_bits(bits, 0x0, part, inst, idx); | 154 | return omap4_cminst_rmw_inst_reg_bits(bits, 0x0, part, inst, idx); |
157 | } | 155 | } |
158 | 156 | ||
159 | u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask) | 157 | static u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask) |
160 | { | 158 | { |
161 | u32 v; | 159 | u32 v; |
162 | 160 | ||
@@ -200,7 +198,7 @@ static void _clktrctrl_write(u8 c, u8 part, u16 inst, u16 cdoffs) | |||
200 | * Returns true if the clockdomain referred to by (@part, @inst, @cdoffs) | 198 | * Returns true if the clockdomain referred to by (@part, @inst, @cdoffs) |
201 | * is in hardware-supervised idle mode, or 0 otherwise. | 199 | * is in hardware-supervised idle mode, or 0 otherwise. |
202 | */ | 200 | */ |
203 | bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs) | 201 | static bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs) |
204 | { | 202 | { |
205 | u32 v; | 203 | u32 v; |
206 | 204 | ||
@@ -220,7 +218,7 @@ bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs) | |||
220 | * Put a clockdomain referred to by (@part, @inst, @cdoffs) into | 218 | * Put a clockdomain referred to by (@part, @inst, @cdoffs) into |
221 | * hardware-supervised idle mode. No return value. | 219 | * hardware-supervised idle mode. No return value. |
222 | */ | 220 | */ |
223 | void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs) | 221 | static void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs) |
224 | { | 222 | { |
225 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, part, inst, cdoffs); | 223 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, part, inst, cdoffs); |
226 | } | 224 | } |
@@ -235,7 +233,7 @@ void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs) | |||
235 | * software-supervised idle mode, i.e., controlled manually by the | 233 | * software-supervised idle mode, i.e., controlled manually by the |
236 | * Linux OMAP clockdomain code. No return value. | 234 | * Linux OMAP clockdomain code. No return value. |
237 | */ | 235 | */ |
238 | void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs) | 236 | static void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs) |
239 | { | 237 | { |
240 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, part, inst, cdoffs); | 238 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, part, inst, cdoffs); |
241 | } | 239 | } |
@@ -249,7 +247,7 @@ void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs) | |||
249 | * Take a clockdomain referred to by (@part, @inst, @cdoffs) out of idle, | 247 | * Take a clockdomain referred to by (@part, @inst, @cdoffs) out of idle, |
250 | * waking it up. No return value. | 248 | * waking it up. No return value. |
251 | */ | 249 | */ |
252 | void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs) | 250 | static void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs) |
253 | { | 251 | { |
254 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, part, inst, cdoffs); | 252 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, part, inst, cdoffs); |
255 | } | 253 | } |
@@ -258,7 +256,7 @@ void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs) | |||
258 | * | 256 | * |
259 | */ | 257 | */ |
260 | 258 | ||
261 | void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs) | 259 | static void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs) |
262 | { | 260 | { |
263 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, part, inst, cdoffs); | 261 | _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, part, inst, cdoffs); |
264 | } | 262 | } |
@@ -267,23 +265,23 @@ void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs) | |||
267 | * omap4_cminst_wait_module_ready - wait for a module to be in 'func' state | 265 | * omap4_cminst_wait_module_ready - wait for a module to be in 'func' state |
268 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in | 266 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in |
269 | * @inst: CM instance register offset (*_INST macro) | 267 | * @inst: CM instance register offset (*_INST macro) |
270 | * @cdoffs: Clockdomain register offset (*_CDOFFS macro) | ||
271 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 268 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
269 | * @bit_shift: bit shift for the register, ignored for OMAP4+ | ||
272 | * | 270 | * |
273 | * Wait for the module IDLEST to be functional. If the idle state is in any | 271 | * Wait for the module IDLEST to be functional. If the idle state is in any |
274 | * the non functional state (trans, idle or disabled), module and thus the | 272 | * the non functional state (trans, idle or disabled), module and thus the |
275 | * sysconfig cannot be accessed and will probably lead to an "imprecise | 273 | * sysconfig cannot be accessed and will probably lead to an "imprecise |
276 | * external abort" | 274 | * external abort" |
277 | */ | 275 | */ |
278 | int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, | 276 | static int omap4_cminst_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs, |
279 | u16 clkctrl_offs) | 277 | u8 bit_shift) |
280 | { | 278 | { |
281 | int i = 0; | 279 | int i = 0; |
282 | 280 | ||
283 | if (!clkctrl_offs) | 281 | if (!clkctrl_offs) |
284 | return 0; | 282 | return 0; |
285 | 283 | ||
286 | omap_test_timeout(_is_module_ready(part, inst, cdoffs, clkctrl_offs), | 284 | omap_test_timeout(_is_module_ready(part, inst, clkctrl_offs), |
287 | MAX_MODULE_READY_TIME, i); | 285 | MAX_MODULE_READY_TIME, i); |
288 | 286 | ||
289 | return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; | 287 | return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; |
@@ -294,21 +292,22 @@ int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, | |||
294 | * state | 292 | * state |
295 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in | 293 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in |
296 | * @inst: CM instance register offset (*_INST macro) | 294 | * @inst: CM instance register offset (*_INST macro) |
297 | * @cdoffs: Clockdomain register offset (*_CDOFFS macro) | ||
298 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 295 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
296 | * @bit_shift: Bit shift for the register, ignored for OMAP4+ | ||
299 | * | 297 | * |
300 | * Wait for the module IDLEST to be disabled. Some PRCM transition, | 298 | * Wait for the module IDLEST to be disabled. Some PRCM transition, |
301 | * like reset assertion or parent clock de-activation must wait the | 299 | * like reset assertion or parent clock de-activation must wait the |
302 | * module to be fully disabled. | 300 | * module to be fully disabled. |
303 | */ | 301 | */ |
304 | int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) | 302 | static int omap4_cminst_wait_module_idle(u8 part, s16 inst, u16 clkctrl_offs, |
303 | u8 bit_shift) | ||
305 | { | 304 | { |
306 | int i = 0; | 305 | int i = 0; |
307 | 306 | ||
308 | if (!clkctrl_offs) | 307 | if (!clkctrl_offs) |
309 | return 0; | 308 | return 0; |
310 | 309 | ||
311 | omap_test_timeout((_clkctrl_idlest(part, inst, cdoffs, clkctrl_offs) == | 310 | omap_test_timeout((_clkctrl_idlest(part, inst, clkctrl_offs) == |
312 | CLKCTRL_IDLEST_DISABLED), | 311 | CLKCTRL_IDLEST_DISABLED), |
313 | MAX_MODULE_DISABLE_TIME, i); | 312 | MAX_MODULE_DISABLE_TIME, i); |
314 | 313 | ||
@@ -320,13 +319,12 @@ int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_off | |||
320 | * @mode: Module mode (SW or HW) | 319 | * @mode: Module mode (SW or HW) |
321 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in | 320 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in |
322 | * @inst: CM instance register offset (*_INST macro) | 321 | * @inst: CM instance register offset (*_INST macro) |
323 | * @cdoffs: Clockdomain register offset (*_CDOFFS macro) | ||
324 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 322 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
325 | * | 323 | * |
326 | * No return value. | 324 | * No return value. |
327 | */ | 325 | */ |
328 | void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, | 326 | static void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, |
329 | u16 clkctrl_offs) | 327 | u16 clkctrl_offs) |
330 | { | 328 | { |
331 | u32 v; | 329 | u32 v; |
332 | 330 | ||
@@ -340,13 +338,11 @@ void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, | |||
340 | * omap4_cminst_module_disable - Disable the module inside CLKCTRL | 338 | * omap4_cminst_module_disable - Disable the module inside CLKCTRL |
341 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in | 339 | * @part: PRCM partition ID that the CM_CLKCTRL register exists in |
342 | * @inst: CM instance register offset (*_INST macro) | 340 | * @inst: CM instance register offset (*_INST macro) |
343 | * @cdoffs: Clockdomain register offset (*_CDOFFS macro) | ||
344 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) | 341 | * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) |
345 | * | 342 | * |
346 | * No return value. | 343 | * No return value. |
347 | */ | 344 | */ |
348 | void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, | 345 | static void omap4_cminst_module_disable(u8 part, u16 inst, u16 clkctrl_offs) |
349 | u16 clkctrl_offs) | ||
350 | { | 346 | { |
351 | u32 v; | 347 | u32 v; |
352 | 348 | ||
@@ -510,3 +506,21 @@ struct clkdm_ops am43xx_clkdm_operations = { | |||
510 | .clkdm_clk_enable = omap4_clkdm_clk_enable, | 506 | .clkdm_clk_enable = omap4_clkdm_clk_enable, |
511 | .clkdm_clk_disable = omap4_clkdm_clk_disable, | 507 | .clkdm_clk_disable = omap4_clkdm_clk_disable, |
512 | }; | 508 | }; |
509 | |||
510 | static struct cm_ll_data omap4xxx_cm_ll_data = { | ||
511 | .wait_module_ready = &omap4_cminst_wait_module_ready, | ||
512 | .wait_module_idle = &omap4_cminst_wait_module_idle, | ||
513 | .module_enable = &omap4_cminst_module_enable, | ||
514 | .module_disable = &omap4_cminst_module_disable, | ||
515 | }; | ||
516 | |||
517 | int __init omap4_cm_init(void) | ||
518 | { | ||
519 | return cm_register(&omap4xxx_cm_ll_data); | ||
520 | } | ||
521 | |||
522 | static void __exit omap4_cm_exit(void) | ||
523 | { | ||
524 | cm_unregister(&omap4xxx_cm_ll_data); | ||
525 | } | ||
526 | __exitcall(omap4_cm_exit); | ||
diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h deleted file mode 100644 index 7f56ea444bc4..000000000000 --- a/arch/arm/mach-omap2/cminst44xx.h +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | /* | ||
2 | * OMAP4 Clock Management (CM) function prototypes | ||
3 | * | ||
4 | * Copyright (C) 2010 Nokia Corporation | ||
5 | * Paul Walmsley | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #ifndef __ARCH_ASM_MACH_OMAP2_CMINST44XX_H | ||
12 | #define __ARCH_ASM_MACH_OMAP2_CMINST44XX_H | ||
13 | |||
14 | bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs); | ||
15 | void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs); | ||
16 | void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs); | ||
17 | void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs); | ||
18 | void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs); | ||
19 | extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs); | ||
20 | extern int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, | ||
21 | u16 clkctrl_offs); | ||
22 | extern void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, | ||
23 | u16 clkctrl_offs); | ||
24 | extern void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, | ||
25 | u16 clkctrl_offs); | ||
26 | /* | ||
27 | * In an ideal world, we would not export these low-level functions, | ||
28 | * but this will probably take some time to fix properly | ||
29 | */ | ||
30 | u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx); | ||
31 | void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx); | ||
32 | u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, | ||
33 | u16 inst, s16 idx); | ||
34 | u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, | ||
35 | s16 idx); | ||
36 | u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst, | ||
37 | s16 idx); | ||
38 | extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, | ||
39 | u32 mask); | ||
40 | |||
41 | extern void omap_cm_base_init(void); | ||
42 | |||
43 | #endif | ||
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index ac3d789ac3cd..20e120d071dd 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c | |||
@@ -460,25 +460,24 @@ void omap3_noncore_dpll_disable(struct clk_hw *hw) | |||
460 | /* Non-CORE DPLL rate set code */ | 460 | /* Non-CORE DPLL rate set code */ |
461 | 461 | ||
462 | /** | 462 | /** |
463 | * omap3_noncore_dpll_set_rate - set non-core DPLL rate | 463 | * omap3_noncore_dpll_determine_rate - determine rate for a DPLL |
464 | * @clk: struct clk * of DPLL to set | 464 | * @hw: pointer to the clock to determine rate for |
465 | * @rate: rounded target rate | 465 | * @rate: target rate for the DPLL |
466 | * @best_parent_rate: pointer for returning best parent rate | ||
467 | * @best_parent_clk: pointer for returning best parent clock | ||
466 | * | 468 | * |
467 | * Set the DPLL CLKOUT to the target rate. If the DPLL can enter | 469 | * Determines which DPLL mode to use for reaching a desired target rate. |
468 | * low-power bypass, and the target rate is the bypass source clock | 470 | * Checks whether the DPLL shall be in bypass or locked mode, and if |
469 | * rate, then configure the DPLL for bypass. Otherwise, round the | 471 | * locked, calculates the M,N values for the DPLL via round-rate. |
470 | * target rate if it hasn't been done already, then program and lock | 472 | * Returns a positive clock rate with success, negative error value |
471 | * the DPLL. Returns -EINVAL upon error, or 0 upon success. | 473 | * in failure. |
472 | */ | 474 | */ |
473 | int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, | 475 | long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, unsigned long rate, |
474 | unsigned long parent_rate) | 476 | unsigned long *best_parent_rate, |
477 | struct clk **best_parent_clk) | ||
475 | { | 478 | { |
476 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); | 479 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); |
477 | struct clk *new_parent = NULL; | ||
478 | unsigned long rrate; | ||
479 | u16 freqsel = 0; | ||
480 | struct dpll_data *dd; | 480 | struct dpll_data *dd; |
481 | int ret; | ||
482 | 481 | ||
483 | if (!hw || !rate) | 482 | if (!hw || !rate) |
484 | return -EINVAL; | 483 | return -EINVAL; |
@@ -489,61 +488,121 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
489 | 488 | ||
490 | if (__clk_get_rate(dd->clk_bypass) == rate && | 489 | if (__clk_get_rate(dd->clk_bypass) == rate && |
491 | (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { | 490 | (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { |
492 | pr_debug("%s: %s: set rate: entering bypass.\n", | 491 | *best_parent_clk = dd->clk_bypass; |
493 | __func__, __clk_get_name(hw->clk)); | 492 | } else { |
493 | rate = omap2_dpll_round_rate(hw, rate, best_parent_rate); | ||
494 | *best_parent_clk = dd->clk_ref; | ||
495 | } | ||
496 | |||
497 | *best_parent_rate = rate; | ||
498 | |||
499 | return rate; | ||
500 | } | ||
501 | |||
502 | /** | ||
503 | * omap3_noncore_dpll_set_parent - set parent for a DPLL clock | ||
504 | * @hw: pointer to the clock to set parent for | ||
505 | * @index: parent index to select | ||
506 | * | ||
507 | * Sets parent for a DPLL clock. This sets the DPLL into bypass or | ||
508 | * locked mode. Returns 0 with success, negative error value otherwise. | ||
509 | */ | ||
510 | int omap3_noncore_dpll_set_parent(struct clk_hw *hw, u8 index) | ||
511 | { | ||
512 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); | ||
513 | int ret; | ||
494 | 514 | ||
495 | __clk_prepare(dd->clk_bypass); | 515 | if (!hw) |
496 | clk_enable(dd->clk_bypass); | 516 | return -EINVAL; |
517 | |||
518 | if (index) | ||
497 | ret = _omap3_noncore_dpll_bypass(clk); | 519 | ret = _omap3_noncore_dpll_bypass(clk); |
498 | if (!ret) | 520 | else |
499 | new_parent = dd->clk_bypass; | 521 | ret = _omap3_noncore_dpll_lock(clk); |
500 | clk_disable(dd->clk_bypass); | ||
501 | __clk_unprepare(dd->clk_bypass); | ||
502 | } else { | ||
503 | __clk_prepare(dd->clk_ref); | ||
504 | clk_enable(dd->clk_ref); | ||
505 | |||
506 | /* XXX this check is probably pointless in the CCF context */ | ||
507 | if (dd->last_rounded_rate != rate) { | ||
508 | rrate = __clk_round_rate(hw->clk, rate); | ||
509 | if (rrate != rate) { | ||
510 | pr_warn("%s: %s: final rate %lu does not match desired rate %lu\n", | ||
511 | __func__, __clk_get_name(hw->clk), | ||
512 | rrate, rate); | ||
513 | rate = rrate; | ||
514 | } | ||
515 | } | ||
516 | 522 | ||
517 | if (dd->last_rounded_rate == 0) | 523 | return ret; |
518 | return -EINVAL; | 524 | } |
519 | 525 | ||
520 | /* Freqsel is available only on OMAP343X devices */ | 526 | /** |
521 | if (ti_clk_features.flags & TI_CLK_DPLL_HAS_FREQSEL) { | 527 | * omap3_noncore_dpll_set_rate - set rate for a DPLL clock |
522 | freqsel = _omap3_dpll_compute_freqsel(clk, | 528 | * @hw: pointer to the clock to set parent for |
523 | dd->last_rounded_n); | 529 | * @rate: target rate for the clock |
524 | WARN_ON(!freqsel); | 530 | * @parent_rate: rate of the parent clock |
525 | } | 531 | * |
532 | * Sets rate for a DPLL clock. First checks if the clock parent is | ||
533 | * reference clock (in bypass mode, the rate of the clock can't be | ||
534 | * changed) and proceeds with the rate change operation. Returns 0 | ||
535 | * with success, negative error value otherwise. | ||
536 | */ | ||
537 | int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, | ||
538 | unsigned long parent_rate) | ||
539 | { | ||
540 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); | ||
541 | struct dpll_data *dd; | ||
542 | u16 freqsel = 0; | ||
543 | int ret; | ||
544 | |||
545 | if (!hw || !rate) | ||
546 | return -EINVAL; | ||
547 | |||
548 | dd = clk->dpll_data; | ||
549 | if (!dd) | ||
550 | return -EINVAL; | ||
526 | 551 | ||
527 | pr_debug("%s: %s: set rate: locking rate to %lu.\n", | 552 | if (__clk_get_parent(hw->clk) != dd->clk_ref) |
528 | __func__, __clk_get_name(hw->clk), rate); | 553 | return -EINVAL; |
554 | |||
555 | if (dd->last_rounded_rate == 0) | ||
556 | return -EINVAL; | ||
529 | 557 | ||
530 | ret = omap3_noncore_dpll_program(clk, freqsel); | 558 | /* Freqsel is available only on OMAP343X devices */ |
531 | if (!ret) | 559 | if (ti_clk_features.flags & TI_CLK_DPLL_HAS_FREQSEL) { |
532 | new_parent = dd->clk_ref; | 560 | freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n); |
533 | clk_disable(dd->clk_ref); | 561 | WARN_ON(!freqsel); |
534 | __clk_unprepare(dd->clk_ref); | ||
535 | } | 562 | } |
536 | /* | ||
537 | * FIXME - this is all wrong. common code handles reparenting and | ||
538 | * migrating prepare/enable counts. dplls should be a multiplexer | ||
539 | * clock and this should be a set_parent operation so that all of that | ||
540 | * stuff is inherited for free | ||
541 | */ | ||
542 | 563 | ||
543 | if (!ret && clk_get_parent(hw->clk) != new_parent) | 564 | pr_debug("%s: %s: set rate: locking rate to %lu.\n", __func__, |
544 | __clk_reparent(hw->clk, new_parent); | 565 | __clk_get_name(hw->clk), rate); |
545 | 566 | ||
546 | return 0; | 567 | ret = omap3_noncore_dpll_program(clk, freqsel); |
568 | |||
569 | return ret; | ||
570 | } | ||
571 | |||
572 | /** | ||
573 | * omap3_noncore_dpll_set_rate_and_parent - set rate and parent for a DPLL clock | ||
574 | * @hw: pointer to the clock to set rate and parent for | ||
575 | * @rate: target rate for the DPLL | ||
576 | * @parent_rate: clock rate of the DPLL parent | ||
577 | * @index: new parent index for the DPLL, 0 - reference, 1 - bypass | ||
578 | * | ||
579 | * Sets rate and parent for a DPLL clock. If new parent is the bypass | ||
580 | * clock, only selects the parent. Otherwise proceeds with a rate | ||
581 | * change, as this will effectively also change the parent as the | ||
582 | * DPLL is put into locked mode. Returns 0 with success, negative error | ||
583 | * value otherwise. | ||
584 | */ | ||
585 | int omap3_noncore_dpll_set_rate_and_parent(struct clk_hw *hw, | ||
586 | unsigned long rate, | ||
587 | unsigned long parent_rate, | ||
588 | u8 index) | ||
589 | { | ||
590 | int ret; | ||
591 | |||
592 | if (!hw || !rate) | ||
593 | return -EINVAL; | ||
594 | |||
595 | /* | ||
596 | * clk-ref at index[0], in which case we only need to set rate, | ||
597 | * the parent will be changed automatically with the lock sequence. | ||
598 | * With clk-bypass case we only need to change parent. | ||
599 | */ | ||
600 | if (index) | ||
601 | ret = omap3_noncore_dpll_set_parent(hw, index); | ||
602 | else | ||
603 | ret = omap3_noncore_dpll_set_rate(hw, rate, parent_rate); | ||
604 | |||
605 | return ret; | ||
547 | } | 606 | } |
548 | 607 | ||
549 | /* DPLL autoidle read/set code */ | 608 | /* DPLL autoidle read/set code */ |
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c index 4613f1e86988..535822fcf4bb 100644 --- a/arch/arm/mach-omap2/dpll44xx.c +++ b/arch/arm/mach-omap2/dpll44xx.c | |||
@@ -207,3 +207,44 @@ out: | |||
207 | 207 | ||
208 | return dd->last_rounded_rate; | 208 | return dd->last_rounded_rate; |
209 | } | 209 | } |
210 | |||
211 | /** | ||
212 | * omap4_dpll_regm4xen_determine_rate - determine rate for a DPLL | ||
213 | * @hw: pointer to the clock to determine rate for | ||
214 | * @rate: target rate for the DPLL | ||
215 | * @best_parent_rate: pointer for returning best parent rate | ||
216 | * @best_parent_clk: pointer for returning best parent clock | ||
217 | * | ||
218 | * Determines which DPLL mode to use for reaching a desired rate. | ||
219 | * Checks whether the DPLL shall be in bypass or locked mode, and if | ||
220 | * locked, calculates the M,N values for the DPLL via round-rate. | ||
221 | * Returns a positive clock rate with success, negative error value | ||
222 | * in failure. | ||
223 | */ | ||
224 | long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate, | ||
225 | unsigned long *best_parent_rate, | ||
226 | struct clk **best_parent_clk) | ||
227 | { | ||
228 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); | ||
229 | struct dpll_data *dd; | ||
230 | |||
231 | if (!hw || !rate) | ||
232 | return -EINVAL; | ||
233 | |||
234 | dd = clk->dpll_data; | ||
235 | if (!dd) | ||
236 | return -EINVAL; | ||
237 | |||
238 | if (__clk_get_rate(dd->clk_bypass) == rate && | ||
239 | (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { | ||
240 | *best_parent_clk = dd->clk_bypass; | ||
241 | } else { | ||
242 | rate = omap4_dpll_regm4xen_round_rate(hw, rate, | ||
243 | best_parent_rate); | ||
244 | *best_parent_clk = dd->clk_ref; | ||
245 | } | ||
246 | |||
247 | *best_parent_rate = rate; | ||
248 | |||
249 | return rate; | ||
250 | } | ||
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 03cbb16898a3..4fc838354e31 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
@@ -45,13 +45,15 @@ | |||
45 | #include "sram.h" | 45 | #include "sram.h" |
46 | #include "cm2xxx.h" | 46 | #include "cm2xxx.h" |
47 | #include "cm3xxx.h" | 47 | #include "cm3xxx.h" |
48 | #include "cm33xx.h" | ||
49 | #include "cm44xx.h" | ||
48 | #include "prm.h" | 50 | #include "prm.h" |
49 | #include "cm.h" | 51 | #include "cm.h" |
50 | #include "prcm_mpu44xx.h" | 52 | #include "prcm_mpu44xx.h" |
51 | #include "prminst44xx.h" | 53 | #include "prminst44xx.h" |
52 | #include "cminst44xx.h" | ||
53 | #include "prm2xxx.h" | 54 | #include "prm2xxx.h" |
54 | #include "prm3xxx.h" | 55 | #include "prm3xxx.h" |
56 | #include "prm33xx.h" | ||
55 | #include "prm44xx.h" | 57 | #include "prm44xx.h" |
56 | #include "opp2xxx.h" | 58 | #include "opp2xxx.h" |
57 | 59 | ||
@@ -565,6 +567,8 @@ void __init am33xx_init_early(void) | |||
565 | omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), NULL); | 567 | omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), NULL); |
566 | omap3xxx_check_revision(); | 568 | omap3xxx_check_revision(); |
567 | am33xx_check_features(); | 569 | am33xx_check_features(); |
570 | am33xx_prm_init(); | ||
571 | am33xx_cm_init(); | ||
568 | am33xx_powerdomains_init(); | 572 | am33xx_powerdomains_init(); |
569 | am33xx_clockdomains_init(); | 573 | am33xx_clockdomains_init(); |
570 | am33xx_hwmod_init(); | 574 | am33xx_hwmod_init(); |
@@ -591,6 +595,8 @@ void __init am43xx_init_early(void) | |||
591 | omap_cm_base_init(); | 595 | omap_cm_base_init(); |
592 | omap3xxx_check_revision(); | 596 | omap3xxx_check_revision(); |
593 | am33xx_check_features(); | 597 | am33xx_check_features(); |
598 | omap44xx_prm_init(); | ||
599 | omap4_cm_init(); | ||
594 | am43xx_powerdomains_init(); | 600 | am43xx_powerdomains_init(); |
595 | am43xx_clockdomains_init(); | 601 | am43xx_clockdomains_init(); |
596 | am43xx_hwmod_init(); | 602 | am43xx_hwmod_init(); |
@@ -620,6 +626,7 @@ void __init omap4430_init_early(void) | |||
620 | omap_cm_base_init(); | 626 | omap_cm_base_init(); |
621 | omap4xxx_check_revision(); | 627 | omap4xxx_check_revision(); |
622 | omap4xxx_check_features(); | 628 | omap4xxx_check_features(); |
629 | omap4_cm_init(); | ||
623 | omap4_pm_init_early(); | 630 | omap4_pm_init_early(); |
624 | omap44xx_prm_init(); | 631 | omap44xx_prm_init(); |
625 | omap44xx_voltagedomains_init(); | 632 | omap44xx_voltagedomains_init(); |
@@ -655,6 +662,7 @@ void __init omap5_init_early(void) | |||
655 | omap_cm_base_init(); | 662 | omap_cm_base_init(); |
656 | omap44xx_prm_init(); | 663 | omap44xx_prm_init(); |
657 | omap5xxx_check_revision(); | 664 | omap5xxx_check_revision(); |
665 | omap4_cm_init(); | ||
658 | omap54xx_voltagedomains_init(); | 666 | omap54xx_voltagedomains_init(); |
659 | omap54xx_powerdomains_init(); | 667 | omap54xx_powerdomains_init(); |
660 | omap54xx_clockdomains_init(); | 668 | omap54xx_clockdomains_init(); |
@@ -686,6 +694,7 @@ void __init dra7xx_init_early(void) | |||
686 | omap_cm_base_init(); | 694 | omap_cm_base_init(); |
687 | omap44xx_prm_init(); | 695 | omap44xx_prm_init(); |
688 | dra7xxx_check_revision(); | 696 | dra7xxx_check_revision(); |
697 | omap4_cm_init(); | ||
689 | dra7xx_powerdomains_init(); | 698 | dra7xx_powerdomains_init(); |
690 | dra7xx_clockdomains_init(); | 699 | dra7xx_clockdomains_init(); |
691 | dra7xx_hwmod_init(); | 700 | dra7xx_hwmod_init(); |
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 6944ae3674e8..79f49d904a06 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c | |||
@@ -227,7 +227,7 @@ static void __init save_l2x0_context(void) | |||
227 | int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) | 227 | int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) |
228 | { | 228 | { |
229 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); | 229 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); |
230 | unsigned int save_state = 0; | 230 | unsigned int save_state = 0, cpu_logic_state = PWRDM_POWER_RET; |
231 | unsigned int wakeup_cpu; | 231 | unsigned int wakeup_cpu; |
232 | 232 | ||
233 | if (omap_rev() == OMAP4430_REV_ES1_0) | 233 | if (omap_rev() == OMAP4430_REV_ES1_0) |
@@ -239,6 +239,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) | |||
239 | save_state = 0; | 239 | save_state = 0; |
240 | break; | 240 | break; |
241 | case PWRDM_POWER_OFF: | 241 | case PWRDM_POWER_OFF: |
242 | cpu_logic_state = PWRDM_POWER_OFF; | ||
242 | save_state = 1; | 243 | save_state = 1; |
243 | break; | 244 | break; |
244 | case PWRDM_POWER_RET: | 245 | case PWRDM_POWER_RET: |
@@ -270,6 +271,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) | |||
270 | 271 | ||
271 | cpu_clear_prev_logic_pwrst(cpu); | 272 | cpu_clear_prev_logic_pwrst(cpu); |
272 | pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); | 273 | pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); |
274 | pwrdm_set_logic_retst(pm_info->pwrdm, cpu_logic_state); | ||
273 | set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume)); | 275 | set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume)); |
274 | omap_pm_ops.scu_prepare(cpu, power_state); | 276 | omap_pm_ops.scu_prepare(cpu, power_state); |
275 | l2x0_pwrst_prepare(cpu, save_state); | 277 | l2x0_pwrst_prepare(cpu, save_state); |
diff --git a/arch/arm/mach-omap2/omap2-restart.c b/arch/arm/mach-omap2/omap2-restart.c index 68423e26399d..d937b2e4040b 100644 --- a/arch/arm/mach-omap2/omap2-restart.c +++ b/arch/arm/mach-omap2/omap2-restart.c | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | #include "soc.h" | 16 | #include "soc.h" |
17 | #include "common.h" | 17 | #include "common.h" |
18 | #include "prm2xxx.h" | 18 | #include "prm.h" |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * reset_virt_prcm_set_ck, reset_sys_ck: pointers to the virt_prcm_set | 21 | * reset_virt_prcm_set_ck, reset_sys_ck: pointers to the virt_prcm_set |
@@ -40,8 +40,7 @@ void omap2xxx_restart(enum reboot_mode mode, const char *cmd) | |||
40 | 40 | ||
41 | /* XXX Should save the cmd argument for use after the reboot */ | 41 | /* XXX Should save the cmd argument for use after the reboot */ |
42 | 42 | ||
43 | omap2xxx_prm_dpll_reset(); /* never returns */ | 43 | omap_prm_reset_system(); |
44 | while (1); | ||
45 | } | 44 | } |
46 | 45 | ||
47 | /** | 46 | /** |
diff --git a/arch/arm/mach-omap2/omap3-restart.c b/arch/arm/mach-omap2/omap3-restart.c index 5de2a0c2979d..103a49f68bcb 100644 --- a/arch/arm/mach-omap2/omap3-restart.c +++ b/arch/arm/mach-omap2/omap3-restart.c | |||
@@ -14,10 +14,8 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/reboot.h> | 15 | #include <linux/reboot.h> |
16 | 16 | ||
17 | #include "iomap.h" | ||
18 | #include "common.h" | ||
19 | #include "control.h" | 17 | #include "control.h" |
20 | #include "prm3xxx.h" | 18 | #include "prm.h" |
21 | 19 | ||
22 | /* Global address base setup code */ | 20 | /* Global address base setup code */ |
23 | 21 | ||
@@ -32,6 +30,5 @@ | |||
32 | void omap3xxx_restart(enum reboot_mode mode, const char *cmd) | 30 | void omap3xxx_restart(enum reboot_mode mode, const char *cmd) |
33 | { | 31 | { |
34 | omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0)); | 32 | omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0)); |
35 | omap3xxx_prm_dpll3_reset(); /* never returns */ | 33 | omap_prm_reset_system(); |
36 | while (1); | ||
37 | } | 34 | } |
diff --git a/arch/arm/mach-omap2/omap4-restart.c b/arch/arm/mach-omap2/omap4-restart.c index 41dfd7da8170..a99e7f7fb5be 100644 --- a/arch/arm/mach-omap2/omap4-restart.c +++ b/arch/arm/mach-omap2/omap4-restart.c | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/reboot.h> | 11 | #include <linux/reboot.h> |
12 | #include "prminst44xx.h" | 12 | #include "prm.h" |
13 | 13 | ||
14 | /** | 14 | /** |
15 | * omap44xx_restart - trigger a software restart of the SoC | 15 | * omap44xx_restart - trigger a software restart of the SoC |
@@ -22,7 +22,5 @@ | |||
22 | void omap44xx_restart(enum reboot_mode mode, const char *cmd) | 22 | void omap44xx_restart(enum reboot_mode mode, const char *cmd) |
23 | { | 23 | { |
24 | /* XXX Should save 'cmd' into scratchpad for use after reboot */ | 24 | /* XXX Should save 'cmd' into scratchpad for use after reboot */ |
25 | omap4_prminst_global_warm_sw_reset(); /* never returns */ | 25 | omap_prm_reset_system(); |
26 | while (1) | ||
27 | ; | ||
28 | } | 26 | } |
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 716247ed9e0c..cbb908dc5cf0 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -153,7 +153,6 @@ | |||
153 | #include "powerdomain.h" | 153 | #include "powerdomain.h" |
154 | #include "cm2xxx.h" | 154 | #include "cm2xxx.h" |
155 | #include "cm3xxx.h" | 155 | #include "cm3xxx.h" |
156 | #include "cminst44xx.h" | ||
157 | #include "cm33xx.h" | 156 | #include "cm33xx.h" |
158 | #include "prm.h" | 157 | #include "prm.h" |
159 | #include "prm3xxx.h" | 158 | #include "prm3xxx.h" |
@@ -979,31 +978,9 @@ static void _omap4_enable_module(struct omap_hwmod *oh) | |||
979 | pr_debug("omap_hwmod: %s: %s: %d\n", | 978 | pr_debug("omap_hwmod: %s: %s: %d\n", |
980 | oh->name, __func__, oh->prcm.omap4.modulemode); | 979 | oh->name, __func__, oh->prcm.omap4.modulemode); |
981 | 980 | ||
982 | omap4_cminst_module_enable(oh->prcm.omap4.modulemode, | 981 | omap_cm_module_enable(oh->prcm.omap4.modulemode, |
983 | oh->clkdm->prcm_partition, | 982 | oh->clkdm->prcm_partition, |
984 | oh->clkdm->cm_inst, | 983 | oh->clkdm->cm_inst, oh->prcm.omap4.clkctrl_offs); |
985 | oh->clkdm->clkdm_offs, | ||
986 | oh->prcm.omap4.clkctrl_offs); | ||
987 | } | ||
988 | |||
989 | /** | ||
990 | * _am33xx_enable_module - enable CLKCTRL modulemode on AM33XX | ||
991 | * @oh: struct omap_hwmod * | ||
992 | * | ||
993 | * Enables the PRCM module mode related to the hwmod @oh. | ||
994 | * No return value. | ||
995 | */ | ||
996 | static void _am33xx_enable_module(struct omap_hwmod *oh) | ||
997 | { | ||
998 | if (!oh->clkdm || !oh->prcm.omap4.modulemode) | ||
999 | return; | ||
1000 | |||
1001 | pr_debug("omap_hwmod: %s: %s: %d\n", | ||
1002 | oh->name, __func__, oh->prcm.omap4.modulemode); | ||
1003 | |||
1004 | am33xx_cm_module_enable(oh->prcm.omap4.modulemode, oh->clkdm->cm_inst, | ||
1005 | oh->clkdm->clkdm_offs, | ||
1006 | oh->prcm.omap4.clkctrl_offs); | ||
1007 | } | 984 | } |
1008 | 985 | ||
1009 | /** | 986 | /** |
@@ -1026,35 +1003,9 @@ static int _omap4_wait_target_disable(struct omap_hwmod *oh) | |||
1026 | if (oh->flags & HWMOD_NO_IDLEST) | 1003 | if (oh->flags & HWMOD_NO_IDLEST) |
1027 | return 0; | 1004 | return 0; |
1028 | 1005 | ||
1029 | return omap4_cminst_wait_module_idle(oh->clkdm->prcm_partition, | 1006 | return omap_cm_wait_module_idle(oh->clkdm->prcm_partition, |
1030 | oh->clkdm->cm_inst, | 1007 | oh->clkdm->cm_inst, |
1031 | oh->clkdm->clkdm_offs, | 1008 | oh->prcm.omap4.clkctrl_offs, 0); |
1032 | oh->prcm.omap4.clkctrl_offs); | ||
1033 | } | ||
1034 | |||
1035 | /** | ||
1036 | * _am33xx_wait_target_disable - wait for a module to be disabled on AM33XX | ||
1037 | * @oh: struct omap_hwmod * | ||
1038 | * | ||
1039 | * Wait for a module @oh to enter slave idle. Returns 0 if the module | ||
1040 | * does not have an IDLEST bit or if the module successfully enters | ||
1041 | * slave idle; otherwise, pass along the return value of the | ||
1042 | * appropriate *_cm*_wait_module_idle() function. | ||
1043 | */ | ||
1044 | static int _am33xx_wait_target_disable(struct omap_hwmod *oh) | ||
1045 | { | ||
1046 | if (!oh) | ||
1047 | return -EINVAL; | ||
1048 | |||
1049 | if (oh->_int_flags & _HWMOD_NO_MPU_PORT) | ||
1050 | return 0; | ||
1051 | |||
1052 | if (oh->flags & HWMOD_NO_IDLEST) | ||
1053 | return 0; | ||
1054 | |||
1055 | return am33xx_cm_wait_module_idle(oh->clkdm->cm_inst, | ||
1056 | oh->clkdm->clkdm_offs, | ||
1057 | oh->prcm.omap4.clkctrl_offs); | ||
1058 | } | 1009 | } |
1059 | 1010 | ||
1060 | /** | 1011 | /** |
@@ -1859,10 +1810,8 @@ static int _omap4_disable_module(struct omap_hwmod *oh) | |||
1859 | 1810 | ||
1860 | pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); | 1811 | pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); |
1861 | 1812 | ||
1862 | omap4_cminst_module_disable(oh->clkdm->prcm_partition, | 1813 | omap_cm_module_disable(oh->clkdm->prcm_partition, oh->clkdm->cm_inst, |
1863 | oh->clkdm->cm_inst, | 1814 | oh->prcm.omap4.clkctrl_offs); |
1864 | oh->clkdm->clkdm_offs, | ||
1865 | oh->prcm.omap4.clkctrl_offs); | ||
1866 | 1815 | ||
1867 | v = _omap4_wait_target_disable(oh); | 1816 | v = _omap4_wait_target_disable(oh); |
1868 | if (v) | 1817 | if (v) |
@@ -1873,36 +1822,6 @@ static int _omap4_disable_module(struct omap_hwmod *oh) | |||
1873 | } | 1822 | } |
1874 | 1823 | ||
1875 | /** | 1824 | /** |
1876 | * _am33xx_disable_module - enable CLKCTRL modulemode on AM33XX | ||
1877 | * @oh: struct omap_hwmod * | ||
1878 | * | ||
1879 | * Disable the PRCM module mode related to the hwmod @oh. | ||
1880 | * Return EINVAL if the modulemode is not supported and 0 in case of success. | ||
1881 | */ | ||
1882 | static int _am33xx_disable_module(struct omap_hwmod *oh) | ||
1883 | { | ||
1884 | int v; | ||
1885 | |||
1886 | if (!oh->clkdm || !oh->prcm.omap4.modulemode) | ||
1887 | return -EINVAL; | ||
1888 | |||
1889 | pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); | ||
1890 | |||
1891 | if (_are_any_hardreset_lines_asserted(oh)) | ||
1892 | return 0; | ||
1893 | |||
1894 | am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, | ||
1895 | oh->prcm.omap4.clkctrl_offs); | ||
1896 | |||
1897 | v = _am33xx_wait_target_disable(oh); | ||
1898 | if (v) | ||
1899 | pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", | ||
1900 | oh->name); | ||
1901 | |||
1902 | return 0; | ||
1903 | } | ||
1904 | |||
1905 | /** | ||
1906 | * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit | 1825 | * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit |
1907 | * @oh: struct omap_hwmod * | 1826 | * @oh: struct omap_hwmod * |
1908 | * | 1827 | * |
@@ -2065,10 +1984,7 @@ static void _reconfigure_io_chain(void) | |||
2065 | 1984 | ||
2066 | spin_lock_irqsave(&io_chain_lock, flags); | 1985 | spin_lock_irqsave(&io_chain_lock, flags); |
2067 | 1986 | ||
2068 | if (cpu_is_omap34xx()) | 1987 | omap_prm_reconfigure_io_chain(); |
2069 | omap3xxx_prm_reconfigure_io_chain(); | ||
2070 | else if (cpu_is_omap44xx()) | ||
2071 | omap44xx_prm_reconfigure_io_chain(); | ||
2072 | 1988 | ||
2073 | spin_unlock_irqrestore(&io_chain_lock, flags); | 1989 | spin_unlock_irqrestore(&io_chain_lock, flags); |
2074 | } | 1990 | } |
@@ -2719,11 +2635,33 @@ static int __init _setup(struct omap_hwmod *oh, void *data) | |||
2719 | if (oh->_state != _HWMOD_STATE_INITIALIZED) | 2635 | if (oh->_state != _HWMOD_STATE_INITIALIZED) |
2720 | return 0; | 2636 | return 0; |
2721 | 2637 | ||
2638 | if (oh->parent_hwmod) { | ||
2639 | int r; | ||
2640 | |||
2641 | r = _enable(oh->parent_hwmod); | ||
2642 | WARN(r, "hwmod: %s: setup: failed to enable parent hwmod %s\n", | ||
2643 | oh->name, oh->parent_hwmod->name); | ||
2644 | } | ||
2645 | |||
2722 | _setup_iclk_autoidle(oh); | 2646 | _setup_iclk_autoidle(oh); |
2723 | 2647 | ||
2724 | if (!_setup_reset(oh)) | 2648 | if (!_setup_reset(oh)) |
2725 | _setup_postsetup(oh); | 2649 | _setup_postsetup(oh); |
2726 | 2650 | ||
2651 | if (oh->parent_hwmod) { | ||
2652 | u8 postsetup_state; | ||
2653 | |||
2654 | postsetup_state = oh->parent_hwmod->_postsetup_state; | ||
2655 | |||
2656 | if (postsetup_state == _HWMOD_STATE_IDLE) | ||
2657 | _idle(oh->parent_hwmod); | ||
2658 | else if (postsetup_state == _HWMOD_STATE_DISABLED) | ||
2659 | _shutdown(oh->parent_hwmod); | ||
2660 | else if (postsetup_state != _HWMOD_STATE_ENABLED) | ||
2661 | WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n", | ||
2662 | oh->parent_hwmod->name, postsetup_state); | ||
2663 | } | ||
2664 | |||
2727 | return 0; | 2665 | return 0; |
2728 | } | 2666 | } |
2729 | 2667 | ||
@@ -2832,12 +2770,10 @@ static int __init _add_link(struct omap_hwmod_ocp_if *oi) | |||
2832 | _alloc_links(&ml, &sl); | 2770 | _alloc_links(&ml, &sl); |
2833 | 2771 | ||
2834 | ml->ocp_if = oi; | 2772 | ml->ocp_if = oi; |
2835 | INIT_LIST_HEAD(&ml->node); | ||
2836 | list_add(&ml->node, &oi->master->master_ports); | 2773 | list_add(&ml->node, &oi->master->master_ports); |
2837 | oi->master->masters_cnt++; | 2774 | oi->master->masters_cnt++; |
2838 | 2775 | ||
2839 | sl->ocp_if = oi; | 2776 | sl->ocp_if = oi; |
2840 | INIT_LIST_HEAD(&sl->node); | ||
2841 | list_add(&sl->node, &oi->slave->slave_ports); | 2777 | list_add(&sl->node, &oi->slave->slave_ports); |
2842 | oi->slave->slaves_cnt++; | 2778 | oi->slave->slaves_cnt++; |
2843 | 2779 | ||
@@ -2927,34 +2863,7 @@ static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois) | |||
2927 | /* Static functions intended only for use in soc_ops field function pointers */ | 2863 | /* Static functions intended only for use in soc_ops field function pointers */ |
2928 | 2864 | ||
2929 | /** | 2865 | /** |
2930 | * _omap2xxx_wait_target_ready - wait for a module to leave slave idle | 2866 | * _omap2xxx_3xxx_wait_target_ready - wait for a module to leave slave idle |
2931 | * @oh: struct omap_hwmod * | ||
2932 | * | ||
2933 | * Wait for a module @oh to leave slave idle. Returns 0 if the module | ||
2934 | * does not have an IDLEST bit or if the module successfully leaves | ||
2935 | * slave idle; otherwise, pass along the return value of the | ||
2936 | * appropriate *_cm*_wait_module_ready() function. | ||
2937 | */ | ||
2938 | static int _omap2xxx_wait_target_ready(struct omap_hwmod *oh) | ||
2939 | { | ||
2940 | if (!oh) | ||
2941 | return -EINVAL; | ||
2942 | |||
2943 | if (oh->flags & HWMOD_NO_IDLEST) | ||
2944 | return 0; | ||
2945 | |||
2946 | if (!_find_mpu_rt_port(oh)) | ||
2947 | return 0; | ||
2948 | |||
2949 | /* XXX check module SIDLEMODE, hardreset status, enabled clocks */ | ||
2950 | |||
2951 | return omap2xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs, | ||
2952 | oh->prcm.omap2.idlest_reg_id, | ||
2953 | oh->prcm.omap2.idlest_idle_bit); | ||
2954 | } | ||
2955 | |||
2956 | /** | ||
2957 | * _omap3xxx_wait_target_ready - wait for a module to leave slave idle | ||
2958 | * @oh: struct omap_hwmod * | 2867 | * @oh: struct omap_hwmod * |
2959 | * | 2868 | * |
2960 | * Wait for a module @oh to leave slave idle. Returns 0 if the module | 2869 | * Wait for a module @oh to leave slave idle. Returns 0 if the module |
@@ -2962,7 +2871,7 @@ static int _omap2xxx_wait_target_ready(struct omap_hwmod *oh) | |||
2962 | * slave idle; otherwise, pass along the return value of the | 2871 | * slave idle; otherwise, pass along the return value of the |
2963 | * appropriate *_cm*_wait_module_ready() function. | 2872 | * appropriate *_cm*_wait_module_ready() function. |
2964 | */ | 2873 | */ |
2965 | static int _omap3xxx_wait_target_ready(struct omap_hwmod *oh) | 2874 | static int _omap2xxx_3xxx_wait_target_ready(struct omap_hwmod *oh) |
2966 | { | 2875 | { |
2967 | if (!oh) | 2876 | if (!oh) |
2968 | return -EINVAL; | 2877 | return -EINVAL; |
@@ -2975,9 +2884,9 @@ static int _omap3xxx_wait_target_ready(struct omap_hwmod *oh) | |||
2975 | 2884 | ||
2976 | /* XXX check module SIDLEMODE, hardreset status, enabled clocks */ | 2885 | /* XXX check module SIDLEMODE, hardreset status, enabled clocks */ |
2977 | 2886 | ||
2978 | return omap3xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs, | 2887 | return omap_cm_wait_module_ready(0, oh->prcm.omap2.module_offs, |
2979 | oh->prcm.omap2.idlest_reg_id, | 2888 | oh->prcm.omap2.idlest_reg_id, |
2980 | oh->prcm.omap2.idlest_idle_bit); | 2889 | oh->prcm.omap2.idlest_idle_bit); |
2981 | } | 2890 | } |
2982 | 2891 | ||
2983 | /** | 2892 | /** |
@@ -3002,37 +2911,9 @@ static int _omap4_wait_target_ready(struct omap_hwmod *oh) | |||
3002 | 2911 | ||
3003 | /* XXX check module SIDLEMODE, hardreset status */ | 2912 | /* XXX check module SIDLEMODE, hardreset status */ |
3004 | 2913 | ||
3005 | return omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition, | 2914 | return omap_cm_wait_module_ready(oh->clkdm->prcm_partition, |
3006 | oh->clkdm->cm_inst, | 2915 | oh->clkdm->cm_inst, |
3007 | oh->clkdm->clkdm_offs, | 2916 | oh->prcm.omap4.clkctrl_offs, 0); |
3008 | oh->prcm.omap4.clkctrl_offs); | ||
3009 | } | ||
3010 | |||
3011 | /** | ||
3012 | * _am33xx_wait_target_ready - wait for a module to leave slave idle | ||
3013 | * @oh: struct omap_hwmod * | ||
3014 | * | ||
3015 | * Wait for a module @oh to leave slave idle. Returns 0 if the module | ||
3016 | * does not have an IDLEST bit or if the module successfully leaves | ||
3017 | * slave idle; otherwise, pass along the return value of the | ||
3018 | * appropriate *_cm*_wait_module_ready() function. | ||
3019 | */ | ||
3020 | static int _am33xx_wait_target_ready(struct omap_hwmod *oh) | ||
3021 | { | ||
3022 | if (!oh || !oh->clkdm) | ||
3023 | return -EINVAL; | ||
3024 | |||
3025 | if (oh->flags & HWMOD_NO_IDLEST) | ||
3026 | return 0; | ||
3027 | |||
3028 | if (!_find_mpu_rt_port(oh)) | ||
3029 | return 0; | ||
3030 | |||
3031 | /* XXX check module SIDLEMODE, hardreset status */ | ||
3032 | |||
3033 | return am33xx_cm_wait_module_ready(oh->clkdm->cm_inst, | ||
3034 | oh->clkdm->clkdm_offs, | ||
3035 | oh->prcm.omap4.clkctrl_offs); | ||
3036 | } | 2917 | } |
3037 | 2918 | ||
3038 | /** | 2919 | /** |
@@ -3049,8 +2930,8 @@ static int _am33xx_wait_target_ready(struct omap_hwmod *oh) | |||
3049 | static int _omap2_assert_hardreset(struct omap_hwmod *oh, | 2930 | static int _omap2_assert_hardreset(struct omap_hwmod *oh, |
3050 | struct omap_hwmod_rst_info *ohri) | 2931 | struct omap_hwmod_rst_info *ohri) |
3051 | { | 2932 | { |
3052 | return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs, | 2933 | return omap_prm_assert_hardreset(ohri->rst_shift, 0, |
3053 | ohri->rst_shift); | 2934 | oh->prcm.omap2.module_offs, 0); |
3054 | } | 2935 | } |
3055 | 2936 | ||
3056 | /** | 2937 | /** |
@@ -3067,9 +2948,8 @@ static int _omap2_assert_hardreset(struct omap_hwmod *oh, | |||
3067 | static int _omap2_deassert_hardreset(struct omap_hwmod *oh, | 2948 | static int _omap2_deassert_hardreset(struct omap_hwmod *oh, |
3068 | struct omap_hwmod_rst_info *ohri) | 2949 | struct omap_hwmod_rst_info *ohri) |
3069 | { | 2950 | { |
3070 | return omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs, | 2951 | return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0, |
3071 | ohri->rst_shift, | 2952 | oh->prcm.omap2.module_offs, 0, 0); |
3072 | ohri->st_shift); | ||
3073 | } | 2953 | } |
3074 | 2954 | ||
3075 | /** | 2955 | /** |
@@ -3087,8 +2967,8 @@ static int _omap2_deassert_hardreset(struct omap_hwmod *oh, | |||
3087 | static int _omap2_is_hardreset_asserted(struct omap_hwmod *oh, | 2967 | static int _omap2_is_hardreset_asserted(struct omap_hwmod *oh, |
3088 | struct omap_hwmod_rst_info *ohri) | 2968 | struct omap_hwmod_rst_info *ohri) |
3089 | { | 2969 | { |
3090 | return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs, | 2970 | return omap_prm_is_hardreset_asserted(ohri->st_shift, 0, |
3091 | ohri->st_shift); | 2971 | oh->prcm.omap2.module_offs, 0); |
3092 | } | 2972 | } |
3093 | 2973 | ||
3094 | /** | 2974 | /** |
@@ -3109,10 +2989,10 @@ static int _omap4_assert_hardreset(struct omap_hwmod *oh, | |||
3109 | if (!oh->clkdm) | 2989 | if (!oh->clkdm) |
3110 | return -EINVAL; | 2990 | return -EINVAL; |
3111 | 2991 | ||
3112 | return omap4_prminst_assert_hardreset(ohri->rst_shift, | 2992 | return omap_prm_assert_hardreset(ohri->rst_shift, |
3113 | oh->clkdm->pwrdm.ptr->prcm_partition, | 2993 | oh->clkdm->pwrdm.ptr->prcm_partition, |
3114 | oh->clkdm->pwrdm.ptr->prcm_offs, | 2994 | oh->clkdm->pwrdm.ptr->prcm_offs, |
3115 | oh->prcm.omap4.rstctrl_offs); | 2995 | oh->prcm.omap4.rstctrl_offs); |
3116 | } | 2996 | } |
3117 | 2997 | ||
3118 | /** | 2998 | /** |
@@ -3136,10 +3016,10 @@ static int _omap4_deassert_hardreset(struct omap_hwmod *oh, | |||
3136 | if (ohri->st_shift) | 3016 | if (ohri->st_shift) |
3137 | pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", | 3017 | pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", |
3138 | oh->name, ohri->name); | 3018 | oh->name, ohri->name); |
3139 | return omap4_prminst_deassert_hardreset(ohri->rst_shift, | 3019 | return omap_prm_deassert_hardreset(ohri->rst_shift, 0, |
3140 | oh->clkdm->pwrdm.ptr->prcm_partition, | 3020 | oh->clkdm->pwrdm.ptr->prcm_partition, |
3141 | oh->clkdm->pwrdm.ptr->prcm_offs, | 3021 | oh->clkdm->pwrdm.ptr->prcm_offs, |
3142 | oh->prcm.omap4.rstctrl_offs); | 3022 | oh->prcm.omap4.rstctrl_offs, 0); |
3143 | } | 3023 | } |
3144 | 3024 | ||
3145 | /** | 3025 | /** |
@@ -3160,10 +3040,11 @@ static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh, | |||
3160 | if (!oh->clkdm) | 3040 | if (!oh->clkdm) |
3161 | return -EINVAL; | 3041 | return -EINVAL; |
3162 | 3042 | ||
3163 | return omap4_prminst_is_hardreset_asserted(ohri->rst_shift, | 3043 | return omap_prm_is_hardreset_asserted(ohri->rst_shift, |
3164 | oh->clkdm->pwrdm.ptr->prcm_partition, | 3044 | oh->clkdm->pwrdm.ptr-> |
3165 | oh->clkdm->pwrdm.ptr->prcm_offs, | 3045 | prcm_partition, |
3166 | oh->prcm.omap4.rstctrl_offs); | 3046 | oh->clkdm->pwrdm.ptr->prcm_offs, |
3047 | oh->prcm.omap4.rstctrl_offs); | ||
3167 | } | 3048 | } |
3168 | 3049 | ||
3169 | /** | 3050 | /** |
@@ -3182,9 +3063,9 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh, | |||
3182 | struct omap_hwmod_rst_info *ohri) | 3063 | struct omap_hwmod_rst_info *ohri) |
3183 | 3064 | ||
3184 | { | 3065 | { |
3185 | return am33xx_prm_assert_hardreset(ohri->rst_shift, | 3066 | return omap_prm_assert_hardreset(ohri->rst_shift, 0, |
3186 | oh->clkdm->pwrdm.ptr->prcm_offs, | 3067 | oh->clkdm->pwrdm.ptr->prcm_offs, |
3187 | oh->prcm.omap4.rstctrl_offs); | 3068 | oh->prcm.omap4.rstctrl_offs); |
3188 | } | 3069 | } |
3189 | 3070 | ||
3190 | /** | 3071 | /** |
@@ -3202,11 +3083,10 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh, | |||
3202 | static int _am33xx_deassert_hardreset(struct omap_hwmod *oh, | 3083 | static int _am33xx_deassert_hardreset(struct omap_hwmod *oh, |
3203 | struct omap_hwmod_rst_info *ohri) | 3084 | struct omap_hwmod_rst_info *ohri) |
3204 | { | 3085 | { |
3205 | return am33xx_prm_deassert_hardreset(ohri->rst_shift, | 3086 | return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0, |
3206 | ohri->st_shift, | 3087 | oh->clkdm->pwrdm.ptr->prcm_offs, |
3207 | oh->clkdm->pwrdm.ptr->prcm_offs, | 3088 | oh->prcm.omap4.rstctrl_offs, |
3208 | oh->prcm.omap4.rstctrl_offs, | 3089 | oh->prcm.omap4.rstst_offs); |
3209 | oh->prcm.omap4.rstst_offs); | ||
3210 | } | 3090 | } |
3211 | 3091 | ||
3212 | /** | 3092 | /** |
@@ -3224,9 +3104,9 @@ static int _am33xx_deassert_hardreset(struct omap_hwmod *oh, | |||
3224 | static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh, | 3104 | static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh, |
3225 | struct omap_hwmod_rst_info *ohri) | 3105 | struct omap_hwmod_rst_info *ohri) |
3226 | { | 3106 | { |
3227 | return am33xx_prm_is_hardreset_asserted(ohri->rst_shift, | 3107 | return omap_prm_is_hardreset_asserted(ohri->rst_shift, 0, |
3228 | oh->clkdm->pwrdm.ptr->prcm_offs, | 3108 | oh->clkdm->pwrdm.ptr->prcm_offs, |
3229 | oh->prcm.omap4.rstctrl_offs); | 3109 | oh->prcm.omap4.rstctrl_offs); |
3230 | } | 3110 | } |
3231 | 3111 | ||
3232 | /* Public functions */ | 3112 | /* Public functions */ |
@@ -4234,12 +4114,12 @@ int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx) | |||
4234 | void __init omap_hwmod_init(void) | 4114 | void __init omap_hwmod_init(void) |
4235 | { | 4115 | { |
4236 | if (cpu_is_omap24xx()) { | 4116 | if (cpu_is_omap24xx()) { |
4237 | soc_ops.wait_target_ready = _omap2xxx_wait_target_ready; | 4117 | soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready; |
4238 | soc_ops.assert_hardreset = _omap2_assert_hardreset; | 4118 | soc_ops.assert_hardreset = _omap2_assert_hardreset; |
4239 | soc_ops.deassert_hardreset = _omap2_deassert_hardreset; | 4119 | soc_ops.deassert_hardreset = _omap2_deassert_hardreset; |
4240 | soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; | 4120 | soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; |
4241 | } else if (cpu_is_omap34xx()) { | 4121 | } else if (cpu_is_omap34xx()) { |
4242 | soc_ops.wait_target_ready = _omap3xxx_wait_target_ready; | 4122 | soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready; |
4243 | soc_ops.assert_hardreset = _omap2_assert_hardreset; | 4123 | soc_ops.assert_hardreset = _omap2_assert_hardreset; |
4244 | soc_ops.deassert_hardreset = _omap2_deassert_hardreset; | 4124 | soc_ops.deassert_hardreset = _omap2_deassert_hardreset; |
4245 | soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; | 4125 | soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; |
@@ -4258,14 +4138,14 @@ void __init omap_hwmod_init(void) | |||
4258 | soc_ops.enable_module = _omap4_enable_module; | 4138 | soc_ops.enable_module = _omap4_enable_module; |
4259 | soc_ops.disable_module = _omap4_disable_module; | 4139 | soc_ops.disable_module = _omap4_disable_module; |
4260 | soc_ops.wait_target_ready = _omap4_wait_target_ready; | 4140 | soc_ops.wait_target_ready = _omap4_wait_target_ready; |
4261 | soc_ops.assert_hardreset = _am33xx_assert_hardreset; | 4141 | soc_ops.assert_hardreset = _omap4_assert_hardreset; |
4262 | soc_ops.deassert_hardreset = _am33xx_deassert_hardreset; | 4142 | soc_ops.deassert_hardreset = _omap4_deassert_hardreset; |
4263 | soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted; | 4143 | soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; |
4264 | soc_ops.init_clkdm = _init_clkdm; | 4144 | soc_ops.init_clkdm = _init_clkdm; |
4265 | } else if (soc_is_am33xx()) { | 4145 | } else if (soc_is_am33xx()) { |
4266 | soc_ops.enable_module = _am33xx_enable_module; | 4146 | soc_ops.enable_module = _omap4_enable_module; |
4267 | soc_ops.disable_module = _am33xx_disable_module; | 4147 | soc_ops.disable_module = _omap4_disable_module; |
4268 | soc_ops.wait_target_ready = _am33xx_wait_target_ready; | 4148 | soc_ops.wait_target_ready = _omap4_wait_target_ready; |
4269 | soc_ops.assert_hardreset = _am33xx_assert_hardreset; | 4149 | soc_ops.assert_hardreset = _am33xx_assert_hardreset; |
4270 | soc_ops.deassert_hardreset = _am33xx_deassert_hardreset; | 4150 | soc_ops.deassert_hardreset = _am33xx_deassert_hardreset; |
4271 | soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted; | 4151 | soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted; |
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 512f809a3f4d..35ca6efbec31 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h | |||
@@ -633,6 +633,7 @@ struct omap_hwmod_link { | |||
633 | * @flags: hwmod flags (documented below) | 633 | * @flags: hwmod flags (documented below) |
634 | * @_lock: spinlock serializing operations on this hwmod | 634 | * @_lock: spinlock serializing operations on this hwmod |
635 | * @node: list node for hwmod list (internal use) | 635 | * @node: list node for hwmod list (internal use) |
636 | * @parent_hwmod: (temporary) a pointer to the hierarchical parent of this hwmod | ||
636 | * | 637 | * |
637 | * @main_clk refers to this module's "main clock," which for our | 638 | * @main_clk refers to this module's "main clock," which for our |
638 | * purposes is defined as "the functional clock needed for register | 639 | * purposes is defined as "the functional clock needed for register |
@@ -643,6 +644,12 @@ struct omap_hwmod_link { | |||
643 | * the omap_hwmod code and should not be set during initialization. | 644 | * the omap_hwmod code and should not be set during initialization. |
644 | * | 645 | * |
645 | * @masters and @slaves are now deprecated. | 646 | * @masters and @slaves are now deprecated. |
647 | * | ||
648 | * @parent_hwmod is temporary; there should be no need for it, as this | ||
649 | * information should already be expressed in the OCP interface | ||
650 | * structures. @parent_hwmod is present as a workaround until we improve | ||
651 | * handling for hwmods with multiple parents (e.g., OMAP4+ DSS with | ||
652 | * multiple register targets across different interconnects). | ||
646 | */ | 653 | */ |
647 | struct omap_hwmod { | 654 | struct omap_hwmod { |
648 | const char *name; | 655 | const char *name; |
@@ -680,6 +687,7 @@ struct omap_hwmod { | |||
680 | u8 _int_flags; | 687 | u8 _int_flags; |
681 | u8 _state; | 688 | u8 _state; |
682 | u8 _postsetup_state; | 689 | u8 _postsetup_state; |
690 | struct omap_hwmod *parent_hwmod; | ||
683 | }; | 691 | }; |
684 | 692 | ||
685 | struct omap_hwmod *omap_hwmod_lookup(const char *name); | 693 | struct omap_hwmod *omap_hwmod_lookup(const char *name); |
diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c index fea01aa3ef42..5c6c8410160e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c | |||
@@ -417,6 +417,37 @@ static struct omap_hwmod am43xx_qspi_hwmod = { | |||
417 | }, | 417 | }, |
418 | }; | 418 | }; |
419 | 419 | ||
420 | /* | ||
421 | * 'adc/tsc' class | ||
422 | * TouchScreen Controller (Analog-To-Digital Converter) | ||
423 | */ | ||
424 | static struct omap_hwmod_class_sysconfig am43xx_adc_tsc_sysc = { | ||
425 | .rev_offs = 0x00, | ||
426 | .sysc_offs = 0x10, | ||
427 | .sysc_flags = SYSC_HAS_SIDLEMODE, | ||
428 | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | | ||
429 | SIDLE_SMART_WKUP), | ||
430 | .sysc_fields = &omap_hwmod_sysc_type2, | ||
431 | }; | ||
432 | |||
433 | static struct omap_hwmod_class am43xx_adc_tsc_hwmod_class = { | ||
434 | .name = "adc_tsc", | ||
435 | .sysc = &am43xx_adc_tsc_sysc, | ||
436 | }; | ||
437 | |||
438 | static struct omap_hwmod am43xx_adc_tsc_hwmod = { | ||
439 | .name = "adc_tsc", | ||
440 | .class = &am43xx_adc_tsc_hwmod_class, | ||
441 | .clkdm_name = "l3s_tsc_clkdm", | ||
442 | .main_clk = "adc_tsc_fck", | ||
443 | .prcm = { | ||
444 | .omap4 = { | ||
445 | .clkctrl_offs = AM43XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET, | ||
446 | .modulemode = MODULEMODE_SWCTRL, | ||
447 | }, | ||
448 | }, | ||
449 | }; | ||
450 | |||
420 | /* dss */ | 451 | /* dss */ |
421 | 452 | ||
422 | static struct omap_hwmod am43xx_dss_core_hwmod = { | 453 | static struct omap_hwmod am43xx_dss_core_hwmod = { |
@@ -547,6 +578,13 @@ static struct omap_hwmod_ocp_if am43xx_l4_wkup__gpio0 = { | |||
547 | .user = OCP_USER_MPU | OCP_USER_SDMA, | 578 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
548 | }; | 579 | }; |
549 | 580 | ||
581 | static struct omap_hwmod_ocp_if am43xx_l4_wkup__adc_tsc = { | ||
582 | .master = &am33xx_l4_wkup_hwmod, | ||
583 | .slave = &am43xx_adc_tsc_hwmod, | ||
584 | .clk = "dpll_core_m4_div2_ck", | ||
585 | .user = OCP_USER_MPU, | ||
586 | }; | ||
587 | |||
550 | static struct omap_hwmod_ocp_if am43xx_l4_hs__cpgmac0 = { | 588 | static struct omap_hwmod_ocp_if am43xx_l4_hs__cpgmac0 = { |
551 | .master = &am43xx_l4_hs_hwmod, | 589 | .master = &am43xx_l4_hs_hwmod, |
552 | .slave = &am33xx_cpgmac0_hwmod, | 590 | .slave = &am33xx_cpgmac0_hwmod, |
@@ -789,6 +827,7 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { | |||
789 | &am43xx_l4_wkup__i2c1, | 827 | &am43xx_l4_wkup__i2c1, |
790 | &am43xx_l4_wkup__gpio0, | 828 | &am43xx_l4_wkup__gpio0, |
791 | &am43xx_l4_wkup__wd_timer1, | 829 | &am43xx_l4_wkup__wd_timer1, |
830 | &am43xx_l4_wkup__adc_tsc, | ||
792 | &am43xx_l3_s__qspi, | 831 | &am43xx_l3_s__qspi, |
793 | &am33xx_l4_per__dcan0, | 832 | &am33xx_l4_per__dcan0, |
794 | &am33xx_l4_per__dcan1, | 833 | &am33xx_l4_per__dcan1, |
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index d8a3cf1c1787..c314b3c31117 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c | |||
@@ -589,6 +589,7 @@ static struct omap_hwmod omap44xx_dss_hwmod = { | |||
589 | .omap4 = { | 589 | .omap4 = { |
590 | .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, | 590 | .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, |
591 | .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, | 591 | .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, |
592 | .modulemode = MODULEMODE_SWCTRL, | ||
592 | }, | 593 | }, |
593 | }, | 594 | }, |
594 | .opt_clks = dss_opt_clks, | 595 | .opt_clks = dss_opt_clks, |
@@ -647,7 +648,8 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = { | |||
647 | .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, | 648 | .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, |
648 | }, | 649 | }, |
649 | }, | 650 | }, |
650 | .dev_attr = &omap44xx_dss_dispc_dev_attr | 651 | .dev_attr = &omap44xx_dss_dispc_dev_attr, |
652 | .parent_hwmod = &omap44xx_dss_hwmod, | ||
651 | }; | 653 | }; |
652 | 654 | ||
653 | /* | 655 | /* |
@@ -701,6 +703,7 @@ static struct omap_hwmod omap44xx_dss_dsi1_hwmod = { | |||
701 | }, | 703 | }, |
702 | .opt_clks = dss_dsi1_opt_clks, | 704 | .opt_clks = dss_dsi1_opt_clks, |
703 | .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_opt_clks), | 705 | .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_opt_clks), |
706 | .parent_hwmod = &omap44xx_dss_hwmod, | ||
704 | }; | 707 | }; |
705 | 708 | ||
706 | /* dss_dsi2 */ | 709 | /* dss_dsi2 */ |
@@ -733,6 +736,7 @@ static struct omap_hwmod omap44xx_dss_dsi2_hwmod = { | |||
733 | }, | 736 | }, |
734 | .opt_clks = dss_dsi2_opt_clks, | 737 | .opt_clks = dss_dsi2_opt_clks, |
735 | .opt_clks_cnt = ARRAY_SIZE(dss_dsi2_opt_clks), | 738 | .opt_clks_cnt = ARRAY_SIZE(dss_dsi2_opt_clks), |
739 | .parent_hwmod = &omap44xx_dss_hwmod, | ||
736 | }; | 740 | }; |
737 | 741 | ||
738 | /* | 742 | /* |
@@ -790,6 +794,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { | |||
790 | }, | 794 | }, |
791 | .opt_clks = dss_hdmi_opt_clks, | 795 | .opt_clks = dss_hdmi_opt_clks, |
792 | .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), | 796 | .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), |
797 | .parent_hwmod = &omap44xx_dss_hwmod, | ||
793 | }; | 798 | }; |
794 | 799 | ||
795 | /* | 800 | /* |
@@ -819,7 +824,7 @@ static struct omap_hwmod_dma_info omap44xx_dss_rfbi_sdma_reqs[] = { | |||
819 | }; | 824 | }; |
820 | 825 | ||
821 | static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { | 826 | static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { |
822 | { .role = "ick", .clk = "dss_fck" }, | 827 | { .role = "ick", .clk = "l3_div_ck" }, |
823 | }; | 828 | }; |
824 | 829 | ||
825 | static struct omap_hwmod omap44xx_dss_rfbi_hwmod = { | 830 | static struct omap_hwmod omap44xx_dss_rfbi_hwmod = { |
@@ -836,6 +841,7 @@ static struct omap_hwmod omap44xx_dss_rfbi_hwmod = { | |||
836 | }, | 841 | }, |
837 | .opt_clks = dss_rfbi_opt_clks, | 842 | .opt_clks = dss_rfbi_opt_clks, |
838 | .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), | 843 | .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), |
844 | .parent_hwmod = &omap44xx_dss_hwmod, | ||
839 | }; | 845 | }; |
840 | 846 | ||
841 | /* | 847 | /* |
@@ -859,6 +865,7 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = { | |||
859 | .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, | 865 | .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, |
860 | }, | 866 | }, |
861 | }, | 867 | }, |
868 | .parent_hwmod = &omap44xx_dss_hwmod, | ||
862 | }; | 869 | }; |
863 | 870 | ||
864 | /* | 871 | /* |
@@ -3671,7 +3678,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dma_addrs[] = { | |||
3671 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss = { | 3678 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss = { |
3672 | .master = &omap44xx_l3_main_2_hwmod, | 3679 | .master = &omap44xx_l3_main_2_hwmod, |
3673 | .slave = &omap44xx_dss_hwmod, | 3680 | .slave = &omap44xx_dss_hwmod, |
3674 | .clk = "dss_fck", | 3681 | .clk = "l3_div_ck", |
3675 | .addr = omap44xx_dss_dma_addrs, | 3682 | .addr = omap44xx_dss_dma_addrs, |
3676 | .user = OCP_USER_SDMA, | 3683 | .user = OCP_USER_SDMA, |
3677 | }; | 3684 | }; |
@@ -3707,7 +3714,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dispc_dma_addrs[] = { | |||
3707 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dispc = { | 3714 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dispc = { |
3708 | .master = &omap44xx_l3_main_2_hwmod, | 3715 | .master = &omap44xx_l3_main_2_hwmod, |
3709 | .slave = &omap44xx_dss_dispc_hwmod, | 3716 | .slave = &omap44xx_dss_dispc_hwmod, |
3710 | .clk = "dss_fck", | 3717 | .clk = "l3_div_ck", |
3711 | .addr = omap44xx_dss_dispc_dma_addrs, | 3718 | .addr = omap44xx_dss_dispc_dma_addrs, |
3712 | .user = OCP_USER_SDMA, | 3719 | .user = OCP_USER_SDMA, |
3713 | }; | 3720 | }; |
@@ -3743,7 +3750,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dsi1_dma_addrs[] = { | |||
3743 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi1 = { | 3750 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi1 = { |
3744 | .master = &omap44xx_l3_main_2_hwmod, | 3751 | .master = &omap44xx_l3_main_2_hwmod, |
3745 | .slave = &omap44xx_dss_dsi1_hwmod, | 3752 | .slave = &omap44xx_dss_dsi1_hwmod, |
3746 | .clk = "dss_fck", | 3753 | .clk = "l3_div_ck", |
3747 | .addr = omap44xx_dss_dsi1_dma_addrs, | 3754 | .addr = omap44xx_dss_dsi1_dma_addrs, |
3748 | .user = OCP_USER_SDMA, | 3755 | .user = OCP_USER_SDMA, |
3749 | }; | 3756 | }; |
@@ -3779,7 +3786,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dsi2_dma_addrs[] = { | |||
3779 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi2 = { | 3786 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi2 = { |
3780 | .master = &omap44xx_l3_main_2_hwmod, | 3787 | .master = &omap44xx_l3_main_2_hwmod, |
3781 | .slave = &omap44xx_dss_dsi2_hwmod, | 3788 | .slave = &omap44xx_dss_dsi2_hwmod, |
3782 | .clk = "dss_fck", | 3789 | .clk = "l3_div_ck", |
3783 | .addr = omap44xx_dss_dsi2_dma_addrs, | 3790 | .addr = omap44xx_dss_dsi2_dma_addrs, |
3784 | .user = OCP_USER_SDMA, | 3791 | .user = OCP_USER_SDMA, |
3785 | }; | 3792 | }; |
@@ -3815,7 +3822,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_hdmi_dma_addrs[] = { | |||
3815 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_hdmi = { | 3822 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_hdmi = { |
3816 | .master = &omap44xx_l3_main_2_hwmod, | 3823 | .master = &omap44xx_l3_main_2_hwmod, |
3817 | .slave = &omap44xx_dss_hdmi_hwmod, | 3824 | .slave = &omap44xx_dss_hdmi_hwmod, |
3818 | .clk = "dss_fck", | 3825 | .clk = "l3_div_ck", |
3819 | .addr = omap44xx_dss_hdmi_dma_addrs, | 3826 | .addr = omap44xx_dss_hdmi_dma_addrs, |
3820 | .user = OCP_USER_SDMA, | 3827 | .user = OCP_USER_SDMA, |
3821 | }; | 3828 | }; |
@@ -3851,7 +3858,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_rfbi_dma_addrs[] = { | |||
3851 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_rfbi = { | 3858 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_rfbi = { |
3852 | .master = &omap44xx_l3_main_2_hwmod, | 3859 | .master = &omap44xx_l3_main_2_hwmod, |
3853 | .slave = &omap44xx_dss_rfbi_hwmod, | 3860 | .slave = &omap44xx_dss_rfbi_hwmod, |
3854 | .clk = "dss_fck", | 3861 | .clk = "l3_div_ck", |
3855 | .addr = omap44xx_dss_rfbi_dma_addrs, | 3862 | .addr = omap44xx_dss_rfbi_dma_addrs, |
3856 | .user = OCP_USER_SDMA, | 3863 | .user = OCP_USER_SDMA, |
3857 | }; | 3864 | }; |
@@ -3887,7 +3894,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_venc_dma_addrs[] = { | |||
3887 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_venc = { | 3894 | static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_venc = { |
3888 | .master = &omap44xx_l3_main_2_hwmod, | 3895 | .master = &omap44xx_l3_main_2_hwmod, |
3889 | .slave = &omap44xx_dss_venc_hwmod, | 3896 | .slave = &omap44xx_dss_venc_hwmod, |
3890 | .clk = "dss_fck", | 3897 | .clk = "l3_div_ck", |
3891 | .addr = omap44xx_dss_venc_dma_addrs, | 3898 | .addr = omap44xx_dss_venc_dma_addrs, |
3892 | .user = OCP_USER_SDMA, | 3899 | .user = OCP_USER_SDMA, |
3893 | }; | 3900 | }; |
diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c index 5ec786a76d3c..3e9523084b2a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c | |||
@@ -421,6 +421,7 @@ static struct omap_hwmod omap54xx_dss_dispc_hwmod = { | |||
421 | .opt_clks = dss_dispc_opt_clks, | 421 | .opt_clks = dss_dispc_opt_clks, |
422 | .opt_clks_cnt = ARRAY_SIZE(dss_dispc_opt_clks), | 422 | .opt_clks_cnt = ARRAY_SIZE(dss_dispc_opt_clks), |
423 | .dev_attr = &dss_dispc_dev_attr, | 423 | .dev_attr = &dss_dispc_dev_attr, |
424 | .parent_hwmod = &omap54xx_dss_hwmod, | ||
424 | }; | 425 | }; |
425 | 426 | ||
426 | /* | 427 | /* |
@@ -462,6 +463,7 @@ static struct omap_hwmod omap54xx_dss_dsi1_a_hwmod = { | |||
462 | }, | 463 | }, |
463 | .opt_clks = dss_dsi1_a_opt_clks, | 464 | .opt_clks = dss_dsi1_a_opt_clks, |
464 | .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_a_opt_clks), | 465 | .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_a_opt_clks), |
466 | .parent_hwmod = &omap54xx_dss_hwmod, | ||
465 | }; | 467 | }; |
466 | 468 | ||
467 | /* dss_dsi1_c */ | 469 | /* dss_dsi1_c */ |
@@ -482,6 +484,7 @@ static struct omap_hwmod omap54xx_dss_dsi1_c_hwmod = { | |||
482 | }, | 484 | }, |
483 | .opt_clks = dss_dsi1_c_opt_clks, | 485 | .opt_clks = dss_dsi1_c_opt_clks, |
484 | .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_c_opt_clks), | 486 | .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_c_opt_clks), |
487 | .parent_hwmod = &omap54xx_dss_hwmod, | ||
485 | }; | 488 | }; |
486 | 489 | ||
487 | /* | 490 | /* |
@@ -521,6 +524,7 @@ static struct omap_hwmod omap54xx_dss_hdmi_hwmod = { | |||
521 | }, | 524 | }, |
522 | .opt_clks = dss_hdmi_opt_clks, | 525 | .opt_clks = dss_hdmi_opt_clks, |
523 | .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), | 526 | .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), |
527 | .parent_hwmod = &omap54xx_dss_hwmod, | ||
524 | }; | 528 | }; |
525 | 529 | ||
526 | /* | 530 | /* |
@@ -560,6 +564,7 @@ static struct omap_hwmod omap54xx_dss_rfbi_hwmod = { | |||
560 | }, | 564 | }, |
561 | .opt_clks = dss_rfbi_opt_clks, | 565 | .opt_clks = dss_rfbi_opt_clks, |
562 | .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), | 566 | .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), |
567 | .parent_hwmod = &omap54xx_dss_hwmod, | ||
563 | }; | 568 | }; |
564 | 569 | ||
565 | /* | 570 | /* |
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index 711c97e90990..ffd6604cd546 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c | |||
@@ -2075,6 +2075,70 @@ static struct omap_hwmod dra7xx_uart6_hwmod = { | |||
2075 | }, | 2075 | }, |
2076 | }; | 2076 | }; |
2077 | 2077 | ||
2078 | /* uart7 */ | ||
2079 | static struct omap_hwmod dra7xx_uart7_hwmod = { | ||
2080 | .name = "uart7", | ||
2081 | .class = &dra7xx_uart_hwmod_class, | ||
2082 | .clkdm_name = "l4per2_clkdm", | ||
2083 | .main_clk = "uart7_gfclk_mux", | ||
2084 | .flags = HWMOD_SWSUP_SIDLE_ACT, | ||
2085 | .prcm = { | ||
2086 | .omap4 = { | ||
2087 | .clkctrl_offs = DRA7XX_CM_L4PER2_UART7_CLKCTRL_OFFSET, | ||
2088 | .context_offs = DRA7XX_RM_L4PER2_UART7_CONTEXT_OFFSET, | ||
2089 | .modulemode = MODULEMODE_SWCTRL, | ||
2090 | }, | ||
2091 | }, | ||
2092 | }; | ||
2093 | |||
2094 | /* uart8 */ | ||
2095 | static struct omap_hwmod dra7xx_uart8_hwmod = { | ||
2096 | .name = "uart8", | ||
2097 | .class = &dra7xx_uart_hwmod_class, | ||
2098 | .clkdm_name = "l4per2_clkdm", | ||
2099 | .main_clk = "uart8_gfclk_mux", | ||
2100 | .flags = HWMOD_SWSUP_SIDLE_ACT, | ||
2101 | .prcm = { | ||
2102 | .omap4 = { | ||
2103 | .clkctrl_offs = DRA7XX_CM_L4PER2_UART8_CLKCTRL_OFFSET, | ||
2104 | .context_offs = DRA7XX_RM_L4PER2_UART8_CONTEXT_OFFSET, | ||
2105 | .modulemode = MODULEMODE_SWCTRL, | ||
2106 | }, | ||
2107 | }, | ||
2108 | }; | ||
2109 | |||
2110 | /* uart9 */ | ||
2111 | static struct omap_hwmod dra7xx_uart9_hwmod = { | ||
2112 | .name = "uart9", | ||
2113 | .class = &dra7xx_uart_hwmod_class, | ||
2114 | .clkdm_name = "l4per2_clkdm", | ||
2115 | .main_clk = "uart9_gfclk_mux", | ||
2116 | .flags = HWMOD_SWSUP_SIDLE_ACT, | ||
2117 | .prcm = { | ||
2118 | .omap4 = { | ||
2119 | .clkctrl_offs = DRA7XX_CM_L4PER2_UART9_CLKCTRL_OFFSET, | ||
2120 | .context_offs = DRA7XX_RM_L4PER2_UART9_CONTEXT_OFFSET, | ||
2121 | .modulemode = MODULEMODE_SWCTRL, | ||
2122 | }, | ||
2123 | }, | ||
2124 | }; | ||
2125 | |||
2126 | /* uart10 */ | ||
2127 | static struct omap_hwmod dra7xx_uart10_hwmod = { | ||
2128 | .name = "uart10", | ||
2129 | .class = &dra7xx_uart_hwmod_class, | ||
2130 | .clkdm_name = "wkupaon_clkdm", | ||
2131 | .main_clk = "uart10_gfclk_mux", | ||
2132 | .flags = HWMOD_SWSUP_SIDLE_ACT, | ||
2133 | .prcm = { | ||
2134 | .omap4 = { | ||
2135 | .clkctrl_offs = DRA7XX_CM_WKUPAON_UART10_CLKCTRL_OFFSET, | ||
2136 | .context_offs = DRA7XX_RM_WKUPAON_UART10_CONTEXT_OFFSET, | ||
2137 | .modulemode = MODULEMODE_SWCTRL, | ||
2138 | }, | ||
2139 | }, | ||
2140 | }; | ||
2141 | |||
2078 | /* | 2142 | /* |
2079 | * 'usb_otg_ss' class | 2143 | * 'usb_otg_ss' class |
2080 | * | 2144 | * |
@@ -3095,6 +3159,38 @@ static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart6 = { | |||
3095 | .user = OCP_USER_MPU | OCP_USER_SDMA, | 3159 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
3096 | }; | 3160 | }; |
3097 | 3161 | ||
3162 | /* l4_per2 -> uart7 */ | ||
3163 | static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart7 = { | ||
3164 | .master = &dra7xx_l4_per2_hwmod, | ||
3165 | .slave = &dra7xx_uart7_hwmod, | ||
3166 | .clk = "l3_iclk_div", | ||
3167 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
3168 | }; | ||
3169 | |||
3170 | /* l4_per2 -> uart8 */ | ||
3171 | static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart8 = { | ||
3172 | .master = &dra7xx_l4_per2_hwmod, | ||
3173 | .slave = &dra7xx_uart8_hwmod, | ||
3174 | .clk = "l3_iclk_div", | ||
3175 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
3176 | }; | ||
3177 | |||
3178 | /* l4_per2 -> uart9 */ | ||
3179 | static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart9 = { | ||
3180 | .master = &dra7xx_l4_per2_hwmod, | ||
3181 | .slave = &dra7xx_uart9_hwmod, | ||
3182 | .clk = "l3_iclk_div", | ||
3183 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
3184 | }; | ||
3185 | |||
3186 | /* l4_wkup -> uart10 */ | ||
3187 | static struct omap_hwmod_ocp_if dra7xx_l4_wkup__uart10 = { | ||
3188 | .master = &dra7xx_l4_wkup_hwmod, | ||
3189 | .slave = &dra7xx_uart10_hwmod, | ||
3190 | .clk = "wkupaon_iclk_mux", | ||
3191 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
3192 | }; | ||
3193 | |||
3098 | /* l4_per3 -> usb_otg_ss1 */ | 3194 | /* l4_per3 -> usb_otg_ss1 */ |
3099 | static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss1 = { | 3195 | static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss1 = { |
3100 | .master = &dra7xx_l4_per3_hwmod, | 3196 | .master = &dra7xx_l4_per3_hwmod, |
@@ -3259,6 +3355,10 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { | |||
3259 | &dra7xx_l4_per1__uart4, | 3355 | &dra7xx_l4_per1__uart4, |
3260 | &dra7xx_l4_per1__uart5, | 3356 | &dra7xx_l4_per1__uart5, |
3261 | &dra7xx_l4_per1__uart6, | 3357 | &dra7xx_l4_per1__uart6, |
3358 | &dra7xx_l4_per2__uart7, | ||
3359 | &dra7xx_l4_per2__uart8, | ||
3360 | &dra7xx_l4_per2__uart9, | ||
3361 | &dra7xx_l4_wkup__uart10, | ||
3262 | &dra7xx_l4_per3__usb_otg_ss1, | 3362 | &dra7xx_l4_per3__usb_otg_ss1, |
3263 | &dra7xx_l4_per3__usb_otg_ss2, | 3363 | &dra7xx_l4_per3__usb_otg_ss2, |
3264 | &dra7xx_l4_per3__usb_otg_ss3, | 3364 | &dra7xx_l4_per3__usb_otg_ss3, |
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 503097c72b82..d697cecf762b 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c | |||
@@ -37,6 +37,16 @@ struct power_state { | |||
37 | struct list_head node; | 37 | struct list_head node; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | /** | ||
41 | * struct static_dep_map - Static dependency map | ||
42 | * @from: from clockdomain | ||
43 | * @to: to clockdomain | ||
44 | */ | ||
45 | struct static_dep_map { | ||
46 | const char *from; | ||
47 | const char *to; | ||
48 | }; | ||
49 | |||
40 | static u32 cpu_suspend_state = PWRDM_POWER_OFF; | 50 | static u32 cpu_suspend_state = PWRDM_POWER_OFF; |
41 | 51 | ||
42 | static LIST_HEAD(pwrst_list); | 52 | static LIST_HEAD(pwrst_list); |
@@ -148,94 +158,61 @@ static void omap_default_idle(void) | |||
148 | omap_do_wfi(); | 158 | omap_do_wfi(); |
149 | } | 159 | } |
150 | 160 | ||
151 | /** | 161 | /* |
152 | * omap4_init_static_deps - Add OMAP4 static dependencies | 162 | * The dynamic dependency between MPUSS -> MEMIF and |
153 | * | 163 | * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as |
154 | * Add needed static clockdomain dependencies on OMAP4 devices. | 164 | * expected. The hardware recommendation is to enable static |
155 | * Return: 0 on success or 'err' on failures | 165 | * dependencies for these to avoid system lock ups or random crashes. |
166 | * The L4 wakeup depedency is added to workaround the OCP sync hardware | ||
167 | * BUG with 32K synctimer which lead to incorrect timer value read | ||
168 | * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which | ||
169 | * are part of L4 wakeup clockdomain. | ||
156 | */ | 170 | */ |
157 | static inline int omap4_init_static_deps(void) | 171 | static const struct static_dep_map omap4_static_dep_map[] = { |
158 | { | 172 | {.from = "mpuss_clkdm", .to = "l3_emif_clkdm"}, |
159 | struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; | 173 | {.from = "mpuss_clkdm", .to = "l3_1_clkdm"}, |
160 | struct clockdomain *ducati_clkdm, *l3_2_clkdm; | 174 | {.from = "mpuss_clkdm", .to = "l3_2_clkdm"}, |
161 | int ret = 0; | 175 | {.from = "ducati_clkdm", .to = "l3_1_clkdm"}, |
162 | 176 | {.from = "ducati_clkdm", .to = "l3_2_clkdm"}, | |
163 | if (omap_rev() == OMAP4430_REV_ES1_0) { | 177 | {.from = NULL} /* TERMINATION */ |
164 | WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); | 178 | }; |
165 | return -ENODEV; | ||
166 | } | ||
167 | |||
168 | pr_err("Power Management for TI OMAP4.\n"); | ||
169 | /* | ||
170 | * OMAP4 chip PM currently works only with certain (newer) | ||
171 | * versions of bootloaders. This is due to missing code in the | ||
172 | * kernel to properly reset and initialize some devices. | ||
173 | * http://www.spinics.net/lists/arm-kernel/msg218641.html | ||
174 | */ | ||
175 | pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n"); | ||
176 | |||
177 | ret = pwrdm_for_each(pwrdms_setup, NULL); | ||
178 | if (ret) { | ||
179 | pr_err("Failed to setup powerdomains\n"); | ||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | /* | ||
184 | * The dynamic dependency between MPUSS -> MEMIF and | ||
185 | * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as | ||
186 | * expected. The hardware recommendation is to enable static | ||
187 | * dependencies for these to avoid system lock ups or random crashes. | ||
188 | * The L4 wakeup depedency is added to workaround the OCP sync hardware | ||
189 | * BUG with 32K synctimer which lead to incorrect timer value read | ||
190 | * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which | ||
191 | * are part of L4 wakeup clockdomain. | ||
192 | */ | ||
193 | mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); | ||
194 | emif_clkdm = clkdm_lookup("l3_emif_clkdm"); | ||
195 | l3_1_clkdm = clkdm_lookup("l3_1_clkdm"); | ||
196 | l3_2_clkdm = clkdm_lookup("l3_2_clkdm"); | ||
197 | ducati_clkdm = clkdm_lookup("ducati_clkdm"); | ||
198 | if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || | ||
199 | (!l3_2_clkdm) || (!ducati_clkdm)) | ||
200 | return -EINVAL; | ||
201 | |||
202 | ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); | ||
203 | ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); | ||
204 | ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm); | ||
205 | ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm); | ||
206 | ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); | ||
207 | if (ret) { | ||
208 | pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n"); | ||
209 | return -EINVAL; | ||
210 | } | ||
211 | 179 | ||
212 | return ret; | 180 | static const struct static_dep_map omap5_dra7_static_dep_map[] = { |
213 | } | 181 | {.from = "mpu_clkdm", .to = "emif_clkdm"}, |
182 | {.from = NULL} /* TERMINATION */ | ||
183 | }; | ||
214 | 184 | ||
215 | /** | 185 | /** |
216 | * omap5_dra7_init_static_deps - Init static clkdm dependencies on OMAP5 and | 186 | * omap4plus_init_static_deps() - Initialize a static dependency map |
217 | * DRA7 | 187 | * @map: Mapping of clock domains |
218 | * | ||
219 | * The dynamic dependency between MPUSS -> EMIF is broken and has | ||
220 | * not worked as expected. The hardware recommendation is to | ||
221 | * enable static dependencies for these to avoid system | ||
222 | * lock ups or random crashes. | ||
223 | */ | 188 | */ |
224 | static inline int omap5_dra7_init_static_deps(void) | 189 | static inline int omap4plus_init_static_deps(const struct static_dep_map *map) |
225 | { | 190 | { |
226 | struct clockdomain *mpuss_clkdm, *emif_clkdm; | ||
227 | int ret; | 191 | int ret; |
192 | struct clockdomain *from, *to; | ||
193 | |||
194 | if (!map) | ||
195 | return 0; | ||
228 | 196 | ||
229 | mpuss_clkdm = clkdm_lookup("mpu_clkdm"); | 197 | while (map->from) { |
230 | emif_clkdm = clkdm_lookup("emif_clkdm"); | 198 | from = clkdm_lookup(map->from); |
231 | if (!mpuss_clkdm || !emif_clkdm) | 199 | to = clkdm_lookup(map->to); |
232 | return -EINVAL; | 200 | if (!from || !to) { |
201 | pr_err("Failed lookup %s or %s for wakeup dependency\n", | ||
202 | map->from, map->to); | ||
203 | return -EINVAL; | ||
204 | } | ||
205 | ret = clkdm_add_wkdep(from, to); | ||
206 | if (ret) { | ||
207 | pr_err("Failed to add %s -> %s wakeup dependency(%d)\n", | ||
208 | map->from, map->to, ret); | ||
209 | return ret; | ||
210 | } | ||
233 | 211 | ||
234 | ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); | 212 | map++; |
235 | if (ret) | 213 | }; |
236 | pr_err("Failed to add MPUSS -> EMIF wakeup dependency\n"); | ||
237 | 214 | ||
238 | return ret; | 215 | return 0; |
239 | } | 216 | } |
240 | 217 | ||
241 | /** | 218 | /** |
@@ -272,6 +249,15 @@ int __init omap4_pm_init(void) | |||
272 | 249 | ||
273 | pr_info("Power Management for TI OMAP4+ devices.\n"); | 250 | pr_info("Power Management for TI OMAP4+ devices.\n"); |
274 | 251 | ||
252 | /* | ||
253 | * OMAP4 chip PM currently works only with certain (newer) | ||
254 | * versions of bootloaders. This is due to missing code in the | ||
255 | * kernel to properly reset and initialize some devices. | ||
256 | * http://www.spinics.net/lists/arm-kernel/msg218641.html | ||
257 | */ | ||
258 | if (cpu_is_omap44xx()) | ||
259 | pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n"); | ||
260 | |||
275 | ret = pwrdm_for_each(pwrdms_setup, NULL); | 261 | ret = pwrdm_for_each(pwrdms_setup, NULL); |
276 | if (ret) { | 262 | if (ret) { |
277 | pr_err("Failed to setup powerdomains.\n"); | 263 | pr_err("Failed to setup powerdomains.\n"); |
@@ -279,9 +265,9 @@ int __init omap4_pm_init(void) | |||
279 | } | 265 | } |
280 | 266 | ||
281 | if (cpu_is_omap44xx()) | 267 | if (cpu_is_omap44xx()) |
282 | ret = omap4_init_static_deps(); | 268 | ret = omap4plus_init_static_deps(omap4_static_dep_map); |
283 | else if (soc_is_omap54xx() || soc_is_dra7xx()) | 269 | else if (soc_is_omap54xx() || soc_is_dra7xx()) |
284 | ret = omap5_dra7_init_static_deps(); | 270 | ret = omap4plus_init_static_deps(omap5_dra7_static_dep_map); |
285 | 271 | ||
286 | if (ret) { | 272 | if (ret) { |
287 | pr_err("Failed to initialise static dependencies.\n"); | 273 | pr_err("Failed to initialise static dependencies.\n"); |
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index 48480d557b61..77752e49d8d4 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h | |||
@@ -29,6 +29,7 @@ int of_prcm_init(void); | |||
29 | * PRM_HAS_VOLTAGE: has voltage domains | 29 | * PRM_HAS_VOLTAGE: has voltage domains |
30 | */ | 30 | */ |
31 | #define PRM_HAS_IO_WAKEUP (1 << 0) | 31 | #define PRM_HAS_IO_WAKEUP (1 << 0) |
32 | #define PRM_HAS_VOLTAGE (1 << 1) | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | * MAX_MODULE_SOFTRESET_WAIT: Maximum microseconds to wait for OMAP | 35 | * MAX_MODULE_SOFTRESET_WAIT: Maximum microseconds to wait for OMAP |
@@ -127,6 +128,8 @@ struct prm_reset_src_map { | |||
127 | * @was_any_context_lost_old: ptr to the SoC PRM context loss test fn | 128 | * @was_any_context_lost_old: ptr to the SoC PRM context loss test fn |
128 | * @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn | 129 | * @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn |
129 | * @late_init: ptr to the late init function | 130 | * @late_init: ptr to the late init function |
131 | * @assert_hardreset: ptr to the SoC PRM hardreset assert impl | ||
132 | * @deassert_hardreset: ptr to the SoC PRM hardreset deassert impl | ||
130 | * | 133 | * |
131 | * XXX @was_any_context_lost_old and @clear_context_loss_flags_old are | 134 | * XXX @was_any_context_lost_old and @clear_context_loss_flags_old are |
132 | * deprecated. | 135 | * deprecated. |
@@ -136,14 +139,27 @@ struct prm_ll_data { | |||
136 | bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx); | 139 | bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx); |
137 | void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx); | 140 | void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx); |
138 | int (*late_init)(void); | 141 | int (*late_init)(void); |
142 | int (*assert_hardreset)(u8 shift, u8 part, s16 prm_mod, u16 offset); | ||
143 | int (*deassert_hardreset)(u8 shift, u8 st_shift, u8 part, s16 prm_mod, | ||
144 | u16 offset, u16 st_offset); | ||
145 | int (*is_hardreset_asserted)(u8 shift, u8 part, s16 prm_mod, | ||
146 | u16 offset); | ||
147 | void (*reset_system)(void); | ||
139 | }; | 148 | }; |
140 | 149 | ||
141 | extern int prm_register(struct prm_ll_data *pld); | 150 | extern int prm_register(struct prm_ll_data *pld); |
142 | extern int prm_unregister(struct prm_ll_data *pld); | 151 | extern int prm_unregister(struct prm_ll_data *pld); |
143 | 152 | ||
153 | int omap_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset); | ||
154 | int omap_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 prm_mod, | ||
155 | u16 offset, u16 st_offset); | ||
156 | int omap_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset); | ||
144 | extern u32 prm_read_reset_sources(void); | 157 | extern u32 prm_read_reset_sources(void); |
145 | extern bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx); | 158 | extern bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx); |
146 | extern void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx); | 159 | extern void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx); |
160 | void omap_prm_reset_system(void); | ||
161 | |||
162 | void omap_prm_reconfigure_io_chain(void); | ||
147 | 163 | ||
148 | #endif | 164 | #endif |
149 | 165 | ||
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c index 86958050547a..af0f15278fc2 100644 --- a/arch/arm/mach-omap2/prm2xxx.c +++ b/arch/arm/mach-omap2/prm2xxx.c | |||
@@ -106,7 +106,7 @@ static int omap2xxx_pwrst_to_common_pwrst(u8 omap2xxx_pwrst) | |||
106 | * Set the DPLL reset bit, which should reboot the SoC. This is the | 106 | * Set the DPLL reset bit, which should reboot the SoC. This is the |
107 | * recommended way to restart the SoC. No return value. | 107 | * recommended way to restart the SoC. No return value. |
108 | */ | 108 | */ |
109 | void omap2xxx_prm_dpll_reset(void) | 109 | static void omap2xxx_prm_dpll_reset(void) |
110 | { | 110 | { |
111 | omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, WKUP_MOD, | 111 | omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, WKUP_MOD, |
112 | OMAP2_RM_RSTCTRL); | 112 | OMAP2_RM_RSTCTRL); |
@@ -212,6 +212,10 @@ struct pwrdm_ops omap2_pwrdm_operations = { | |||
212 | 212 | ||
213 | static struct prm_ll_data omap2xxx_prm_ll_data = { | 213 | static struct prm_ll_data omap2xxx_prm_ll_data = { |
214 | .read_reset_sources = &omap2xxx_prm_read_reset_sources, | 214 | .read_reset_sources = &omap2xxx_prm_read_reset_sources, |
215 | .assert_hardreset = &omap2_prm_assert_hardreset, | ||
216 | .deassert_hardreset = &omap2_prm_deassert_hardreset, | ||
217 | .is_hardreset_asserted = &omap2_prm_is_hardreset_asserted, | ||
218 | .reset_system = &omap2xxx_prm_dpll_reset, | ||
215 | }; | 219 | }; |
216 | 220 | ||
217 | int __init omap2xxx_prm_init(void) | 221 | int __init omap2xxx_prm_init(void) |
diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h index d73414139292..1d51643062f7 100644 --- a/arch/arm/mach-omap2/prm2xxx.h +++ b/arch/arm/mach-omap2/prm2xxx.h | |||
@@ -124,7 +124,6 @@ | |||
124 | extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm); | 124 | extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm); |
125 | extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm); | 125 | extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm); |
126 | 126 | ||
127 | extern void omap2xxx_prm_dpll_reset(void); | ||
128 | void omap2xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask); | 127 | void omap2xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask); |
129 | 128 | ||
130 | extern int __init omap2xxx_prm_init(void); | 129 | extern int __init omap2xxx_prm_init(void); |
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index c13b4e293ffa..cc3341f263cd 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c | |||
@@ -24,14 +24,16 @@ | |||
24 | /** | 24 | /** |
25 | * omap2_prm_is_hardreset_asserted - read the HW reset line state of | 25 | * omap2_prm_is_hardreset_asserted - read the HW reset line state of |
26 | * submodules contained in the hwmod module | 26 | * submodules contained in the hwmod module |
27 | * @prm_mod: PRM submodule base (e.g. CORE_MOD) | ||
28 | * @shift: register bit shift corresponding to the reset line to check | 27 | * @shift: register bit shift corresponding to the reset line to check |
28 | * @part: PRM partition, ignored for OMAP2 | ||
29 | * @prm_mod: PRM submodule base (e.g. CORE_MOD) | ||
30 | * @offset: register offset, ignored for OMAP2 | ||
29 | * | 31 | * |
30 | * Returns 1 if the (sub)module hardreset line is currently asserted, | 32 | * Returns 1 if the (sub)module hardreset line is currently asserted, |
31 | * 0 if the (sub)module hardreset line is not currently asserted, or | 33 | * 0 if the (sub)module hardreset line is not currently asserted, or |
32 | * -EINVAL if called while running on a non-OMAP2/3 chip. | 34 | * -EINVAL if called while running on a non-OMAP2/3 chip. |
33 | */ | 35 | */ |
34 | int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) | 36 | int omap2_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset) |
35 | { | 37 | { |
36 | return omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, | 38 | return omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, |
37 | (1 << shift)); | 39 | (1 << shift)); |
@@ -39,8 +41,10 @@ int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) | |||
39 | 41 | ||
40 | /** | 42 | /** |
41 | * omap2_prm_assert_hardreset - assert the HW reset line of a submodule | 43 | * omap2_prm_assert_hardreset - assert the HW reset line of a submodule |
42 | * @prm_mod: PRM submodule base (e.g. CORE_MOD) | ||
43 | * @shift: register bit shift corresponding to the reset line to assert | 44 | * @shift: register bit shift corresponding to the reset line to assert |
45 | * @part: PRM partition, ignored for OMAP2 | ||
46 | * @prm_mod: PRM submodule base (e.g. CORE_MOD) | ||
47 | * @offset: register offset, ignored for OMAP2 | ||
44 | * | 48 | * |
45 | * Some IPs like dsp or iva contain processors that require an HW | 49 | * Some IPs like dsp or iva contain processors that require an HW |
46 | * reset line to be asserted / deasserted in order to fully enable the | 50 | * reset line to be asserted / deasserted in order to fully enable the |
@@ -49,7 +53,7 @@ int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) | |||
49 | * place the submodule into reset. Returns 0 upon success or -EINVAL | 53 | * place the submodule into reset. Returns 0 upon success or -EINVAL |
50 | * upon an argument error. | 54 | * upon an argument error. |
51 | */ | 55 | */ |
52 | int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift) | 56 | int omap2_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset) |
53 | { | 57 | { |
54 | u32 mask; | 58 | u32 mask; |
55 | 59 | ||
@@ -64,6 +68,10 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift) | |||
64 | * @prm_mod: PRM submodule base (e.g. CORE_MOD) | 68 | * @prm_mod: PRM submodule base (e.g. CORE_MOD) |
65 | * @rst_shift: register bit shift corresponding to the reset line to deassert | 69 | * @rst_shift: register bit shift corresponding to the reset line to deassert |
66 | * @st_shift: register bit shift for the status of the deasserted submodule | 70 | * @st_shift: register bit shift for the status of the deasserted submodule |
71 | * @part: PRM partition, not used for OMAP2 | ||
72 | * @prm_mod: PRM submodule base (e.g. CORE_MOD) | ||
73 | * @rst_offset: reset register offset, not used for OMAP2 | ||
74 | * @st_offset: reset status register offset, not used for OMAP2 | ||
67 | * | 75 | * |
68 | * Some IPs like dsp or iva contain processors that require an HW | 76 | * Some IPs like dsp or iva contain processors that require an HW |
69 | * reset line to be asserted / deasserted in order to fully enable the | 77 | * reset line to be asserted / deasserted in order to fully enable the |
@@ -74,7 +82,8 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift) | |||
74 | * -EINVAL upon an argument error, -EEXIST if the submodule was already out | 82 | * -EINVAL upon an argument error, -EEXIST if the submodule was already out |
75 | * of reset, or -EBUSY if the submodule did not exit reset promptly. | 83 | * of reset, or -EBUSY if the submodule did not exit reset promptly. |
76 | */ | 84 | */ |
77 | int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift) | 85 | int omap2_prm_deassert_hardreset(u8 rst_shift, u8 st_shift, u8 part, |
86 | s16 prm_mod, u16 rst_offset, u16 st_offset) | ||
78 | { | 87 | { |
79 | u32 rst, st; | 88 | u32 rst, st; |
80 | int c; | 89 | int c; |
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h index 1a3a96392b97..f57e29b0e041 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h | |||
@@ -100,9 +100,12 @@ static inline u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) | |||
100 | } | 100 | } |
101 | 101 | ||
102 | /* These omap2_ PRM functions apply to both OMAP2 and 3 */ | 102 | /* These omap2_ PRM functions apply to both OMAP2 and 3 */ |
103 | extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift); | 103 | int omap2_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset); |
104 | extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift); | 104 | int omap2_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, |
105 | extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift); | 105 | u16 offset); |
106 | int omap2_prm_deassert_hardreset(u8 rst_shift, u8 st_shift, u8 part, | ||
107 | s16 prm_mod, u16 reset_offset, | ||
108 | u16 st_offset); | ||
106 | 109 | ||
107 | extern int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst); | 110 | extern int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst); |
108 | extern int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm); | 111 | extern int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm); |
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c index 62709cd2f9c5..02f628601b09 100644 --- a/arch/arm/mach-omap2/prm33xx.c +++ b/arch/arm/mach-omap2/prm33xx.c | |||
@@ -23,20 +23,24 @@ | |||
23 | #include "prm33xx.h" | 23 | #include "prm33xx.h" |
24 | #include "prm-regbits-33xx.h" | 24 | #include "prm-regbits-33xx.h" |
25 | 25 | ||
26 | #define AM33XX_PRM_RSTCTRL_OFFSET 0x0000 | ||
27 | |||
28 | #define AM33XX_RST_GLOBAL_WARM_SW_MASK (1 << 0) | ||
29 | |||
26 | /* Read a register in a PRM instance */ | 30 | /* Read a register in a PRM instance */ |
27 | u32 am33xx_prm_read_reg(s16 inst, u16 idx) | 31 | static u32 am33xx_prm_read_reg(s16 inst, u16 idx) |
28 | { | 32 | { |
29 | return readl_relaxed(prm_base + inst + idx); | 33 | return readl_relaxed(prm_base + inst + idx); |
30 | } | 34 | } |
31 | 35 | ||
32 | /* Write into a register in a PRM instance */ | 36 | /* Write into a register in a PRM instance */ |
33 | void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) | 37 | static void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) |
34 | { | 38 | { |
35 | writel_relaxed(val, prm_base + inst + idx); | 39 | writel_relaxed(val, prm_base + inst + idx); |
36 | } | 40 | } |
37 | 41 | ||
38 | /* Read-modify-write a register in PRM. Caller must lock */ | 42 | /* Read-modify-write a register in PRM. Caller must lock */ |
39 | u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) | 43 | static u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) |
40 | { | 44 | { |
41 | u32 v; | 45 | u32 v; |
42 | 46 | ||
@@ -52,6 +56,7 @@ u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) | |||
52 | * am33xx_prm_is_hardreset_asserted - read the HW reset line state of | 56 | * am33xx_prm_is_hardreset_asserted - read the HW reset line state of |
53 | * submodules contained in the hwmod module | 57 | * submodules contained in the hwmod module |
54 | * @shift: register bit shift corresponding to the reset line to check | 58 | * @shift: register bit shift corresponding to the reset line to check |
59 | * @part: PRM partition, ignored for AM33xx | ||
55 | * @inst: CM instance register offset (*_INST macro) | 60 | * @inst: CM instance register offset (*_INST macro) |
56 | * @rstctrl_offs: RM_RSTCTRL register address offset for this module | 61 | * @rstctrl_offs: RM_RSTCTRL register address offset for this module |
57 | * | 62 | * |
@@ -59,7 +64,8 @@ u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) | |||
59 | * 0 if the (sub)module hardreset line is not currently asserted, or | 64 | * 0 if the (sub)module hardreset line is not currently asserted, or |
60 | * -EINVAL upon parameter error. | 65 | * -EINVAL upon parameter error. |
61 | */ | 66 | */ |
62 | int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, u16 rstctrl_offs) | 67 | static int am33xx_prm_is_hardreset_asserted(u8 shift, u8 part, s16 inst, |
68 | u16 rstctrl_offs) | ||
63 | { | 69 | { |
64 | u32 v; | 70 | u32 v; |
65 | 71 | ||
@@ -73,6 +79,7 @@ int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, u16 rstctrl_offs) | |||
73 | /** | 79 | /** |
74 | * am33xx_prm_assert_hardreset - assert the HW reset line of a submodule | 80 | * am33xx_prm_assert_hardreset - assert the HW reset line of a submodule |
75 | * @shift: register bit shift corresponding to the reset line to assert | 81 | * @shift: register bit shift corresponding to the reset line to assert |
82 | * @part: CM partition, ignored for AM33xx | ||
76 | * @inst: CM instance register offset (*_INST macro) | 83 | * @inst: CM instance register offset (*_INST macro) |
77 | * @rstctrl_reg: RM_RSTCTRL register address for this module | 84 | * @rstctrl_reg: RM_RSTCTRL register address for this module |
78 | * | 85 | * |
@@ -83,7 +90,8 @@ int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, u16 rstctrl_offs) | |||
83 | * place the submodule into reset. Returns 0 upon success or -EINVAL | 90 | * place the submodule into reset. Returns 0 upon success or -EINVAL |
84 | * upon an argument error. | 91 | * upon an argument error. |
85 | */ | 92 | */ |
86 | int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs) | 93 | static int am33xx_prm_assert_hardreset(u8 shift, u8 part, s16 inst, |
94 | u16 rstctrl_offs) | ||
87 | { | 95 | { |
88 | u32 mask = 1 << shift; | 96 | u32 mask = 1 << shift; |
89 | 97 | ||
@@ -96,6 +104,8 @@ int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs) | |||
96 | * am33xx_prm_deassert_hardreset - deassert a submodule hardreset line and | 104 | * am33xx_prm_deassert_hardreset - deassert a submodule hardreset line and |
97 | * wait | 105 | * wait |
98 | * @shift: register bit shift corresponding to the reset line to deassert | 106 | * @shift: register bit shift corresponding to the reset line to deassert |
107 | * @st_shift: reset status register bit shift corresponding to the reset line | ||
108 | * @part: PRM partition, not used for AM33xx | ||
99 | * @inst: CM instance register offset (*_INST macro) | 109 | * @inst: CM instance register offset (*_INST macro) |
100 | * @rstctrl_reg: RM_RSTCTRL register address for this module | 110 | * @rstctrl_reg: RM_RSTCTRL register address for this module |
101 | * @rstst_reg: RM_RSTST register address for this module | 111 | * @rstst_reg: RM_RSTST register address for this module |
@@ -109,14 +119,15 @@ int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs) | |||
109 | * -EINVAL upon an argument error, -EEXIST if the submodule was already out | 119 | * -EINVAL upon an argument error, -EEXIST if the submodule was already out |
110 | * of reset, or -EBUSY if the submodule did not exit reset promptly. | 120 | * of reset, or -EBUSY if the submodule did not exit reset promptly. |
111 | */ | 121 | */ |
112 | int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst, | 122 | static int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part, |
113 | u16 rstctrl_offs, u16 rstst_offs) | 123 | s16 inst, u16 rstctrl_offs, |
124 | u16 rstst_offs) | ||
114 | { | 125 | { |
115 | int c; | 126 | int c; |
116 | u32 mask = 1 << st_shift; | 127 | u32 mask = 1 << st_shift; |
117 | 128 | ||
118 | /* Check the current status to avoid de-asserting the line twice */ | 129 | /* Check the current status to avoid de-asserting the line twice */ |
119 | if (am33xx_prm_is_hardreset_asserted(shift, inst, rstctrl_offs) == 0) | 130 | if (am33xx_prm_is_hardreset_asserted(shift, 0, inst, rstctrl_offs) == 0) |
120 | return -EEXIST; | 131 | return -EEXIST; |
121 | 132 | ||
122 | /* Clear the reset status by writing 1 to the status bit */ | 133 | /* Clear the reset status by writing 1 to the status bit */ |
@@ -128,7 +139,7 @@ int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst, | |||
128 | am33xx_prm_rmw_reg_bits(mask, 0, inst, rstctrl_offs); | 139 | am33xx_prm_rmw_reg_bits(mask, 0, inst, rstctrl_offs); |
129 | 140 | ||
130 | /* wait the status to be set */ | 141 | /* wait the status to be set */ |
131 | omap_test_timeout(am33xx_prm_is_hardreset_asserted(st_shift, inst, | 142 | omap_test_timeout(am33xx_prm_is_hardreset_asserted(st_shift, 0, inst, |
132 | rstst_offs), | 143 | rstst_offs), |
133 | MAX_MODULE_HARDRESET_WAIT, c); | 144 | MAX_MODULE_HARDRESET_WAIT, c); |
134 | 145 | ||
@@ -325,6 +336,23 @@ static int am33xx_check_vcvp(void) | |||
325 | return 0; | 336 | return 0; |
326 | } | 337 | } |
327 | 338 | ||
339 | /** | ||
340 | * am33xx_prm_global_warm_sw_reset - reboot the device via warm reset | ||
341 | * | ||
342 | * Immediately reboots the device through warm reset. | ||
343 | */ | ||
344 | static void am33xx_prm_global_warm_sw_reset(void) | ||
345 | { | ||
346 | am33xx_prm_rmw_reg_bits(AM33XX_RST_GLOBAL_WARM_SW_MASK, | ||
347 | AM33XX_RST_GLOBAL_WARM_SW_MASK, | ||
348 | AM33XX_PRM_DEVICE_MOD, | ||
349 | AM33XX_PRM_RSTCTRL_OFFSET); | ||
350 | |||
351 | /* OCP barrier */ | ||
352 | (void)am33xx_prm_read_reg(AM33XX_PRM_DEVICE_MOD, | ||
353 | AM33XX_PRM_RSTCTRL_OFFSET); | ||
354 | } | ||
355 | |||
328 | struct pwrdm_ops am33xx_pwrdm_operations = { | 356 | struct pwrdm_ops am33xx_pwrdm_operations = { |
329 | .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst, | 357 | .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst, |
330 | .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst, | 358 | .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst, |
@@ -342,3 +370,21 @@ struct pwrdm_ops am33xx_pwrdm_operations = { | |||
342 | .pwrdm_wait_transition = am33xx_pwrdm_wait_transition, | 370 | .pwrdm_wait_transition = am33xx_pwrdm_wait_transition, |
343 | .pwrdm_has_voltdm = am33xx_check_vcvp, | 371 | .pwrdm_has_voltdm = am33xx_check_vcvp, |
344 | }; | 372 | }; |
373 | |||
374 | static struct prm_ll_data am33xx_prm_ll_data = { | ||
375 | .assert_hardreset = am33xx_prm_assert_hardreset, | ||
376 | .deassert_hardreset = am33xx_prm_deassert_hardreset, | ||
377 | .is_hardreset_asserted = am33xx_prm_is_hardreset_asserted, | ||
378 | .reset_system = am33xx_prm_global_warm_sw_reset, | ||
379 | }; | ||
380 | |||
381 | int __init am33xx_prm_init(void) | ||
382 | { | ||
383 | return prm_register(&am33xx_prm_ll_data); | ||
384 | } | ||
385 | |||
386 | static void __exit am33xx_prm_exit(void) | ||
387 | { | ||
388 | prm_unregister(&am33xx_prm_ll_data); | ||
389 | } | ||
390 | __exitcall(am33xx_prm_exit); | ||
diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h index 9b9918dfb119..98ac41f271da 100644 --- a/arch/arm/mach-omap2/prm33xx.h +++ b/arch/arm/mach-omap2/prm33xx.h | |||
@@ -118,14 +118,7 @@ | |||
118 | #define AM33XX_PM_CEFUSE_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004) | 118 | #define AM33XX_PM_CEFUSE_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004) |
119 | 119 | ||
120 | #ifndef __ASSEMBLER__ | 120 | #ifndef __ASSEMBLER__ |
121 | extern u32 am33xx_prm_read_reg(s16 inst, u16 idx); | 121 | int am33xx_prm_init(void); |
122 | extern void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx); | 122 | |
123 | extern u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); | ||
124 | extern void am33xx_prm_global_warm_sw_reset(void); | ||
125 | extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, | ||
126 | u16 rstctrl_offs); | ||
127 | extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs); | ||
128 | extern int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst, | ||
129 | u16 rstctrl_offs, u16 rstst_offs); | ||
130 | #endif /* ASSEMBLER */ | 123 | #endif /* ASSEMBLER */ |
131 | #endif | 124 | #endif |
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c index ff08da385a2d..c5e00c6714b1 100644 --- a/arch/arm/mach-omap2/prm3xxx.c +++ b/arch/arm/mach-omap2/prm3xxx.c | |||
@@ -30,6 +30,11 @@ | |||
30 | #include "cm3xxx.h" | 30 | #include "cm3xxx.h" |
31 | #include "cm-regbits-34xx.h" | 31 | #include "cm-regbits-34xx.h" |
32 | 32 | ||
33 | static void omap3xxx_prm_read_pending_irqs(unsigned long *events); | ||
34 | static void omap3xxx_prm_ocp_barrier(void); | ||
35 | static void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask); | ||
36 | static void omap3xxx_prm_restore_irqen(u32 *saved_mask); | ||
37 | |||
33 | static const struct omap_prcm_irq omap3_prcm_irqs[] = { | 38 | static const struct omap_prcm_irq omap3_prcm_irqs[] = { |
34 | OMAP_PRCM_IRQ("wkup", 0, 0), | 39 | OMAP_PRCM_IRQ("wkup", 0, 0), |
35 | OMAP_PRCM_IRQ("io", 9, 1), | 40 | OMAP_PRCM_IRQ("io", 9, 1), |
@@ -131,7 +136,7 @@ u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset) | |||
131 | * recommended way to restart the SoC, considering Errata i520. No | 136 | * recommended way to restart the SoC, considering Errata i520. No |
132 | * return value. | 137 | * return value. |
133 | */ | 138 | */ |
134 | void omap3xxx_prm_dpll3_reset(void) | 139 | static void omap3xxx_prm_dpll3_reset(void) |
135 | { | 140 | { |
136 | omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, OMAP3430_GR_MOD, | 141 | omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, OMAP3430_GR_MOD, |
137 | OMAP2_RM_RSTCTRL); | 142 | OMAP2_RM_RSTCTRL); |
@@ -147,7 +152,7 @@ void omap3xxx_prm_dpll3_reset(void) | |||
147 | * MPU IRQs, and store the result into the u32 pointed to by @events. | 152 | * MPU IRQs, and store the result into the u32 pointed to by @events. |
148 | * No return value. | 153 | * No return value. |
149 | */ | 154 | */ |
150 | void omap3xxx_prm_read_pending_irqs(unsigned long *events) | 155 | static void omap3xxx_prm_read_pending_irqs(unsigned long *events) |
151 | { | 156 | { |
152 | u32 mask, st; | 157 | u32 mask, st; |
153 | 158 | ||
@@ -166,7 +171,7 @@ void omap3xxx_prm_read_pending_irqs(unsigned long *events) | |||
166 | * block, to avoid race conditions after acknowledging or clearing IRQ | 171 | * block, to avoid race conditions after acknowledging or clearing IRQ |
167 | * bits. No return value. | 172 | * bits. No return value. |
168 | */ | 173 | */ |
169 | void omap3xxx_prm_ocp_barrier(void) | 174 | static void omap3xxx_prm_ocp_barrier(void) |
170 | { | 175 | { |
171 | omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET); | 176 | omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET); |
172 | } | 177 | } |
@@ -182,7 +187,7 @@ void omap3xxx_prm_ocp_barrier(void) | |||
182 | * returning; otherwise, spurious interrupts might occur. No return | 187 | * returning; otherwise, spurious interrupts might occur. No return |
183 | * value. | 188 | * value. |
184 | */ | 189 | */ |
185 | void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask) | 190 | static void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask) |
186 | { | 191 | { |
187 | saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD, | 192 | saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD, |
188 | OMAP3_PRM_IRQENABLE_MPU_OFFSET); | 193 | OMAP3_PRM_IRQENABLE_MPU_OFFSET); |
@@ -202,7 +207,7 @@ void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask) | |||
202 | * barrier should be needed here; any pending PRM interrupts will fire | 207 | * barrier should be needed here; any pending PRM interrupts will fire |
203 | * once the writes reach the PRM. No return value. | 208 | * once the writes reach the PRM. No return value. |
204 | */ | 209 | */ |
205 | void omap3xxx_prm_restore_irqen(u32 *saved_mask) | 210 | static void omap3xxx_prm_restore_irqen(u32 *saved_mask) |
206 | { | 211 | { |
207 | omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD, | 212 | omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD, |
208 | OMAP3_PRM_IRQENABLE_MPU_OFFSET); | 213 | OMAP3_PRM_IRQENABLE_MPU_OFFSET); |
@@ -375,7 +380,7 @@ void __init omap3_prm_init_pm(bool has_uart4, bool has_iva) | |||
375 | * The ST_IO_CHAIN bit does not exist in 3430 before es3.1. The only | 380 | * The ST_IO_CHAIN bit does not exist in 3430 before es3.1. The only |
376 | * thing we can do is toggle EN_IO bit for earlier omaps. | 381 | * thing we can do is toggle EN_IO bit for earlier omaps. |
377 | */ | 382 | */ |
378 | void omap3430_pre_es3_1_reconfigure_io_chain(void) | 383 | static void omap3430_pre_es3_1_reconfigure_io_chain(void) |
379 | { | 384 | { |
380 | omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, | 385 | omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, |
381 | PM_WKEN); | 386 | PM_WKEN); |
@@ -393,7 +398,7 @@ void omap3430_pre_es3_1_reconfigure_io_chain(void) | |||
393 | * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No | 398 | * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No |
394 | * return value. These registers are only available in 3430 es3.1 and later. | 399 | * return value. These registers are only available in 3430 es3.1 and later. |
395 | */ | 400 | */ |
396 | void omap3_prm_reconfigure_io_chain(void) | 401 | static void omap3_prm_reconfigure_io_chain(void) |
397 | { | 402 | { |
398 | int i = 0; | 403 | int i = 0; |
399 | 404 | ||
@@ -416,15 +421,6 @@ void omap3_prm_reconfigure_io_chain(void) | |||
416 | } | 421 | } |
417 | 422 | ||
418 | /** | 423 | /** |
419 | * omap3xxx_prm_reconfigure_io_chain - reconfigure I/O chain | ||
420 | */ | ||
421 | void omap3xxx_prm_reconfigure_io_chain(void) | ||
422 | { | ||
423 | if (omap3_prcm_irq_setup.reconfigure_io_chain) | ||
424 | omap3_prcm_irq_setup.reconfigure_io_chain(); | ||
425 | } | ||
426 | |||
427 | /** | ||
428 | * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches | 424 | * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches |
429 | * | 425 | * |
430 | * Activates the I/O wakeup event latches and allows events logged by | 426 | * Activates the I/O wakeup event latches and allows events logged by |
@@ -664,6 +660,10 @@ static int omap3xxx_prm_late_init(void); | |||
664 | static struct prm_ll_data omap3xxx_prm_ll_data = { | 660 | static struct prm_ll_data omap3xxx_prm_ll_data = { |
665 | .read_reset_sources = &omap3xxx_prm_read_reset_sources, | 661 | .read_reset_sources = &omap3xxx_prm_read_reset_sources, |
666 | .late_init = &omap3xxx_prm_late_init, | 662 | .late_init = &omap3xxx_prm_late_init, |
663 | .assert_hardreset = &omap2_prm_assert_hardreset, | ||
664 | .deassert_hardreset = &omap2_prm_deassert_hardreset, | ||
665 | .is_hardreset_asserted = &omap2_prm_is_hardreset_asserted, | ||
666 | .reset_system = &omap3xxx_prm_dpll3_reset, | ||
667 | }; | 667 | }; |
668 | 668 | ||
669 | int __init omap3xxx_prm_init(void) | 669 | int __init omap3xxx_prm_init(void) |
diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h index bc37d42a8704..cfde3f4a03cc 100644 --- a/arch/arm/mach-omap2/prm3xxx.h +++ b/arch/arm/mach-omap2/prm3xxx.h | |||
@@ -144,22 +144,6 @@ extern u32 omap3_prm_vcvp_read(u8 offset); | |||
144 | extern void omap3_prm_vcvp_write(u32 val, u8 offset); | 144 | extern void omap3_prm_vcvp_write(u32 val, u8 offset); |
145 | extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); | 145 | extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); |
146 | 146 | ||
147 | #ifdef CONFIG_ARCH_OMAP3 | ||
148 | void omap3xxx_prm_reconfigure_io_chain(void); | ||
149 | #else | ||
150 | static inline void omap3xxx_prm_reconfigure_io_chain(void) | ||
151 | { | ||
152 | } | ||
153 | #endif | ||
154 | |||
155 | /* PRM interrupt-related functions */ | ||
156 | extern void omap3xxx_prm_read_pending_irqs(unsigned long *events); | ||
157 | extern void omap3xxx_prm_ocp_barrier(void); | ||
158 | extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask); | ||
159 | extern void omap3xxx_prm_restore_irqen(u32 *saved_mask); | ||
160 | |||
161 | extern void omap3xxx_prm_dpll3_reset(void); | ||
162 | |||
163 | extern int __init omap3xxx_prm_init(void); | 147 | extern int __init omap3xxx_prm_init(void); |
164 | extern u32 omap3xxx_prm_get_reset_sources(void); | 148 | extern u32 omap3xxx_prm_get_reset_sources(void); |
165 | int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits); | 149 | int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits); |
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index 0958d070d3db..cc170fb81ff7 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c | |||
@@ -32,6 +32,12 @@ | |||
32 | 32 | ||
33 | /* Static data */ | 33 | /* Static data */ |
34 | 34 | ||
35 | static void omap44xx_prm_read_pending_irqs(unsigned long *events); | ||
36 | static void omap44xx_prm_ocp_barrier(void); | ||
37 | static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); | ||
38 | static void omap44xx_prm_restore_irqen(u32 *saved_mask); | ||
39 | static void omap44xx_prm_reconfigure_io_chain(void); | ||
40 | |||
35 | static const struct omap_prcm_irq omap4_prcm_irqs[] = { | 41 | static const struct omap_prcm_irq omap4_prcm_irqs[] = { |
36 | OMAP_PRCM_IRQ("io", 9, 1), | 42 | OMAP_PRCM_IRQ("io", 9, 1), |
37 | }; | 43 | }; |
@@ -80,19 +86,19 @@ static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = { | |||
80 | /* PRM low-level functions */ | 86 | /* PRM low-level functions */ |
81 | 87 | ||
82 | /* Read a register in a CM/PRM instance in the PRM module */ | 88 | /* Read a register in a CM/PRM instance in the PRM module */ |
83 | u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) | 89 | static u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) |
84 | { | 90 | { |
85 | return readl_relaxed(prm_base + inst + reg); | 91 | return readl_relaxed(prm_base + inst + reg); |
86 | } | 92 | } |
87 | 93 | ||
88 | /* Write into a register in a CM/PRM instance in the PRM module */ | 94 | /* Write into a register in a CM/PRM instance in the PRM module */ |
89 | void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg) | 95 | static void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg) |
90 | { | 96 | { |
91 | writel_relaxed(val, prm_base + inst + reg); | 97 | writel_relaxed(val, prm_base + inst + reg); |
92 | } | 98 | } |
93 | 99 | ||
94 | /* Read-modify-write a register in a PRM module. Caller must lock */ | 100 | /* Read-modify-write a register in a PRM module. Caller must lock */ |
95 | u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) | 101 | static u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) |
96 | { | 102 | { |
97 | u32 v; | 103 | u32 v; |
98 | 104 | ||
@@ -207,7 +213,7 @@ static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs) | |||
207 | * MPU IRQs, and store the result into the two u32s pointed to by @events. | 213 | * MPU IRQs, and store the result into the two u32s pointed to by @events. |
208 | * No return value. | 214 | * No return value. |
209 | */ | 215 | */ |
210 | void omap44xx_prm_read_pending_irqs(unsigned long *events) | 216 | static void omap44xx_prm_read_pending_irqs(unsigned long *events) |
211 | { | 217 | { |
212 | events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET, | 218 | events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET, |
213 | OMAP4_PRM_IRQSTATUS_MPU_OFFSET); | 219 | OMAP4_PRM_IRQSTATUS_MPU_OFFSET); |
@@ -224,7 +230,7 @@ void omap44xx_prm_read_pending_irqs(unsigned long *events) | |||
224 | * block, to avoid race conditions after acknowledging or clearing IRQ | 230 | * block, to avoid race conditions after acknowledging or clearing IRQ |
225 | * bits. No return value. | 231 | * bits. No return value. |
226 | */ | 232 | */ |
227 | void omap44xx_prm_ocp_barrier(void) | 233 | static void omap44xx_prm_ocp_barrier(void) |
228 | { | 234 | { |
229 | omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, | 235 | omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, |
230 | OMAP4_REVISION_PRM_OFFSET); | 236 | OMAP4_REVISION_PRM_OFFSET); |
@@ -241,7 +247,7 @@ void omap44xx_prm_ocp_barrier(void) | |||
241 | * interrupts reaches the PRM before returning; otherwise, spurious | 247 | * interrupts reaches the PRM before returning; otherwise, spurious |
242 | * interrupts might occur. No return value. | 248 | * interrupts might occur. No return value. |
243 | */ | 249 | */ |
244 | void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) | 250 | static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) |
245 | { | 251 | { |
246 | saved_mask[0] = | 252 | saved_mask[0] = |
247 | omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, | 253 | omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, |
@@ -270,7 +276,7 @@ void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) | |||
270 | * No OCP barrier should be needed here; any pending PRM interrupts will fire | 276 | * No OCP barrier should be needed here; any pending PRM interrupts will fire |
271 | * once the writes reach the PRM. No return value. | 277 | * once the writes reach the PRM. No return value. |
272 | */ | 278 | */ |
273 | void omap44xx_prm_restore_irqen(u32 *saved_mask) | 279 | static void omap44xx_prm_restore_irqen(u32 *saved_mask) |
274 | { | 280 | { |
275 | omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_OCP_SOCKET_INST, | 281 | omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_OCP_SOCKET_INST, |
276 | OMAP4_PRM_IRQENABLE_MPU_OFFSET); | 282 | OMAP4_PRM_IRQENABLE_MPU_OFFSET); |
@@ -287,7 +293,7 @@ void omap44xx_prm_restore_irqen(u32 *saved_mask) | |||
287 | * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted. | 293 | * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted. |
288 | * No return value. XXX Are the final two steps necessary? | 294 | * No return value. XXX Are the final two steps necessary? |
289 | */ | 295 | */ |
290 | void omap44xx_prm_reconfigure_io_chain(void) | 296 | static void omap44xx_prm_reconfigure_io_chain(void) |
291 | { | 297 | { |
292 | int i = 0; | 298 | int i = 0; |
293 | s32 inst = omap4_prmst_get_prm_dev_inst(); | 299 | s32 inst = omap4_prmst_get_prm_dev_inst(); |
@@ -652,11 +658,10 @@ static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) | |||
652 | 658 | ||
653 | static int omap4_check_vcvp(void) | 659 | static int omap4_check_vcvp(void) |
654 | { | 660 | { |
655 | /* No VC/VP on dra7xx devices */ | 661 | if (prm_features & PRM_HAS_VOLTAGE) |
656 | if (soc_is_dra7xx()) | 662 | return 1; |
657 | return 0; | ||
658 | 663 | ||
659 | return 1; | 664 | return 0; |
660 | } | 665 | } |
661 | 666 | ||
662 | struct pwrdm_ops omap4_pwrdm_operations = { | 667 | struct pwrdm_ops omap4_pwrdm_operations = { |
@@ -689,6 +694,10 @@ static struct prm_ll_data omap44xx_prm_ll_data = { | |||
689 | .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old, | 694 | .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old, |
690 | .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old, | 695 | .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old, |
691 | .late_init = &omap44xx_prm_late_init, | 696 | .late_init = &omap44xx_prm_late_init, |
697 | .assert_hardreset = omap4_prminst_assert_hardreset, | ||
698 | .deassert_hardreset = omap4_prminst_deassert_hardreset, | ||
699 | .is_hardreset_asserted = omap4_prminst_is_hardreset_asserted, | ||
700 | .reset_system = omap4_prminst_global_warm_sw_reset, | ||
692 | }; | 701 | }; |
693 | 702 | ||
694 | int __init omap44xx_prm_init(void) | 703 | int __init omap44xx_prm_init(void) |
@@ -696,6 +705,9 @@ int __init omap44xx_prm_init(void) | |||
696 | if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) | 705 | if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) |
697 | prm_features |= PRM_HAS_IO_WAKEUP; | 706 | prm_features |= PRM_HAS_IO_WAKEUP; |
698 | 707 | ||
708 | if (!soc_is_dra7xx()) | ||
709 | prm_features |= PRM_HAS_VOLTAGE; | ||
710 | |||
699 | return prm_register(&omap44xx_prm_ll_data); | 711 | return prm_register(&omap44xx_prm_ll_data); |
700 | } | 712 | } |
701 | 713 | ||
diff --git a/arch/arm/mach-omap2/prm44xx_54xx.h b/arch/arm/mach-omap2/prm44xx_54xx.h index 8d95aa543ef5..f7512515fde5 100644 --- a/arch/arm/mach-omap2/prm44xx_54xx.h +++ b/arch/arm/mach-omap2/prm44xx_54xx.h | |||
@@ -26,10 +26,6 @@ | |||
26 | /* Function prototypes */ | 26 | /* Function prototypes */ |
27 | #ifndef __ASSEMBLER__ | 27 | #ifndef __ASSEMBLER__ |
28 | 28 | ||
29 | extern u32 omap4_prm_read_inst_reg(s16 inst, u16 idx); | ||
30 | extern void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 idx); | ||
31 | extern u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); | ||
32 | |||
33 | /* OMAP4/OMAP5-specific VP functions */ | 29 | /* OMAP4/OMAP5-specific VP functions */ |
34 | u32 omap4_prm_vp_check_txdone(u8 vp_id); | 30 | u32 omap4_prm_vp_check_txdone(u8 vp_id); |
35 | void omap4_prm_vp_clear_txdone(u8 vp_id); | 31 | void omap4_prm_vp_clear_txdone(u8 vp_id); |
@@ -42,21 +38,6 @@ extern u32 omap4_prm_vcvp_read(u8 offset); | |||
42 | extern void omap4_prm_vcvp_write(u32 val, u8 offset); | 38 | extern void omap4_prm_vcvp_write(u32 val, u8 offset); |
43 | extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); | 39 | extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); |
44 | 40 | ||
45 | #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ | ||
46 | defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX) | ||
47 | void omap44xx_prm_reconfigure_io_chain(void); | ||
48 | #else | ||
49 | static inline void omap44xx_prm_reconfigure_io_chain(void) | ||
50 | { | ||
51 | } | ||
52 | #endif | ||
53 | |||
54 | /* PRM interrupt-related functions */ | ||
55 | extern void omap44xx_prm_read_pending_irqs(unsigned long *events); | ||
56 | extern void omap44xx_prm_ocp_barrier(void); | ||
57 | extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); | ||
58 | extern void omap44xx_prm_restore_irqen(u32 *saved_mask); | ||
59 | |||
60 | extern int __init omap44xx_prm_init(void); | 41 | extern int __init omap44xx_prm_init(void); |
61 | extern u32 omap44xx_prm_get_reset_sources(void); | 42 | extern u32 omap44xx_prm_get_reset_sources(void); |
62 | 43 | ||
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index ee2b5222eac0..779940cb6e56 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c | |||
@@ -423,6 +423,105 @@ void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx) | |||
423 | } | 423 | } |
424 | 424 | ||
425 | /** | 425 | /** |
426 | * omap_prm_assert_hardreset - assert hardreset for an IP block | ||
427 | * @shift: register bit shift corresponding to the reset line | ||
428 | * @part: PRM partition | ||
429 | * @prm_mod: PRM submodule base or instance offset | ||
430 | * @offset: register offset | ||
431 | * | ||
432 | * Asserts a hardware reset line for an IP block. | ||
433 | */ | ||
434 | int omap_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset) | ||
435 | { | ||
436 | if (!prm_ll_data->assert_hardreset) { | ||
437 | WARN_ONCE(1, "prm: %s: no mapping function defined\n", | ||
438 | __func__); | ||
439 | return -EINVAL; | ||
440 | } | ||
441 | |||
442 | return prm_ll_data->assert_hardreset(shift, part, prm_mod, offset); | ||
443 | } | ||
444 | |||
445 | /** | ||
446 | * omap_prm_deassert_hardreset - deassert hardreset for an IP block | ||
447 | * @shift: register bit shift corresponding to the reset line | ||
448 | * @st_shift: reset status bit shift corresponding to the reset line | ||
449 | * @part: PRM partition | ||
450 | * @prm_mod: PRM submodule base or instance offset | ||
451 | * @offset: register offset | ||
452 | * @st_offset: status register offset | ||
453 | * | ||
454 | * Deasserts a hardware reset line for an IP block. | ||
455 | */ | ||
456 | int omap_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 prm_mod, | ||
457 | u16 offset, u16 st_offset) | ||
458 | { | ||
459 | if (!prm_ll_data->deassert_hardreset) { | ||
460 | WARN_ONCE(1, "prm: %s: no mapping function defined\n", | ||
461 | __func__); | ||
462 | return -EINVAL; | ||
463 | } | ||
464 | |||
465 | return prm_ll_data->deassert_hardreset(shift, st_shift, part, prm_mod, | ||
466 | offset, st_offset); | ||
467 | } | ||
468 | |||
469 | /** | ||
470 | * omap_prm_is_hardreset_asserted - check the hardreset status for an IP block | ||
471 | * @shift: register bit shift corresponding to the reset line | ||
472 | * @part: PRM partition | ||
473 | * @prm_mod: PRM submodule base or instance offset | ||
474 | * @offset: register offset | ||
475 | * | ||
476 | * Checks if a hardware reset line for an IP block is enabled or not. | ||
477 | */ | ||
478 | int omap_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset) | ||
479 | { | ||
480 | if (!prm_ll_data->is_hardreset_asserted) { | ||
481 | WARN_ONCE(1, "prm: %s: no mapping function defined\n", | ||
482 | __func__); | ||
483 | return -EINVAL; | ||
484 | } | ||
485 | |||
486 | return prm_ll_data->is_hardreset_asserted(shift, part, prm_mod, offset); | ||
487 | } | ||
488 | |||
489 | /** | ||
490 | * omap_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain | ||
491 | * | ||
492 | * Clear any previously-latched I/O wakeup events and ensure that the | ||
493 | * I/O wakeup gates are aligned with the current mux settings. | ||
494 | * Calls SoC specific I/O chain reconfigure function if available, | ||
495 | * otherwise does nothing. | ||
496 | */ | ||
497 | void omap_prm_reconfigure_io_chain(void) | ||
498 | { | ||
499 | if (!prcm_irq_setup || !prcm_irq_setup->reconfigure_io_chain) | ||
500 | return; | ||
501 | |||
502 | prcm_irq_setup->reconfigure_io_chain(); | ||
503 | } | ||
504 | |||
505 | /** | ||
506 | * omap_prm_reset_system - trigger global SW reset | ||
507 | * | ||
508 | * Triggers SoC specific global warm reset to reboot the device. | ||
509 | */ | ||
510 | void omap_prm_reset_system(void) | ||
511 | { | ||
512 | if (!prm_ll_data->reset_system) { | ||
513 | WARN_ONCE(1, "prm: %s: no mapping function defined\n", | ||
514 | __func__); | ||
515 | return; | ||
516 | } | ||
517 | |||
518 | prm_ll_data->reset_system(); | ||
519 | |||
520 | while (1) | ||
521 | cpu_relax(); | ||
522 | } | ||
523 | |||
524 | /** | ||
426 | * prm_register - register per-SoC low-level data with the PRM | 525 | * prm_register - register per-SoC low-level data with the PRM |
427 | * @pld: low-level per-SoC OMAP PRM data & function pointers to register | 526 | * @pld: low-level per-SoC OMAP PRM data & function pointers to register |
428 | * | 527 | * |
diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c index 225e0258d76d..8adf7b1a1dce 100644 --- a/arch/arm/mach-omap2/prminst44xx.c +++ b/arch/arm/mach-omap2/prminst44xx.c | |||
@@ -148,8 +148,12 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, | |||
148 | /** | 148 | /** |
149 | * omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and | 149 | * omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and |
150 | * wait | 150 | * wait |
151 | * @rstctrl_reg: RM_RSTCTRL register address for this module | ||
152 | * @shift: register bit shift corresponding to the reset line to deassert | 151 | * @shift: register bit shift corresponding to the reset line to deassert |
152 | * @st_shift: status bit offset, not used for OMAP4+ | ||
153 | * @part: PRM partition | ||
154 | * @inst: PRM instance offset | ||
155 | * @rstctrl_offs: reset register offset | ||
156 | * @st_offs: reset status register offset, not used for OMAP4+ | ||
153 | * | 157 | * |
154 | * Some IPs like dsp, ipu or iva contain processors that require an HW | 158 | * Some IPs like dsp, ipu or iva contain processors that require an HW |
155 | * reset line to be asserted / deasserted in order to fully enable the | 159 | * reset line to be asserted / deasserted in order to fully enable the |
@@ -160,8 +164,8 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, | |||
160 | * -EINVAL upon an argument error, -EEXIST if the submodule was already out | 164 | * -EINVAL upon an argument error, -EEXIST if the submodule was already out |
161 | * of reset, or -EBUSY if the submodule did not exit reset promptly. | 165 | * of reset, or -EBUSY if the submodule did not exit reset promptly. |
162 | */ | 166 | */ |
163 | int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst, | 167 | int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst, |
164 | u16 rstctrl_offs) | 168 | u16 rstctrl_offs, u16 st_offs) |
165 | { | 169 | { |
166 | int c; | 170 | int c; |
167 | u32 mask = 1 << shift; | 171 | u32 mask = 1 << shift; |
diff --git a/arch/arm/mach-omap2/prminst44xx.h b/arch/arm/mach-omap2/prminst44xx.h index 583aa3774571..fb1c9d7a2f9d 100644 --- a/arch/arm/mach-omap2/prminst44xx.h +++ b/arch/arm/mach-omap2/prminst44xx.h | |||
@@ -30,8 +30,9 @@ extern int omap4_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst, | |||
30 | u16 rstctrl_offs); | 30 | u16 rstctrl_offs); |
31 | extern int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, | 31 | extern int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, |
32 | u16 rstctrl_offs); | 32 | u16 rstctrl_offs); |
33 | extern int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst, | 33 | int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, |
34 | u16 rstctrl_offs); | 34 | s16 inst, u16 rstctrl_offs, |
35 | u16 rstst_offs); | ||
35 | 36 | ||
36 | extern void omap_prm_base_init(void); | 37 | extern void omap_prm_base_init(void); |
37 | 38 | ||
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index e6690a44917d..83efe914bf7d 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig | |||
@@ -4,6 +4,17 @@ menu "Intel PXA2xx/PXA3xx Implementations" | |||
4 | 4 | ||
5 | comment "Intel/Marvell Dev Platforms (sorted by hardware release time)" | 5 | comment "Intel/Marvell Dev Platforms (sorted by hardware release time)" |
6 | 6 | ||
7 | config MACH_PXA27X_DT | ||
8 | bool "Support PXA27x platforms from device tree" | ||
9 | select CPU_PXA27x | ||
10 | select POWER_SUPPLY | ||
11 | select PXA27x | ||
12 | select USE_OF | ||
13 | help | ||
14 | Include support for Marvell PXA27x based platforms using | ||
15 | the device tree. Needn't select any other machine while | ||
16 | MACH_PXA27X_DT is enabled. | ||
17 | |||
7 | config MACH_PXA3XX_DT | 18 | config MACH_PXA3XX_DT |
8 | bool "Support PXA3xx platforms from device tree" | 19 | bool "Support PXA3xx platforms from device tree" |
9 | select CPU_PXA300 | 20 | select CPU_PXA300 |
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 2fe1824c6dcb..eb0bf7678a99 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile | |||
@@ -21,6 +21,7 @@ obj-$(CONFIG_CPU_PXA930) += pxa930.o | |||
21 | 21 | ||
22 | # Device Tree support | 22 | # Device Tree support |
23 | obj-$(CONFIG_MACH_PXA3XX_DT) += pxa-dt.o | 23 | obj-$(CONFIG_MACH_PXA3XX_DT) += pxa-dt.o |
24 | obj-$(CONFIG_MACH_PXA27X_DT) += pxa-dt.o | ||
24 | 25 | ||
25 | # Intel/Marvell Dev Platforms | 26 | # Intel/Marvell Dev Platforms |
26 | obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o | 27 | obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o |
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 6915a9f6b3a3..51531ecffca8 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c | |||
@@ -378,7 +378,7 @@ static void __init em_x270_init_nand(void) | |||
378 | 378 | ||
379 | err = gpio_request(GPIO11_NAND_CS, "NAND CS"); | 379 | err = gpio_request(GPIO11_NAND_CS, "NAND CS"); |
380 | if (err) { | 380 | if (err) { |
381 | pr_warning("EM-X270: failed to request NAND CS gpio\n"); | 381 | pr_warn("EM-X270: failed to request NAND CS gpio\n"); |
382 | return; | 382 | return; |
383 | } | 383 | } |
384 | 384 | ||
@@ -386,7 +386,7 @@ static void __init em_x270_init_nand(void) | |||
386 | 386 | ||
387 | err = gpio_request(nand_rb, "NAND R/B"); | 387 | err = gpio_request(nand_rb, "NAND R/B"); |
388 | if (err) { | 388 | if (err) { |
389 | pr_warning("EM-X270: failed to request NAND R/B gpio\n"); | 389 | pr_warn("EM-X270: failed to request NAND R/B gpio\n"); |
390 | gpio_free(GPIO11_NAND_CS); | 390 | gpio_free(GPIO11_NAND_CS); |
391 | return; | 391 | return; |
392 | } | 392 | } |
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index 8963984d1f43..7a9fa1aa4e41 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h | |||
@@ -13,11 +13,11 @@ | |||
13 | 13 | ||
14 | struct irq_data; | 14 | struct irq_data; |
15 | 15 | ||
16 | extern void pxa_timer_init(void); | ||
17 | |||
18 | extern void __init pxa_map_io(void); | ||
19 | |||
20 | extern unsigned int get_clk_frequency_khz(int info); | 16 | extern unsigned int get_clk_frequency_khz(int info); |
17 | extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, | ||
18 | unsigned int)); | ||
19 | extern void __init pxa_map_io(void); | ||
20 | extern void pxa_timer_init(void); | ||
21 | 21 | ||
22 | #define SET_BANK(__nr,__start,__size) \ | 22 | #define SET_BANK(__nr,__start,__size) \ |
23 | mi->bank[__nr].start = (__start), \ | 23 | mi->bank[__nr].start = (__start), \ |
@@ -25,6 +25,43 @@ extern unsigned int get_clk_frequency_khz(int info); | |||
25 | 25 | ||
26 | #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) | 26 | #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) |
27 | 27 | ||
28 | #define pxa25x_handle_irq icip_handle_irq | ||
29 | extern void __init pxa25x_init_irq(void); | ||
30 | extern void __init pxa25x_map_io(void); | ||
31 | extern void __init pxa26x_init_irq(void); | ||
32 | |||
33 | #define pxa27x_handle_irq ichp_handle_irq | ||
34 | extern void __init pxa27x_dt_init_irq(void); | ||
35 | extern unsigned pxa27x_get_clk_frequency_khz(int); | ||
36 | extern void __init pxa27x_init_irq(void); | ||
37 | extern void __init pxa27x_map_io(void); | ||
38 | |||
39 | #define pxa3xx_handle_irq ichp_handle_irq | ||
40 | extern void __init pxa3xx_dt_init_irq(void); | ||
41 | extern void __init pxa3xx_init_irq(void); | ||
42 | extern void __init pxa3xx_map_io(void); | ||
43 | |||
44 | extern struct syscore_ops pxa_irq_syscore_ops; | ||
45 | extern struct syscore_ops pxa2xx_mfp_syscore_ops; | ||
46 | extern struct syscore_ops pxa3xx_mfp_syscore_ops; | ||
47 | |||
48 | void __init pxa_set_ffuart_info(void *info); | ||
49 | void __init pxa_set_btuart_info(void *info); | ||
50 | void __init pxa_set_stuart_info(void *info); | ||
51 | void __init pxa_set_hwuart_info(void *info); | ||
52 | |||
53 | void pxa_restart(enum reboot_mode, const char *); | ||
54 | |||
55 | #if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) | ||
56 | extern void pxa2xx_clear_reset_status(unsigned int); | ||
57 | #else | ||
58 | static inline void pxa2xx_clear_reset_status(unsigned int mask) {} | ||
59 | #endif | ||
60 | |||
61 | /* | ||
62 | * Once fully converted to the clock framework, all these functions should be | ||
63 | * removed, and replaced with a clk_get(NULL, "core"). | ||
64 | */ | ||
28 | #ifdef CONFIG_PXA25x | 65 | #ifdef CONFIG_PXA25x |
29 | extern unsigned pxa25x_get_clk_frequency_khz(int); | 66 | extern unsigned pxa25x_get_clk_frequency_khz(int); |
30 | #else | 67 | #else |
@@ -32,30 +69,12 @@ extern unsigned pxa25x_get_clk_frequency_khz(int); | |||
32 | #endif | 69 | #endif |
33 | 70 | ||
34 | #ifdef CONFIG_PXA27x | 71 | #ifdef CONFIG_PXA27x |
35 | extern unsigned pxa27x_get_clk_frequency_khz(int); | ||
36 | #else | 72 | #else |
37 | #define pxa27x_get_clk_frequency_khz(x) (0) | 73 | #define pxa27x_get_clk_frequency_khz(x) (0) |
38 | #endif | 74 | #endif |
39 | 75 | ||
40 | #if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) | ||
41 | extern void pxa2xx_clear_reset_status(unsigned int); | ||
42 | #else | ||
43 | static inline void pxa2xx_clear_reset_status(unsigned int mask) {} | ||
44 | #endif | ||
45 | |||
46 | #ifdef CONFIG_PXA3xx | 76 | #ifdef CONFIG_PXA3xx |
47 | extern unsigned pxa3xx_get_clk_frequency_khz(int); | 77 | extern unsigned pxa3xx_get_clk_frequency_khz(int); |
48 | #else | 78 | #else |
49 | #define pxa3xx_get_clk_frequency_khz(x) (0) | 79 | #define pxa3xx_get_clk_frequency_khz(x) (0) |
50 | #endif | 80 | #endif |
51 | |||
52 | extern struct syscore_ops pxa_irq_syscore_ops; | ||
53 | extern struct syscore_ops pxa2xx_mfp_syscore_ops; | ||
54 | extern struct syscore_ops pxa3xx_mfp_syscore_ops; | ||
55 | |||
56 | void __init pxa_set_ffuart_info(void *info); | ||
57 | void __init pxa_set_btuart_info(void *info); | ||
58 | void __init pxa_set_stuart_info(void *info); | ||
59 | void __init pxa_set_hwuart_info(void *info); | ||
60 | |||
61 | void pxa_restart(enum reboot_mode, const char *); | ||
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index 00b92dad7b81..f6c76a3ee3b2 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c | |||
@@ -140,8 +140,7 @@ static void gumstix_setup_bt_clock(void) | |||
140 | int timeout = 500; | 140 | int timeout = 500; |
141 | 141 | ||
142 | if (!(OSCC & OSCC_OOK)) | 142 | if (!(OSCC & OSCC_OOK)) |
143 | pr_warning("32kHz clock was not on. Bootloader may need to " | 143 | pr_warn("32kHz clock was not on. Bootloader may need to be updated\n"); |
144 | "be updated\n"); | ||
145 | else | 144 | else |
146 | return; | 145 | return; |
147 | 146 | ||
diff --git a/arch/arm/mach-pxa/include/mach/pxa25x.h b/arch/arm/mach-pxa/include/mach/pxa25x.h index 3ac0baac7350..5a341752e32c 100644 --- a/arch/arm/mach-pxa/include/mach/pxa25x.h +++ b/arch/arm/mach-pxa/include/mach/pxa25x.h | |||
@@ -6,12 +6,4 @@ | |||
6 | #include <mach/mfp-pxa25x.h> | 6 | #include <mach/mfp-pxa25x.h> |
7 | #include <mach/irqs.h> | 7 | #include <mach/irqs.h> |
8 | 8 | ||
9 | extern void __init pxa25x_map_io(void); | ||
10 | extern void __init pxa25x_init_irq(void); | ||
11 | #ifdef CONFIG_CPU_PXA26x | ||
12 | extern void __init pxa26x_init_irq(void); | ||
13 | #endif | ||
14 | |||
15 | #define pxa25x_handle_irq icip_handle_irq | ||
16 | |||
17 | #endif /* __MACH_PXA25x_H */ | 9 | #endif /* __MACH_PXA25x_H */ |
diff --git a/arch/arm/mach-pxa/include/mach/pxa27x.h b/arch/arm/mach-pxa/include/mach/pxa27x.h index 7cff640582b8..599b925a657c 100644 --- a/arch/arm/mach-pxa/include/mach/pxa27x.h +++ b/arch/arm/mach-pxa/include/mach/pxa27x.h | |||
@@ -19,11 +19,7 @@ | |||
19 | #define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */ | 19 | #define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */ |
20 | #define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */ | 20 | #define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */ |
21 | 21 | ||
22 | extern void __init pxa27x_map_io(void); | ||
23 | extern void __init pxa27x_init_irq(void); | ||
24 | extern int __init pxa27x_set_pwrmode(unsigned int mode); | 22 | extern int __init pxa27x_set_pwrmode(unsigned int mode); |
25 | extern void pxa27x_cpu_pm_enter(suspend_state_t state); | 23 | extern void pxa27x_cpu_pm_enter(suspend_state_t state); |
26 | 24 | ||
27 | #define pxa27x_handle_irq ichp_handle_irq | ||
28 | |||
29 | #endif /* __MACH_PXA27x_H */ | 25 | #endif /* __MACH_PXA27x_H */ |
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx.h b/arch/arm/mach-pxa/include/mach/pxa3xx.h index 6dd7fa163e29..b4143fb6631f 100644 --- a/arch/arm/mach-pxa/include/mach/pxa3xx.h +++ b/arch/arm/mach-pxa/include/mach/pxa3xx.h | |||
@@ -5,9 +5,4 @@ | |||
5 | #include <mach/pxa3xx-regs.h> | 5 | #include <mach/pxa3xx-regs.h> |
6 | #include <mach/irqs.h> | 6 | #include <mach/irqs.h> |
7 | 7 | ||
8 | extern void __init pxa3xx_map_io(void); | ||
9 | extern void __init pxa3xx_init_irq(void); | ||
10 | |||
11 | #define pxa3xx_handle_irq ichp_handle_irq | ||
12 | |||
13 | #endif /* __MACH_PXA3XX_H */ | 8 | #endif /* __MACH_PXA3XX_H */ |
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index ef0426a159d4..666b78972c40 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c | |||
@@ -93,8 +93,8 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) | |||
93 | break; | 93 | break; |
94 | default: | 94 | default: |
95 | /* warning and fall through, treat as MFP_LPM_DEFAULT */ | 95 | /* warning and fall through, treat as MFP_LPM_DEFAULT */ |
96 | pr_warning("%s: GPIO%d: unsupported low power mode\n", | 96 | pr_warn("%s: GPIO%d: unsupported low power mode\n", |
97 | __func__, gpio); | 97 | __func__, gpio); |
98 | break; | 98 | break; |
99 | } | 99 | } |
100 | 100 | ||
@@ -107,14 +107,12 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) | |||
107 | * configurations of those pins not able to wakeup | 107 | * configurations of those pins not able to wakeup |
108 | */ | 108 | */ |
109 | if ((c & MFP_LPM_CAN_WAKEUP) && !gpio_desc[gpio].can_wakeup) { | 109 | if ((c & MFP_LPM_CAN_WAKEUP) && !gpio_desc[gpio].can_wakeup) { |
110 | pr_warning("%s: GPIO%d unable to wakeup\n", | 110 | pr_warn("%s: GPIO%d unable to wakeup\n", __func__, gpio); |
111 | __func__, gpio); | ||
112 | return -EINVAL; | 111 | return -EINVAL; |
113 | } | 112 | } |
114 | 113 | ||
115 | if ((c & MFP_LPM_CAN_WAKEUP) && is_out) { | 114 | if ((c & MFP_LPM_CAN_WAKEUP) && is_out) { |
116 | pr_warning("%s: output GPIO%d unable to wakeup\n", | 115 | pr_warn("%s: output GPIO%d unable to wakeup\n", __func__, gpio); |
117 | __func__, gpio); | ||
118 | return -EINVAL; | 116 | return -EINVAL; |
119 | } | 117 | } |
120 | 118 | ||
@@ -126,7 +124,7 @@ static inline int __mfp_validate(int mfp) | |||
126 | int gpio = mfp_to_gpio(mfp); | 124 | int gpio = mfp_to_gpio(mfp); |
127 | 125 | ||
128 | if ((mfp > MFP_PIN_GPIO127) || !gpio_desc[gpio].valid) { | 126 | if ((mfp > MFP_PIN_GPIO127) || !gpio_desc[gpio].valid) { |
129 | pr_warning("%s: GPIO%d is invalid pin\n", __func__, gpio); | 127 | pr_warn("%s: GPIO%d is invalid pin\n", __func__, gpio); |
130 | return -1; | 128 | return -1; |
131 | } | 129 | } |
132 | 130 | ||
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 131991629116..29019beae591 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c | |||
@@ -446,7 +446,7 @@ static void __init poodle_init(void) | |||
446 | 446 | ||
447 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); | 447 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); |
448 | if (ret) | 448 | if (ret) |
449 | pr_warning("poodle: Unable to register LoCoMo device\n"); | 449 | pr_warn("poodle: Unable to register LoCoMo device\n"); |
450 | 450 | ||
451 | pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info); | 451 | pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info); |
452 | pxa_set_udc_info(&udc_info); | 452 | pxa_set_udc_info(&udc_info); |
diff --git a/arch/arm/mach-pxa/pxa-dt.c b/arch/arm/mach-pxa/pxa-dt.c index f6a2c4b1c1dc..7e0e5bd0c9de 100644 --- a/arch/arm/mach-pxa/pxa-dt.c +++ b/arch/arm/mach-pxa/pxa-dt.c | |||
@@ -15,13 +15,10 @@ | |||
15 | #include <asm/mach/arch.h> | 15 | #include <asm/mach/arch.h> |
16 | #include <asm/mach/time.h> | 16 | #include <asm/mach/time.h> |
17 | #include <mach/irqs.h> | 17 | #include <mach/irqs.h> |
18 | #include <mach/pxa3xx.h> | ||
19 | 18 | ||
20 | #include "generic.h" | 19 | #include "generic.h" |
21 | 20 | ||
22 | #ifdef CONFIG_PXA3xx | 21 | #ifdef CONFIG_PXA3xx |
23 | extern void __init pxa3xx_dt_init_irq(void); | ||
24 | |||
25 | static const struct of_dev_auxdata pxa3xx_auxdata_lookup[] __initconst = { | 22 | static const struct of_dev_auxdata pxa3xx_auxdata_lookup[] __initconst = { |
26 | OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL), | 23 | OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL), |
27 | OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL), | 24 | OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL), |
@@ -61,3 +58,18 @@ DT_MACHINE_START(PXA_DT, "Marvell PXA3xx (Device Tree Support)") | |||
61 | .dt_compat = pxa3xx_dt_board_compat, | 58 | .dt_compat = pxa3xx_dt_board_compat, |
62 | MACHINE_END | 59 | MACHINE_END |
63 | #endif | 60 | #endif |
61 | |||
62 | #ifdef CONFIG_PXA27x | ||
63 | static const char * const pxa27x_dt_board_compat[] __initconst = { | ||
64 | "marvell,pxa270", | ||
65 | NULL, | ||
66 | }; | ||
67 | |||
68 | DT_MACHINE_START(PXA27X_DT, "Marvell PXA2xx (Device Tree Support)") | ||
69 | .map_io = pxa27x_map_io, | ||
70 | .init_irq = pxa27x_dt_init_irq, | ||
71 | .handle_irq = pxa27x_handle_irq, | ||
72 | .restart = pxa_restart, | ||
73 | .dt_compat = pxa27x_dt_board_compat, | ||
74 | MACHINE_END | ||
75 | #endif | ||
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index b040d7d14888..af423a48c2e3 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
@@ -398,6 +398,12 @@ void __init pxa27x_init_irq(void) | |||
398 | pxa_init_irq(34, pxa27x_set_wake); | 398 | pxa_init_irq(34, pxa27x_set_wake); |
399 | } | 399 | } |
400 | 400 | ||
401 | void __init pxa27x_dt_init_irq(void) | ||
402 | { | ||
403 | if (IS_ENABLED(CONFIG_OF)) | ||
404 | pxa_dt_irq_init(pxa27x_set_wake); | ||
405 | } | ||
406 | |||
401 | static struct map_desc pxa27x_io_desc[] __initdata = { | 407 | static struct map_desc pxa27x_io_desc[] __initdata = { |
402 | { /* Mem Ctl */ | 408 | { /* Mem Ctl */ |
403 | .virtual = (unsigned long)SMEMC_VIRT, | 409 | .virtual = (unsigned long)SMEMC_VIRT, |
diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c index e329ccefd364..614003e8b081 100644 --- a/arch/arm/mach-pxa/pxa3xx-ulpi.c +++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c | |||
@@ -74,7 +74,7 @@ static int pxa310_ulpi_poll(void) | |||
74 | cpu_relax(); | 74 | cpu_relax(); |
75 | } | 75 | } |
76 | 76 | ||
77 | pr_warning("%s: ULPI access timed out!\n", __func__); | 77 | pr_warn("%s: ULPI access timed out!\n", __func__); |
78 | 78 | ||
79 | return -ETIMEDOUT; | 79 | return -ETIMEDOUT; |
80 | } | 80 | } |
@@ -84,7 +84,7 @@ static int pxa310_ulpi_read(struct usb_phy *otg, u32 reg) | |||
84 | int err; | 84 | int err; |
85 | 85 | ||
86 | if (pxa310_ulpi_get_phymode() != SYNCH) { | 86 | if (pxa310_ulpi_get_phymode() != SYNCH) { |
87 | pr_warning("%s: PHY is not in SYNCH mode!\n", __func__); | 87 | pr_warn("%s: PHY is not in SYNCH mode!\n", __func__); |
88 | return -EBUSY; | 88 | return -EBUSY; |
89 | } | 89 | } |
90 | 90 | ||
@@ -101,7 +101,7 @@ static int pxa310_ulpi_read(struct usb_phy *otg, u32 reg) | |||
101 | static int pxa310_ulpi_write(struct usb_phy *otg, u32 val, u32 reg) | 101 | static int pxa310_ulpi_write(struct usb_phy *otg, u32 val, u32 reg) |
102 | { | 102 | { |
103 | if (pxa310_ulpi_get_phymode() != SYNCH) { | 103 | if (pxa310_ulpi_get_phymode() != SYNCH) { |
104 | pr_warning("%s: PHY is not in SYNCH mode!\n", __func__); | 104 | pr_warn("%s: PHY is not in SYNCH mode!\n", __func__); |
105 | return -EBUSY; | 105 | return -EBUSY; |
106 | } | 106 | } |
107 | 107 | ||
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 8386dc30b3e4..a762b23ac830 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c | |||
@@ -521,7 +521,7 @@ static void __init raumfeld_w1_init(void) | |||
521 | "W1 external pullup enable"); | 521 | "W1 external pullup enable"); |
522 | 522 | ||
523 | if (ret < 0) | 523 | if (ret < 0) |
524 | pr_warning("Unable to request GPIO_W1_PULLUP_ENABLE\n"); | 524 | pr_warn("Unable to request GPIO_W1_PULLUP_ENABLE\n"); |
525 | else | 525 | else |
526 | gpio_direction_output(GPIO_W1_PULLUP_ENABLE, 0); | 526 | gpio_direction_output(GPIO_W1_PULLUP_ENABLE, 0); |
527 | 527 | ||
@@ -600,7 +600,7 @@ static void __init raumfeld_lcd_init(void) | |||
600 | 600 | ||
601 | ret = gpio_request(GPIO_TFT_VA_EN, "display VA enable"); | 601 | ret = gpio_request(GPIO_TFT_VA_EN, "display VA enable"); |
602 | if (ret < 0) | 602 | if (ret < 0) |
603 | pr_warning("Unable to request GPIO_TFT_VA_EN\n"); | 603 | pr_warn("Unable to request GPIO_TFT_VA_EN\n"); |
604 | else | 604 | else |
605 | gpio_direction_output(GPIO_TFT_VA_EN, 1); | 605 | gpio_direction_output(GPIO_TFT_VA_EN, 1); |
606 | 606 | ||
@@ -608,7 +608,7 @@ static void __init raumfeld_lcd_init(void) | |||
608 | 608 | ||
609 | ret = gpio_request(GPIO_DISPLAY_ENABLE, "display enable"); | 609 | ret = gpio_request(GPIO_DISPLAY_ENABLE, "display enable"); |
610 | if (ret < 0) | 610 | if (ret < 0) |
611 | pr_warning("Unable to request GPIO_DISPLAY_ENABLE\n"); | 611 | pr_warn("Unable to request GPIO_DISPLAY_ENABLE\n"); |
612 | else | 612 | else |
613 | gpio_direction_output(GPIO_DISPLAY_ENABLE, 1); | 613 | gpio_direction_output(GPIO_DISPLAY_ENABLE, 1); |
614 | 614 | ||
@@ -814,17 +814,17 @@ static void __init raumfeld_power_init(void) | |||
814 | /* Set PEN2 high to enable maximum charge current */ | 814 | /* Set PEN2 high to enable maximum charge current */ |
815 | ret = gpio_request(GPIO_CHRG_PEN2, "CHRG_PEN2"); | 815 | ret = gpio_request(GPIO_CHRG_PEN2, "CHRG_PEN2"); |
816 | if (ret < 0) | 816 | if (ret < 0) |
817 | pr_warning("Unable to request GPIO_CHRG_PEN2\n"); | 817 | pr_warn("Unable to request GPIO_CHRG_PEN2\n"); |
818 | else | 818 | else |
819 | gpio_direction_output(GPIO_CHRG_PEN2, 1); | 819 | gpio_direction_output(GPIO_CHRG_PEN2, 1); |
820 | 820 | ||
821 | ret = gpio_request(GPIO_CHARGE_DC_OK, "CABLE_DC_OK"); | 821 | ret = gpio_request(GPIO_CHARGE_DC_OK, "CABLE_DC_OK"); |
822 | if (ret < 0) | 822 | if (ret < 0) |
823 | pr_warning("Unable to request GPIO_CHARGE_DC_OK\n"); | 823 | pr_warn("Unable to request GPIO_CHARGE_DC_OK\n"); |
824 | 824 | ||
825 | ret = gpio_request(GPIO_CHARGE_USB_SUSP, "CHARGE_USB_SUSP"); | 825 | ret = gpio_request(GPIO_CHARGE_USB_SUSP, "CHARGE_USB_SUSP"); |
826 | if (ret < 0) | 826 | if (ret < 0) |
827 | pr_warning("Unable to request GPIO_CHARGE_USB_SUSP\n"); | 827 | pr_warn("Unable to request GPIO_CHARGE_USB_SUSP\n"); |
828 | else | 828 | else |
829 | gpio_direction_output(GPIO_CHARGE_USB_SUSP, 0); | 829 | gpio_direction_output(GPIO_CHARGE_USB_SUSP, 0); |
830 | 830 | ||
@@ -976,19 +976,19 @@ static void __init raumfeld_audio_init(void) | |||
976 | 976 | ||
977 | ret = gpio_request(GPIO_CODEC_RESET, "cs4270 reset"); | 977 | ret = gpio_request(GPIO_CODEC_RESET, "cs4270 reset"); |
978 | if (ret < 0) | 978 | if (ret < 0) |
979 | pr_warning("unable to request GPIO_CODEC_RESET\n"); | 979 | pr_warn("unable to request GPIO_CODEC_RESET\n"); |
980 | else | 980 | else |
981 | gpio_direction_output(GPIO_CODEC_RESET, 1); | 981 | gpio_direction_output(GPIO_CODEC_RESET, 1); |
982 | 982 | ||
983 | ret = gpio_request(GPIO_SPDIF_RESET, "ak4104 s/pdif reset"); | 983 | ret = gpio_request(GPIO_SPDIF_RESET, "ak4104 s/pdif reset"); |
984 | if (ret < 0) | 984 | if (ret < 0) |
985 | pr_warning("unable to request GPIO_SPDIF_RESET\n"); | 985 | pr_warn("unable to request GPIO_SPDIF_RESET\n"); |
986 | else | 986 | else |
987 | gpio_direction_output(GPIO_SPDIF_RESET, 1); | 987 | gpio_direction_output(GPIO_SPDIF_RESET, 1); |
988 | 988 | ||
989 | ret = gpio_request(GPIO_MCLK_RESET, "MCLK reset"); | 989 | ret = gpio_request(GPIO_MCLK_RESET, "MCLK reset"); |
990 | if (ret < 0) | 990 | if (ret < 0) |
991 | pr_warning("unable to request GPIO_MCLK_RESET\n"); | 991 | pr_warn("unable to request GPIO_MCLK_RESET\n"); |
992 | else | 992 | else |
993 | gpio_direction_output(GPIO_MCLK_RESET, 1); | 993 | gpio_direction_output(GPIO_MCLK_RESET, 1); |
994 | 994 | ||
@@ -1019,20 +1019,20 @@ static void __init raumfeld_common_init(void) | |||
1019 | 1019 | ||
1020 | ret = gpio_request(GPIO_W2W_RESET, "Wi2Wi reset"); | 1020 | ret = gpio_request(GPIO_W2W_RESET, "Wi2Wi reset"); |
1021 | if (ret < 0) | 1021 | if (ret < 0) |
1022 | pr_warning("Unable to request GPIO_W2W_RESET\n"); | 1022 | pr_warn("Unable to request GPIO_W2W_RESET\n"); |
1023 | else | 1023 | else |
1024 | gpio_direction_output(GPIO_W2W_RESET, 0); | 1024 | gpio_direction_output(GPIO_W2W_RESET, 0); |
1025 | 1025 | ||
1026 | ret = gpio_request(GPIO_W2W_PDN, "Wi2Wi powerup"); | 1026 | ret = gpio_request(GPIO_W2W_PDN, "Wi2Wi powerup"); |
1027 | if (ret < 0) | 1027 | if (ret < 0) |
1028 | pr_warning("Unable to request GPIO_W2W_PDN\n"); | 1028 | pr_warn("Unable to request GPIO_W2W_PDN\n"); |
1029 | else | 1029 | else |
1030 | gpio_direction_output(GPIO_W2W_PDN, 0); | 1030 | gpio_direction_output(GPIO_W2W_PDN, 0); |
1031 | 1031 | ||
1032 | /* this can be used to switch off the device */ | 1032 | /* this can be used to switch off the device */ |
1033 | ret = gpio_request(GPIO_SHUTDOWN_SUPPLY, "supply shutdown"); | 1033 | ret = gpio_request(GPIO_SHUTDOWN_SUPPLY, "supply shutdown"); |
1034 | if (ret < 0) | 1034 | if (ret < 0) |
1035 | pr_warning("Unable to request GPIO_SHUTDOWN_SUPPLY\n"); | 1035 | pr_warn("Unable to request GPIO_SHUTDOWN_SUPPLY\n"); |
1036 | else | 1036 | else |
1037 | gpio_direction_output(GPIO_SHUTDOWN_SUPPLY, 0); | 1037 | gpio_direction_output(GPIO_SHUTDOWN_SUPPLY, 0); |
1038 | 1038 | ||
@@ -1051,7 +1051,7 @@ static void __init raumfeld_controller_init(void) | |||
1051 | 1051 | ||
1052 | ret = gpio_request(GPIO_SHUTDOWN_BATT, "battery shutdown"); | 1052 | ret = gpio_request(GPIO_SHUTDOWN_BATT, "battery shutdown"); |
1053 | if (ret < 0) | 1053 | if (ret < 0) |
1054 | pr_warning("Unable to request GPIO_SHUTDOWN_BATT\n"); | 1054 | pr_warn("Unable to request GPIO_SHUTDOWN_BATT\n"); |
1055 | else | 1055 | else |
1056 | gpio_direction_output(GPIO_SHUTDOWN_BATT, 0); | 1056 | gpio_direction_output(GPIO_SHUTDOWN_BATT, 0); |
1057 | 1057 | ||
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index c158a6e3e0aa..7780d1faa06f 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/gpio_keys.h> | 30 | #include <linux/gpio_keys.h> |
31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
32 | #include <linux/gpio.h> | 32 | #include <linux/gpio.h> |
33 | #include <linux/pda_power.h> | 33 | #include <linux/power/gpio-charger.h> |
34 | #include <linux/spi/spi.h> | 34 | #include <linux/spi/spi.h> |
35 | #include <linux/spi/pxa2xx_spi.h> | 35 | #include <linux/spi/pxa2xx_spi.h> |
36 | #include <linux/input/matrix_keypad.h> | 36 | #include <linux/input/matrix_keypad.h> |
@@ -361,44 +361,17 @@ static struct pxaficp_platform_data tosa_ficp_platform_data = { | |||
361 | /* | 361 | /* |
362 | * Tosa AC IN | 362 | * Tosa AC IN |
363 | */ | 363 | */ |
364 | static int tosa_power_init(struct device *dev) | ||
365 | { | ||
366 | int ret = gpio_request(TOSA_GPIO_AC_IN, "ac in"); | ||
367 | if (ret) | ||
368 | goto err_gpio_req; | ||
369 | |||
370 | ret = gpio_direction_input(TOSA_GPIO_AC_IN); | ||
371 | if (ret) | ||
372 | goto err_gpio_in; | ||
373 | |||
374 | return 0; | ||
375 | |||
376 | err_gpio_in: | ||
377 | gpio_free(TOSA_GPIO_AC_IN); | ||
378 | err_gpio_req: | ||
379 | return ret; | ||
380 | } | ||
381 | |||
382 | static void tosa_power_exit(struct device *dev) | ||
383 | { | ||
384 | gpio_free(TOSA_GPIO_AC_IN); | ||
385 | } | ||
386 | |||
387 | static int tosa_power_ac_online(void) | ||
388 | { | ||
389 | return gpio_get_value(TOSA_GPIO_AC_IN) == 0; | ||
390 | } | ||
391 | |||
392 | static char *tosa_ac_supplied_to[] = { | 364 | static char *tosa_ac_supplied_to[] = { |
393 | "main-battery", | 365 | "main-battery", |
394 | "backup-battery", | 366 | "backup-battery", |
395 | "jacket-battery", | 367 | "jacket-battery", |
396 | }; | 368 | }; |
397 | 369 | ||
398 | static struct pda_power_pdata tosa_power_data = { | 370 | static struct gpio_charger_platform_data tosa_power_data = { |
399 | .init = tosa_power_init, | 371 | .name = "charger", |
400 | .is_ac_online = tosa_power_ac_online, | 372 | .type = POWER_SUPPLY_TYPE_MAINS, |
401 | .exit = tosa_power_exit, | 373 | .gpio = TOSA_GPIO_AC_IN, |
374 | .gpio_active_low = 1, | ||
402 | .supplied_to = tosa_ac_supplied_to, | 375 | .supplied_to = tosa_ac_supplied_to, |
403 | .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to), | 376 | .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to), |
404 | }; | 377 | }; |
@@ -415,7 +388,7 @@ static struct resource tosa_power_resource[] = { | |||
415 | }; | 388 | }; |
416 | 389 | ||
417 | static struct platform_device tosa_power_device = { | 390 | static struct platform_device tosa_power_device = { |
418 | .name = "pda-power", | 391 | .name = "gpio-charger", |
419 | .id = -1, | 392 | .id = -1, |
420 | .dev.platform_data = &tosa_power_data, | 393 | .dev.platform_data = &tosa_power_data, |
421 | .resource = tosa_power_resource, | 394 | .resource = tosa_power_resource, |
diff --git a/arch/arm/mach-rockchip/headsmp.S b/arch/arm/mach-rockchip/headsmp.S index 73206e360e31..46c22dedf632 100644 --- a/arch/arm/mach-rockchip/headsmp.S +++ b/arch/arm/mach-rockchip/headsmp.S | |||
@@ -16,7 +16,10 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | 17 | ||
18 | ENTRY(rockchip_secondary_startup) | 18 | ENTRY(rockchip_secondary_startup) |
19 | bl v7_invalidate_l1 | 19 | mrc p15, 0, r0, c0, c0, 0 @ read main ID register |
20 | ldr r1, =0x00000c09 @ Cortex-A9 primary part number | ||
21 | teq r0, r1 | ||
22 | beq v7_invalidate_l1 | ||
20 | b secondary_startup | 23 | b secondary_startup |
21 | ENDPROC(rockchip_secondary_startup) | 24 | ENDPROC(rockchip_secondary_startup) |
22 | 25 | ||
diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index 189684f55927..f26fcdca2445 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c | |||
@@ -19,7 +19,11 @@ | |||
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
22 | #include <linux/regmap.h> | ||
23 | #include <linux/mfd/syscon.h> | ||
22 | 24 | ||
25 | #include <linux/reset.h> | ||
26 | #include <linux/cpu.h> | ||
23 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
24 | #include <asm/cp15.h> | 28 | #include <asm/cp15.h> |
25 | #include <asm/smp_scu.h> | 29 | #include <asm/smp_scu.h> |
@@ -37,23 +41,78 @@ static int ncores; | |||
37 | 41 | ||
38 | #define PMU_PWRDN_SCU 4 | 42 | #define PMU_PWRDN_SCU 4 |
39 | 43 | ||
40 | static void __iomem *pmu_base_addr; | 44 | static struct regmap *pmu; |
41 | 45 | ||
42 | static inline bool pmu_power_domain_is_on(int pd) | 46 | static int pmu_power_domain_is_on(int pd) |
43 | { | 47 | { |
44 | return !(readl_relaxed(pmu_base_addr + PMU_PWRDN_ST) & BIT(pd)); | 48 | u32 val; |
49 | int ret; | ||
50 | |||
51 | ret = regmap_read(pmu, PMU_PWRDN_ST, &val); | ||
52 | if (ret < 0) | ||
53 | return ret; | ||
54 | |||
55 | return !(val & BIT(pd)); | ||
45 | } | 56 | } |
46 | 57 | ||
47 | static void pmu_set_power_domain(int pd, bool on) | 58 | struct reset_control *rockchip_get_core_reset(int cpu) |
48 | { | 59 | { |
49 | u32 val = readl_relaxed(pmu_base_addr + PMU_PWRDN_CON); | 60 | struct device *dev = get_cpu_device(cpu); |
50 | if (on) | 61 | struct device_node *np; |
51 | val &= ~BIT(pd); | 62 | |
63 | /* The cpu device is only available after the initial core bringup */ | ||
64 | if (dev) | ||
65 | np = dev->of_node; | ||
52 | else | 66 | else |
53 | val |= BIT(pd); | 67 | np = of_get_cpu_node(cpu, 0); |
54 | writel(val, pmu_base_addr + PMU_PWRDN_CON); | ||
55 | 68 | ||
56 | while (pmu_power_domain_is_on(pd) != on) { } | 69 | return of_reset_control_get(np, NULL); |
70 | } | ||
71 | |||
72 | static int pmu_set_power_domain(int pd, bool on) | ||
73 | { | ||
74 | u32 val = (on) ? 0 : BIT(pd); | ||
75 | int ret; | ||
76 | |||
77 | /* | ||
78 | * We need to soft reset the cpu when we turn off the cpu power domain, | ||
79 | * or else the active processors might be stalled when the individual | ||
80 | * processor is powered down. | ||
81 | */ | ||
82 | if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) { | ||
83 | struct reset_control *rstc = rockchip_get_core_reset(pd); | ||
84 | |||
85 | if (IS_ERR(rstc)) { | ||
86 | pr_err("%s: could not get reset control for core %d\n", | ||
87 | __func__, pd); | ||
88 | return PTR_ERR(rstc); | ||
89 | } | ||
90 | |||
91 | if (on) | ||
92 | reset_control_deassert(rstc); | ||
93 | else | ||
94 | reset_control_assert(rstc); | ||
95 | |||
96 | reset_control_put(rstc); | ||
97 | } | ||
98 | |||
99 | ret = regmap_update_bits(pmu, PMU_PWRDN_CON, BIT(pd), val); | ||
100 | if (ret < 0) { | ||
101 | pr_err("%s: could not update power domain\n", __func__); | ||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | ret = -1; | ||
106 | while (ret != on) { | ||
107 | ret = pmu_power_domain_is_on(pd); | ||
108 | if (ret < 0) { | ||
109 | pr_err("%s: could not read power domain state\n", | ||
110 | __func__); | ||
111 | return ret; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | return 0; | ||
57 | } | 116 | } |
58 | 117 | ||
59 | /* | 118 | /* |
@@ -63,7 +122,9 @@ static void pmu_set_power_domain(int pd, bool on) | |||
63 | static int __cpuinit rockchip_boot_secondary(unsigned int cpu, | 122 | static int __cpuinit rockchip_boot_secondary(unsigned int cpu, |
64 | struct task_struct *idle) | 123 | struct task_struct *idle) |
65 | { | 124 | { |
66 | if (!sram_base_addr || !pmu_base_addr) { | 125 | int ret; |
126 | |||
127 | if (!sram_base_addr || !pmu) { | ||
67 | pr_err("%s: sram or pmu missing for cpu boot\n", __func__); | 128 | pr_err("%s: sram or pmu missing for cpu boot\n", __func__); |
68 | return -ENXIO; | 129 | return -ENXIO; |
69 | } | 130 | } |
@@ -75,7 +136,24 @@ static int __cpuinit rockchip_boot_secondary(unsigned int cpu, | |||
75 | } | 136 | } |
76 | 137 | ||
77 | /* start the core */ | 138 | /* start the core */ |
78 | pmu_set_power_domain(0 + cpu, true); | 139 | ret = pmu_set_power_domain(0 + cpu, true); |
140 | if (ret < 0) | ||
141 | return ret; | ||
142 | |||
143 | if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) { | ||
144 | /* We communicate with the bootrom to active the cpus other | ||
145 | * than cpu0, after a blob of initialize code, they will | ||
146 | * stay at wfe state, once they are actived, they will check | ||
147 | * the mailbox: | ||
148 | * sram_base_addr + 4: 0xdeadbeaf | ||
149 | * sram_base_addr + 8: start address for pc | ||
150 | * */ | ||
151 | udelay(10); | ||
152 | writel(virt_to_phys(rockchip_secondary_startup), | ||
153 | sram_base_addr + 8); | ||
154 | writel(0xDEADBEAF, sram_base_addr + 4); | ||
155 | dsb_sev(); | ||
156 | } | ||
79 | 157 | ||
80 | return 0; | 158 | return 0; |
81 | } | 159 | } |
@@ -110,8 +188,6 @@ static int __init rockchip_smp_prepare_sram(struct device_node *node) | |||
110 | return -EINVAL; | 188 | return -EINVAL; |
111 | } | 189 | } |
112 | 190 | ||
113 | sram_base_addr = of_iomap(node, 0); | ||
114 | |||
115 | /* set the boot function for the sram code */ | 191 | /* set the boot function for the sram code */ |
116 | rockchip_boot_fn = virt_to_phys(rockchip_secondary_startup); | 192 | rockchip_boot_fn = virt_to_phys(rockchip_secondary_startup); |
117 | 193 | ||
@@ -125,54 +201,115 @@ static int __init rockchip_smp_prepare_sram(struct device_node *node) | |||
125 | return 0; | 201 | return 0; |
126 | } | 202 | } |
127 | 203 | ||
128 | static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus) | 204 | static struct regmap_config rockchip_pmu_regmap_config = { |
205 | .reg_bits = 32, | ||
206 | .val_bits = 32, | ||
207 | .reg_stride = 4, | ||
208 | }; | ||
209 | |||
210 | static int __init rockchip_smp_prepare_pmu(void) | ||
129 | { | 211 | { |
130 | struct device_node *node; | 212 | struct device_node *node; |
131 | unsigned int i; | 213 | void __iomem *pmu_base; |
132 | 214 | ||
133 | node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); | 215 | /* |
216 | * This function is only called via smp_ops->smp_prepare_cpu(). | ||
217 | * That only happens if a "/cpus" device tree node exists | ||
218 | * and has an "enable-method" property that selects the SMP | ||
219 | * operations defined herein. | ||
220 | */ | ||
221 | node = of_find_node_by_path("/cpus"); | ||
222 | |||
223 | pmu = syscon_regmap_lookup_by_phandle(node, "rockchip,pmu"); | ||
224 | of_node_put(node); | ||
225 | if (!IS_ERR(pmu)) | ||
226 | return 0; | ||
227 | |||
228 | pmu = syscon_regmap_lookup_by_compatible("rockchip,rk3066-pmu"); | ||
229 | if (!IS_ERR(pmu)) | ||
230 | return 0; | ||
231 | |||
232 | /* fallback, create our own regmap for the pmu area */ | ||
233 | pmu = NULL; | ||
234 | node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu"); | ||
134 | if (!node) { | 235 | if (!node) { |
135 | pr_err("%s: missing scu\n", __func__); | 236 | pr_err("%s: could not find pmu dt node\n", __func__); |
136 | return; | 237 | return -ENODEV; |
137 | } | 238 | } |
138 | 239 | ||
139 | scu_base_addr = of_iomap(node, 0); | 240 | pmu_base = of_iomap(node, 0); |
140 | if (!scu_base_addr) { | 241 | if (!pmu_base) { |
141 | pr_err("%s: could not map scu registers\n", __func__); | 242 | pr_err("%s: could not map pmu registers\n", __func__); |
142 | return; | 243 | return -ENOMEM; |
143 | } | 244 | } |
144 | 245 | ||
145 | node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-smp-sram"); | 246 | pmu = regmap_init_mmio(NULL, pmu_base, &rockchip_pmu_regmap_config); |
146 | if (!node) { | 247 | if (IS_ERR(pmu)) { |
147 | pr_err("%s: could not find sram dt node\n", __func__); | 248 | int ret = PTR_ERR(pmu); |
148 | return; | 249 | |
250 | iounmap(pmu_base); | ||
251 | pmu = NULL; | ||
252 | pr_err("%s: regmap init failed\n", __func__); | ||
253 | return ret; | ||
149 | } | 254 | } |
150 | 255 | ||
151 | if (rockchip_smp_prepare_sram(node)) | 256 | return 0; |
152 | return; | 257 | } |
153 | 258 | ||
154 | node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu"); | 259 | static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus) |
260 | { | ||
261 | struct device_node *node; | ||
262 | unsigned int i; | ||
263 | |||
264 | node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-smp-sram"); | ||
155 | if (!node) { | 265 | if (!node) { |
156 | pr_err("%s: could not find pmu dt node\n", __func__); | 266 | pr_err("%s: could not find sram dt node\n", __func__); |
157 | return; | 267 | return; |
158 | } | 268 | } |
159 | 269 | ||
160 | pmu_base_addr = of_iomap(node, 0); | 270 | sram_base_addr = of_iomap(node, 0); |
161 | if (!pmu_base_addr) { | 271 | if (!sram_base_addr) { |
162 | pr_err("%s: could not map pmu registers\n", __func__); | 272 | pr_err("%s: could not map sram registers\n", __func__); |
163 | return; | 273 | return; |
164 | } | 274 | } |
165 | 275 | ||
166 | /* enable the SCU power domain */ | 276 | if (rockchip_smp_prepare_pmu()) |
167 | pmu_set_power_domain(PMU_PWRDN_SCU, true); | 277 | return; |
168 | |||
169 | /* | ||
170 | * While the number of cpus is gathered from dt, also get the number | ||
171 | * of cores from the scu to verify this value when booting the cores. | ||
172 | */ | ||
173 | ncores = scu_get_core_count(scu_base_addr); | ||
174 | 278 | ||
175 | scu_enable(scu_base_addr); | 279 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) { |
280 | if (rockchip_smp_prepare_sram(node)) | ||
281 | return; | ||
282 | |||
283 | /* enable the SCU power domain */ | ||
284 | pmu_set_power_domain(PMU_PWRDN_SCU, true); | ||
285 | |||
286 | node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); | ||
287 | if (!node) { | ||
288 | pr_err("%s: missing scu\n", __func__); | ||
289 | return; | ||
290 | } | ||
291 | |||
292 | scu_base_addr = of_iomap(node, 0); | ||
293 | if (!scu_base_addr) { | ||
294 | pr_err("%s: could not map scu registers\n", __func__); | ||
295 | return; | ||
296 | } | ||
297 | |||
298 | /* | ||
299 | * While the number of cpus is gathered from dt, also get the | ||
300 | * number of cores from the scu to verify this value when | ||
301 | * booting the cores. | ||
302 | */ | ||
303 | ncores = scu_get_core_count(scu_base_addr); | ||
304 | pr_err("%s: ncores %d\n", __func__, ncores); | ||
305 | |||
306 | scu_enable(scu_base_addr); | ||
307 | } else { | ||
308 | unsigned int l2ctlr; | ||
309 | |||
310 | asm ("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr)); | ||
311 | ncores = ((l2ctlr >> 24) & 0x3) + 1; | ||
312 | } | ||
176 | 313 | ||
177 | /* Make sure that all cores except the first are really off */ | 314 | /* Make sure that all cores except the first are really off */ |
178 | for (i = 1; i < ncores; i++) | 315 | for (i = 1; i < ncores; i++) |
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c index 8ab9e0e7ff04..d226b71d21d5 100644 --- a/arch/arm/mach-rockchip/rockchip.c +++ b/arch/arm/mach-rockchip/rockchip.c | |||
@@ -24,6 +24,12 @@ | |||
24 | #include <asm/hardware/cache-l2x0.h> | 24 | #include <asm/hardware/cache-l2x0.h> |
25 | #include "core.h" | 25 | #include "core.h" |
26 | 26 | ||
27 | static void __init rockchip_dt_init(void) | ||
28 | { | ||
29 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | ||
30 | platform_device_register_simple("cpufreq-dt", 0, NULL, 0); | ||
31 | } | ||
32 | |||
27 | static const char * const rockchip_board_dt_compat[] = { | 33 | static const char * const rockchip_board_dt_compat[] = { |
28 | "rockchip,rk2928", | 34 | "rockchip,rk2928", |
29 | "rockchip,rk3066a", | 35 | "rockchip,rk3066a", |
@@ -37,4 +43,5 @@ DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)") | |||
37 | .l2c_aux_val = 0, | 43 | .l2c_aux_val = 0, |
38 | .l2c_aux_mask = ~0, | 44 | .l2c_aux_mask = ~0, |
39 | .dt_compat = rockchip_board_dt_compat, | 45 | .dt_compat = rockchip_board_dt_compat, |
46 | .init_machine = rockchip_dt_init, | ||
40 | MACHINE_END | 47 | MACHINE_END |
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 0f2539550f1b..1b4fafe524ff 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config ARCH_SHMOBILE | 1 | config ARCH_SHMOBILE |
2 | bool | 2 | bool |
3 | select ZONE_DMA if ARM_LPAE | ||
3 | 4 | ||
4 | config PM_RCAR | 5 | config PM_RCAR |
5 | bool | 6 | bool |
@@ -18,6 +19,7 @@ config ARCH_RCAR_GEN2 | |||
18 | select PM_RCAR if PM || SMP | 19 | select PM_RCAR if PM || SMP |
19 | select RENESAS_IRQC | 20 | select RENESAS_IRQC |
20 | select SYS_SUPPORTS_SH_CMT | 21 | select SYS_SUPPORTS_SH_CMT |
22 | select PCI_DOMAINS if PCI | ||
21 | 23 | ||
22 | config ARCH_RMOBILE | 24 | config ARCH_RMOBILE |
23 | bool | 25 | bool |
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 7d68eba53be3..b55cac0e5b2b 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile | |||
@@ -35,6 +35,7 @@ cpu-y := platsmp.o headsmp.o | |||
35 | 35 | ||
36 | # Shared SoC family objects | 36 | # Shared SoC family objects |
37 | obj-$(CONFIG_ARCH_RCAR_GEN2) += setup-rcar-gen2.o platsmp-apmu.o $(cpu-y) | 37 | obj-$(CONFIG_ARCH_RCAR_GEN2) += setup-rcar-gen2.o platsmp-apmu.o $(cpu-y) |
38 | CFLAGS_setup-rcar-gen2.o += -march=armv7-a | ||
38 | 39 | ||
39 | # SMP objects | 40 | # SMP objects |
40 | smp-y := $(cpu-y) | 41 | smp-y := $(cpu-y) |
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index de95181c7de4..6d949f1c850b 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c | |||
@@ -1229,8 +1229,15 @@ static void __init eva_init(void) | |||
1229 | static struct pm_domain_device domain_devices[] __initdata = { | 1229 | static struct pm_domain_device domain_devices[] __initdata = { |
1230 | { "A4LC", &lcdc0_device }, | 1230 | { "A4LC", &lcdc0_device }, |
1231 | { "A4LC", &hdmi_lcdc_device }, | 1231 | { "A4LC", &hdmi_lcdc_device }, |
1232 | { "A4MP", &hdmi_device }, | ||
1233 | { "A4MP", &fsi_device }, | ||
1234 | { "A4R", &ceu0_device }, | ||
1235 | { "A4S", &sh_eth_device }, | ||
1236 | { "A3SP", &pwm_device }, | ||
1237 | { "A3SP", &sdhi0_device }, | ||
1238 | { "A3SP", &sh_mmcif_device }, | ||
1232 | }; | 1239 | }; |
1233 | struct platform_device *usb = NULL; | 1240 | struct platform_device *usb = NULL, *sdhi1 = NULL; |
1234 | 1241 | ||
1235 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | 1242 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, |
1236 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | 1243 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); |
@@ -1299,6 +1306,7 @@ static void __init eva_init(void) | |||
1299 | 1306 | ||
1300 | platform_device_register(&vcc_sdhi1); | 1307 | platform_device_register(&vcc_sdhi1); |
1301 | platform_device_register(&sdhi1_device); | 1308 | platform_device_register(&sdhi1_device); |
1309 | sdhi1 = &sdhi1_device; | ||
1302 | } | 1310 | } |
1303 | 1311 | ||
1304 | 1312 | ||
@@ -1319,6 +1327,8 @@ static void __init eva_init(void) | |||
1319 | ARRAY_SIZE(domain_devices)); | 1327 | ARRAY_SIZE(domain_devices)); |
1320 | if (usb) | 1328 | if (usb) |
1321 | rmobile_add_device_to_domain("A3SP", usb); | 1329 | rmobile_add_device_to_domain("A3SP", usb); |
1330 | if (sdhi1) | ||
1331 | rmobile_add_device_to_domain("A3SP", sdhi1); | ||
1322 | 1332 | ||
1323 | r8a7740_pm_init(); | 1333 | r8a7740_pm_init(); |
1324 | } | 1334 | } |
diff --git a/arch/arm/mach-shmobile/board-kzm9g-reference.c b/arch/arm/mach-shmobile/board-kzm9g-reference.c index f2ef759b6e96..2e82e44ab852 100644 --- a/arch/arm/mach-shmobile/board-kzm9g-reference.c +++ b/arch/arm/mach-shmobile/board-kzm9g-reference.c | |||
@@ -39,6 +39,13 @@ static void __init kzm_init(void) | |||
39 | #endif | 39 | #endif |
40 | } | 40 | } |
41 | 41 | ||
42 | #define RESCNT2 IOMEM(0xe6188020) | ||
43 | static void kzm9g_restart(enum reboot_mode mode, const char *cmd) | ||
44 | { | ||
45 | /* Do soft power on reset */ | ||
46 | writel((1 << 31), RESCNT2); | ||
47 | } | ||
48 | |||
42 | static const char *kzm9g_boards_compat_dt[] __initdata = { | 49 | static const char *kzm9g_boards_compat_dt[] __initdata = { |
43 | "renesas,kzm9g-reference", | 50 | "renesas,kzm9g-reference", |
44 | NULL, | 51 | NULL, |
@@ -50,5 +57,6 @@ DT_MACHINE_START(KZM9G_DT, "kzm9g-reference") | |||
50 | .init_early = shmobile_init_delay, | 57 | .init_early = shmobile_init_delay, |
51 | .init_machine = kzm_init, | 58 | .init_machine = kzm_init, |
52 | .init_late = shmobile_init_late, | 59 | .init_late = shmobile_init_late, |
60 | .restart = kzm9g_restart, | ||
53 | .dt_compat = kzm9g_boards_compat_dt, | 61 | .dt_compat = kzm9g_boards_compat_dt, |
54 | MACHINE_END | 62 | MACHINE_END |
diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h index 72087c79ad7b..309025efd4cf 100644 --- a/arch/arm/mach-shmobile/common.h +++ b/arch/arm/mach-shmobile/common.h | |||
@@ -19,11 +19,6 @@ extern void shmobile_boot_scu(void); | |||
19 | extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); | 19 | extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); |
20 | extern void shmobile_smp_scu_cpu_die(unsigned int cpu); | 20 | extern void shmobile_smp_scu_cpu_die(unsigned int cpu); |
21 | extern int shmobile_smp_scu_cpu_kill(unsigned int cpu); | 21 | extern int shmobile_smp_scu_cpu_kill(unsigned int cpu); |
22 | extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus); | ||
23 | extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu, | ||
24 | struct task_struct *idle); | ||
25 | extern void shmobile_smp_apmu_cpu_die(unsigned int cpu); | ||
26 | extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu); | ||
27 | struct clk; | 22 | struct clk; |
28 | extern int shmobile_clk_init(void); | 23 | extern int shmobile_clk_init(void); |
29 | extern void shmobile_handle_irq_intc(struct pt_regs *); | 24 | extern void shmobile_handle_irq_intc(struct pt_regs *); |
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c index 2c06810d3a70..f483b560b066 100644 --- a/arch/arm/mach-shmobile/platsmp-apmu.c +++ b/arch/arm/mach-shmobile/platsmp-apmu.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SMP support for SoCs with APMU | 2 | * SMP support for SoCs with APMU |
3 | * | 3 | * |
4 | * Copyright (C) 2014 Renesas Electronics Corporation | ||
4 | * Copyright (C) 2013 Magnus Damm | 5 | * Copyright (C) 2013 Magnus Damm |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -22,6 +23,7 @@ | |||
22 | #include <asm/smp_plat.h> | 23 | #include <asm/smp_plat.h> |
23 | #include <asm/suspend.h> | 24 | #include <asm/suspend.h> |
24 | #include "common.h" | 25 | #include "common.h" |
26 | #include "platsmp-apmu.h" | ||
25 | 27 | ||
26 | static struct { | 28 | static struct { |
27 | void __iomem *iomem; | 29 | void __iomem *iomem; |
@@ -83,28 +85,15 @@ static void apmu_init_cpu(struct resource *res, int cpu, int bit) | |||
83 | pr_debug("apmu ioremap %d %d %pr\n", cpu, bit, res); | 85 | pr_debug("apmu ioremap %d %d %pr\n", cpu, bit, res); |
84 | } | 86 | } |
85 | 87 | ||
86 | static struct { | 88 | static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit), |
87 | struct resource iomem; | 89 | struct rcar_apmu_config *apmu_config, int num) |
88 | int cpus[4]; | ||
89 | } apmu_config[] = { | ||
90 | { | ||
91 | .iomem = DEFINE_RES_MEM(0xe6152000, 0x88), | ||
92 | .cpus = { 0, 1, 2, 3 }, | ||
93 | }, | ||
94 | { | ||
95 | .iomem = DEFINE_RES_MEM(0xe6151000, 0x88), | ||
96 | .cpus = { 0x100, 0x101, 0x102, 0x103 }, | ||
97 | } | ||
98 | }; | ||
99 | |||
100 | static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit)) | ||
101 | { | 90 | { |
102 | u32 id; | 91 | u32 id; |
103 | int k; | 92 | int k; |
104 | int bit, index; | 93 | int bit, index; |
105 | bool is_allowed; | 94 | bool is_allowed; |
106 | 95 | ||
107 | for (k = 0; k < ARRAY_SIZE(apmu_config); k++) { | 96 | for (k = 0; k < num; k++) { |
108 | /* only enable the cluster that includes the boot CPU */ | 97 | /* only enable the cluster that includes the boot CPU */ |
109 | is_allowed = false; | 98 | is_allowed = false; |
110 | for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) { | 99 | for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) { |
@@ -128,14 +117,16 @@ static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit)) | |||
128 | } | 117 | } |
129 | } | 118 | } |
130 | 119 | ||
131 | void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus) | 120 | void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus, |
121 | struct rcar_apmu_config *apmu_config, | ||
122 | int num) | ||
132 | { | 123 | { |
133 | /* install boot code shared by all CPUs */ | 124 | /* install boot code shared by all CPUs */ |
134 | shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); | 125 | shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); |
135 | shmobile_boot_arg = MPIDR_HWID_BITMASK; | 126 | shmobile_boot_arg = MPIDR_HWID_BITMASK; |
136 | 127 | ||
137 | /* perform per-cpu setup */ | 128 | /* perform per-cpu setup */ |
138 | apmu_parse_cfg(apmu_init_cpu); | 129 | apmu_parse_cfg(apmu_init_cpu, apmu_config, num); |
139 | } | 130 | } |
140 | 131 | ||
141 | #ifdef CONFIG_SMP | 132 | #ifdef CONFIG_SMP |
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.h b/arch/arm/mach-shmobile/platsmp-apmu.h new file mode 100644 index 000000000000..76512c9a2545 --- /dev/null +++ b/arch/arm/mach-shmobile/platsmp-apmu.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * rmobile apmu definition | ||
3 | * | ||
4 | * Copyright (C) 2014 Renesas Electronics Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef PLATSMP_APMU_H | ||
17 | #define PLATSMP_APMU_H | ||
18 | |||
19 | struct rcar_apmu_config { | ||
20 | struct resource iomem; | ||
21 | int cpus[4]; | ||
22 | }; | ||
23 | |||
24 | extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus, | ||
25 | struct rcar_apmu_config *apmu_config, | ||
26 | int num); | ||
27 | extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu, | ||
28 | struct task_struct *idle); | ||
29 | extern void shmobile_smp_apmu_cpu_die(unsigned int cpu); | ||
30 | extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu); | ||
31 | |||
32 | #endif /* PLATSMP_APMU_H */ | ||
diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c index e3f146448237..ac2eecd6f5ea 100644 --- a/arch/arm/mach-shmobile/pm-r8a7740.c +++ b/arch/arm/mach-shmobile/pm-r8a7740.c | |||
@@ -14,10 +14,10 @@ | |||
14 | #include "pm-rmobile.h" | 14 | #include "pm-rmobile.h" |
15 | 15 | ||
16 | #if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM) | 16 | #if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM) |
17 | static int r8a7740_pd_a4s_suspend(void) | 17 | static int r8a7740_pd_a3sm_suspend(void) |
18 | { | 18 | { |
19 | /* | 19 | /* |
20 | * The A4S domain contains the CPU core and therefore it should | 20 | * The A3SM domain contains the CPU core and therefore it should |
21 | * only be turned off if the CPU is not in use. | 21 | * only be turned off if the CPU is not in use. |
22 | */ | 22 | */ |
23 | return -EBUSY; | 23 | return -EBUSY; |
@@ -32,29 +32,65 @@ static int r8a7740_pd_a3sp_suspend(void) | |||
32 | return console_suspend_enabled ? 0 : -EBUSY; | 32 | return console_suspend_enabled ? 0 : -EBUSY; |
33 | } | 33 | } |
34 | 34 | ||
35 | static int r8a7740_pd_d4_suspend(void) | ||
36 | { | ||
37 | /* | ||
38 | * The D4 domain contains the Coresight-ETM hardware block and | ||
39 | * therefore it should only be turned off if the debug module is | ||
40 | * not in use. | ||
41 | */ | ||
42 | return -EBUSY; | ||
43 | } | ||
44 | |||
35 | static struct rmobile_pm_domain r8a7740_pm_domains[] = { | 45 | static struct rmobile_pm_domain r8a7740_pm_domains[] = { |
36 | { | 46 | { |
37 | .genpd.name = "A4LC", | 47 | .genpd.name = "A4LC", |
38 | .bit_shift = 1, | 48 | .bit_shift = 1, |
39 | }, { | 49 | }, { |
50 | .genpd.name = "A4MP", | ||
51 | .bit_shift = 2, | ||
52 | }, { | ||
53 | .genpd.name = "D4", | ||
54 | .bit_shift = 3, | ||
55 | .gov = &pm_domain_always_on_gov, | ||
56 | .suspend = r8a7740_pd_d4_suspend, | ||
57 | }, { | ||
58 | .genpd.name = "A4R", | ||
59 | .bit_shift = 5, | ||
60 | }, { | ||
61 | .genpd.name = "A3RV", | ||
62 | .bit_shift = 6, | ||
63 | }, { | ||
40 | .genpd.name = "A4S", | 64 | .genpd.name = "A4S", |
41 | .bit_shift = 10, | 65 | .bit_shift = 10, |
42 | .gov = &pm_domain_always_on_gov, | ||
43 | .no_debug = true, | 66 | .no_debug = true, |
44 | .suspend = r8a7740_pd_a4s_suspend, | ||
45 | }, { | 67 | }, { |
46 | .genpd.name = "A3SP", | 68 | .genpd.name = "A3SP", |
47 | .bit_shift = 11, | 69 | .bit_shift = 11, |
48 | .gov = &pm_domain_always_on_gov, | 70 | .gov = &pm_domain_always_on_gov, |
49 | .no_debug = true, | 71 | .no_debug = true, |
50 | .suspend = r8a7740_pd_a3sp_suspend, | 72 | .suspend = r8a7740_pd_a3sp_suspend, |
73 | }, { | ||
74 | .genpd.name = "A3SM", | ||
75 | .bit_shift = 12, | ||
76 | .gov = &pm_domain_always_on_gov, | ||
77 | .suspend = r8a7740_pd_a3sm_suspend, | ||
78 | }, { | ||
79 | .genpd.name = "A3SG", | ||
80 | .bit_shift = 13, | ||
81 | }, { | ||
82 | .genpd.name = "A4SU", | ||
83 | .bit_shift = 20, | ||
51 | }, | 84 | }, |
52 | }; | 85 | }; |
53 | 86 | ||
54 | void __init r8a7740_init_pm_domains(void) | 87 | void __init r8a7740_init_pm_domains(void) |
55 | { | 88 | { |
56 | rmobile_init_domains(r8a7740_pm_domains, ARRAY_SIZE(r8a7740_pm_domains)); | 89 | rmobile_init_domains(r8a7740_pm_domains, ARRAY_SIZE(r8a7740_pm_domains)); |
90 | pm_genpd_add_subdomain_names("A4R", "A3RV"); | ||
57 | pm_genpd_add_subdomain_names("A4S", "A3SP"); | 91 | pm_genpd_add_subdomain_names("A4S", "A3SP"); |
92 | pm_genpd_add_subdomain_names("A4S", "A3SM"); | ||
93 | pm_genpd_add_subdomain_names("A4S", "A3SG"); | ||
58 | } | 94 | } |
59 | #endif /* CONFIG_PM && !CONFIG_ARCH_MULTIPLATFORM */ | 95 | #endif /* CONFIG_PM && !CONFIG_ARCH_MULTIPLATFORM */ |
60 | 96 | ||
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index fe15dd26d15d..79ad93dfdae4 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c | |||
@@ -67,6 +67,7 @@ static struct map_desc r8a7740_io_desc[] __initdata = { | |||
67 | 67 | ||
68 | void __init r8a7740_map_io(void) | 68 | void __init r8a7740_map_io(void) |
69 | { | 69 | { |
70 | debug_ll_io_init(); | ||
70 | iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc)); | 71 | iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc)); |
71 | } | 72 | } |
72 | 73 | ||
@@ -742,6 +743,12 @@ static void r8a7740_i2c_workaround(struct platform_device *pdev) | |||
742 | void __init r8a7740_add_standard_devices(void) | 743 | void __init r8a7740_add_standard_devices(void) |
743 | { | 744 | { |
744 | static struct pm_domain_device domain_devices[] __initdata = { | 745 | static struct pm_domain_device domain_devices[] __initdata = { |
746 | { "A4R", &tmu0_device }, | ||
747 | { "A4R", &i2c0_device }, | ||
748 | { "A4S", &irqpin0_device }, | ||
749 | { "A4S", &irqpin1_device }, | ||
750 | { "A4S", &irqpin2_device }, | ||
751 | { "A4S", &irqpin3_device }, | ||
745 | { "A3SP", &scif0_device }, | 752 | { "A3SP", &scif0_device }, |
746 | { "A3SP", &scif1_device }, | 753 | { "A3SP", &scif1_device }, |
747 | { "A3SP", &scif2_device }, | 754 | { "A3SP", &scif2_device }, |
@@ -752,6 +759,11 @@ void __init r8a7740_add_standard_devices(void) | |||
752 | { "A3SP", &scif7_device }, | 759 | { "A3SP", &scif7_device }, |
753 | { "A3SP", &scif8_device }, | 760 | { "A3SP", &scif8_device }, |
754 | { "A3SP", &i2c1_device }, | 761 | { "A3SP", &i2c1_device }, |
762 | { "A3SP", &ipmmu_device }, | ||
763 | { "A3SP", &dma0_device }, | ||
764 | { "A3SP", &dma1_device }, | ||
765 | { "A3SP", &dma2_device }, | ||
766 | { "A3SP", &usb_dma_device }, | ||
755 | }; | 767 | }; |
756 | 768 | ||
757 | /* I2C work-around */ | 769 | /* I2C work-around */ |
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 645d7cca6238..6156d172cf31 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c | |||
@@ -66,6 +66,7 @@ static struct map_desc r8a7779_io_desc[] __initdata = { | |||
66 | 66 | ||
67 | void __init r8a7779_map_io(void) | 67 | void __init r8a7779_map_io(void) |
68 | { | 68 | { |
69 | debug_ll_io_init(); | ||
69 | iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc)); | 70 | iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc)); |
70 | } | 71 | } |
71 | 72 | ||
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index a669377aea57..3dd6edd9bd1d 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2013 Renesas Solutions Corp. | 4 | * Copyright (C) 2013 Renesas Solutions Corp. |
5 | * Copyright (C) 2013 Magnus Damm | 5 | * Copyright (C) 2013 Magnus Damm |
6 | * Copyright (C) 2014 Ulrich Hecht | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -20,6 +21,7 @@ | |||
20 | #include <linux/dma-contiguous.h> | 21 | #include <linux/dma-contiguous.h> |
21 | #include <linux/io.h> | 22 | #include <linux/io.h> |
22 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/of.h> | ||
23 | #include <linux/of_fdt.h> | 25 | #include <linux/of_fdt.h> |
24 | #include <asm/mach/arch.h> | 26 | #include <asm/mach/arch.h> |
25 | #include "common.h" | 27 | #include "common.h" |
@@ -50,37 +52,61 @@ void __init rcar_gen2_timer_init(void) | |||
50 | { | 52 | { |
51 | #if defined(CONFIG_ARM_ARCH_TIMER) || defined(CONFIG_COMMON_CLK) | 53 | #if defined(CONFIG_ARM_ARCH_TIMER) || defined(CONFIG_COMMON_CLK) |
52 | u32 mode = rcar_gen2_read_mode_pins(); | 54 | u32 mode = rcar_gen2_read_mode_pins(); |
55 | bool is_e2 = (bool)of_find_compatible_node(NULL, NULL, | ||
56 | "renesas,r8a7794"); | ||
53 | #endif | 57 | #endif |
54 | #ifdef CONFIG_ARM_ARCH_TIMER | 58 | #ifdef CONFIG_ARM_ARCH_TIMER |
55 | void __iomem *base; | 59 | void __iomem *base; |
56 | int extal_mhz = 0; | 60 | int extal_mhz = 0; |
57 | u32 freq; | 61 | u32 freq; |
58 | 62 | ||
59 | /* At Linux boot time the r8a7790 arch timer comes up | 63 | if (is_e2) { |
60 | * with the counter disabled. Moreover, it may also report | 64 | freq = 260000000 / 8; /* ZS / 8 */ |
61 | * a potentially incorrect fixed 13 MHz frequency. To be | 65 | /* CNTVOFF has to be initialized either from non-secure |
62 | * correct these registers need to be updated to use the | 66 | * Hypervisor mode or secure Monitor mode with SCR.NS==1. |
63 | * frequency EXTAL / 2 which can be determined by the MD pins. | 67 | * If TrustZone is enabled then it should be handled by the |
64 | */ | 68 | * secure code. |
65 | 69 | */ | |
66 | switch (mode & (MD(14) | MD(13))) { | 70 | asm volatile( |
67 | case 0: | 71 | " cps 0x16\n" |
68 | extal_mhz = 15; | 72 | " mrc p15, 0, r1, c1, c1, 0\n" |
69 | break; | 73 | " orr r0, r1, #1\n" |
70 | case MD(13): | 74 | " mcr p15, 0, r0, c1, c1, 0\n" |
71 | extal_mhz = 20; | 75 | " isb\n" |
72 | break; | 76 | " mov r0, #0\n" |
73 | case MD(14): | 77 | " mcrr p15, 4, r0, r0, c14\n" |
74 | extal_mhz = 26; | 78 | " isb\n" |
75 | break; | 79 | " mcr p15, 0, r1, c1, c1, 0\n" |
76 | case MD(13) | MD(14): | 80 | " isb\n" |
77 | extal_mhz = 30; | 81 | " cps 0x13\n" |
78 | break; | 82 | : : : "r0", "r1"); |
83 | } else { | ||
84 | /* At Linux boot time the r8a7790 arch timer comes up | ||
85 | * with the counter disabled. Moreover, it may also report | ||
86 | * a potentially incorrect fixed 13 MHz frequency. To be | ||
87 | * correct these registers need to be updated to use the | ||
88 | * frequency EXTAL / 2 which can be determined by the MD pins. | ||
89 | */ | ||
90 | |||
91 | switch (mode & (MD(14) | MD(13))) { | ||
92 | case 0: | ||
93 | extal_mhz = 15; | ||
94 | break; | ||
95 | case MD(13): | ||
96 | extal_mhz = 20; | ||
97 | break; | ||
98 | case MD(14): | ||
99 | extal_mhz = 26; | ||
100 | break; | ||
101 | case MD(13) | MD(14): | ||
102 | extal_mhz = 30; | ||
103 | break; | ||
104 | } | ||
105 | |||
106 | /* The arch timer frequency equals EXTAL / 2 */ | ||
107 | freq = extal_mhz * (1000000 / 2); | ||
79 | } | 108 | } |
80 | 109 | ||
81 | /* The arch timer frequency equals EXTAL / 2 */ | ||
82 | freq = extal_mhz * (1000000 / 2); | ||
83 | |||
84 | /* Remap "armgcnt address map" space */ | 110 | /* Remap "armgcnt address map" space */ |
85 | base = ioremap(0xe6080000, PAGE_SIZE); | 111 | base = ioremap(0xe6080000, PAGE_SIZE); |
86 | 112 | ||
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index ca2b80b9bc90..458a2cfad417 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c | |||
@@ -56,6 +56,7 @@ static struct map_desc sh7372_io_desc[] __initdata = { | |||
56 | 56 | ||
57 | void __init sh7372_map_io(void) | 57 | void __init sh7372_map_io(void) |
58 | { | 58 | { |
59 | debug_ll_io_init(); | ||
59 | iotable_init(sh7372_io_desc, ARRAY_SIZE(sh7372_io_desc)); | 60 | iotable_init(sh7372_io_desc, ARRAY_SIZE(sh7372_io_desc)); |
60 | } | 61 | } |
61 | 62 | ||
@@ -1008,6 +1009,7 @@ DT_MACHINE_START(SH7372_DT, "Generic SH7372 (Flattened Device Tree)") | |||
1008 | .init_irq = sh7372_init_irq, | 1009 | .init_irq = sh7372_init_irq, |
1009 | .handle_irq = shmobile_handle_irq_intc, | 1010 | .handle_irq = shmobile_handle_irq_intc, |
1010 | .init_machine = sh7372_add_standard_devices_dt, | 1011 | .init_machine = sh7372_add_standard_devices_dt, |
1012 | .init_late = shmobile_init_late, | ||
1011 | .dt_compat = sh7372_boards_compat_dt, | 1013 | .dt_compat = sh7372_boards_compat_dt, |
1012 | MACHINE_END | 1014 | MACHINE_END |
1013 | 1015 | ||
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 1ff4bd65e647..93ebe3430bfe 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c | |||
@@ -55,6 +55,7 @@ static struct map_desc sh73a0_io_desc[] __initdata = { | |||
55 | 55 | ||
56 | void __init sh73a0_map_io(void) | 56 | void __init sh73a0_map_io(void) |
57 | { | 57 | { |
58 | debug_ll_io_init(); | ||
58 | iotable_init(sh73a0_io_desc, ARRAY_SIZE(sh73a0_io_desc)); | 59 | iotable_init(sh73a0_io_desc, ARRAY_SIZE(sh73a0_io_desc)); |
59 | } | 60 | } |
60 | 61 | ||
@@ -786,6 +787,13 @@ void __init sh73a0_add_standard_devices_dt(void) | |||
786 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 787 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
787 | } | 788 | } |
788 | 789 | ||
790 | #define RESCNT2 IOMEM(0xe6188020) | ||
791 | static void sh73a0_restart(enum reboot_mode mode, const char *cmd) | ||
792 | { | ||
793 | /* Do soft power on reset */ | ||
794 | writel((1 << 31), RESCNT2); | ||
795 | } | ||
796 | |||
789 | static const char *sh73a0_boards_compat_dt[] __initdata = { | 797 | static const char *sh73a0_boards_compat_dt[] __initdata = { |
790 | "renesas,sh73a0", | 798 | "renesas,sh73a0", |
791 | NULL, | 799 | NULL, |
@@ -797,6 +805,7 @@ DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)") | |||
797 | .init_early = shmobile_init_delay, | 805 | .init_early = shmobile_init_delay, |
798 | .init_machine = sh73a0_add_standard_devices_dt, | 806 | .init_machine = sh73a0_add_standard_devices_dt, |
799 | .init_late = shmobile_init_late, | 807 | .init_late = shmobile_init_late, |
808 | .restart = sh73a0_restart, | ||
800 | .dt_compat = sh73a0_boards_compat_dt, | 809 | .dt_compat = sh73a0_boards_compat_dt, |
801 | MACHINE_END | 810 | MACHINE_END |
802 | #endif /* CONFIG_USE_OF */ | 811 | #endif /* CONFIG_USE_OF */ |
diff --git a/arch/arm/mach-shmobile/smp-r8a7790.c b/arch/arm/mach-shmobile/smp-r8a7790.c index 2311694636e1..9c3da1345b8b 100644 --- a/arch/arm/mach-shmobile/smp-r8a7790.c +++ b/arch/arm/mach-shmobile/smp-r8a7790.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/smp_plat.h> | 21 | #include <asm/smp_plat.h> |
22 | 22 | ||
23 | #include "common.h" | 23 | #include "common.h" |
24 | #include "platsmp-apmu.h" | ||
24 | #include "pm-rcar.h" | 25 | #include "pm-rcar.h" |
25 | #include "r8a7790.h" | 26 | #include "r8a7790.h" |
26 | 27 | ||
@@ -34,10 +35,23 @@ static struct rcar_sysc_ch r8a7790_ca7_scu = { | |||
34 | .isr_bit = 21, /* CA7-SCU */ | 35 | .isr_bit = 21, /* CA7-SCU */ |
35 | }; | 36 | }; |
36 | 37 | ||
38 | static struct rcar_apmu_config r8a7790_apmu_config[] = { | ||
39 | { | ||
40 | .iomem = DEFINE_RES_MEM(0xe6152000, 0x88), | ||
41 | .cpus = { 0, 1, 2, 3 }, | ||
42 | }, | ||
43 | { | ||
44 | .iomem = DEFINE_RES_MEM(0xe6151000, 0x88), | ||
45 | .cpus = { 0x100, 0x0101, 0x102, 0x103 }, | ||
46 | } | ||
47 | }; | ||
48 | |||
37 | static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus) | 49 | static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus) |
38 | { | 50 | { |
39 | /* let APMU code install data related to shmobile_boot_vector */ | 51 | /* let APMU code install data related to shmobile_boot_vector */ |
40 | shmobile_smp_apmu_prepare_cpus(max_cpus); | 52 | shmobile_smp_apmu_prepare_cpus(max_cpus, |
53 | r8a7790_apmu_config, | ||
54 | ARRAY_SIZE(r8a7790_apmu_config)); | ||
41 | 55 | ||
42 | /* turn on power to SCU */ | 56 | /* turn on power to SCU */ |
43 | r8a7790_pm_init(); | 57 | r8a7790_pm_init(); |
diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c index f743386166fb..7e49e0a52e32 100644 --- a/arch/arm/mach-shmobile/smp-r8a7791.c +++ b/arch/arm/mach-shmobile/smp-r8a7791.c | |||
@@ -21,13 +21,23 @@ | |||
21 | #include <asm/smp_plat.h> | 21 | #include <asm/smp_plat.h> |
22 | 22 | ||
23 | #include "common.h" | 23 | #include "common.h" |
24 | #include "platsmp-apmu.h" | ||
24 | #include "r8a7791.h" | 25 | #include "r8a7791.h" |
25 | #include "rcar-gen2.h" | 26 | #include "rcar-gen2.h" |
26 | 27 | ||
28 | static struct rcar_apmu_config r8a7791_apmu_config[] = { | ||
29 | { | ||
30 | .iomem = DEFINE_RES_MEM(0xe6152000, 0x88), | ||
31 | .cpus = { 0, 1 }, | ||
32 | } | ||
33 | }; | ||
34 | |||
27 | static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus) | 35 | static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus) |
28 | { | 36 | { |
29 | /* let APMU code install data related to shmobile_boot_vector */ | 37 | /* let APMU code install data related to shmobile_boot_vector */ |
30 | shmobile_smp_apmu_prepare_cpus(max_cpus); | 38 | shmobile_smp_apmu_prepare_cpus(max_cpus, |
39 | r8a7791_apmu_config, | ||
40 | ARRAY_SIZE(r8a7791_apmu_config)); | ||
31 | 41 | ||
32 | r8a7791_pm_init(); | 42 | r8a7791_pm_init(); |
33 | } | 43 | } |
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c index 1081b763e0f3..f1d027aa7a81 100644 --- a/arch/arm/mach-shmobile/timer.c +++ b/arch/arm/mach-shmobile/timer.c | |||
@@ -40,6 +40,7 @@ void __init shmobile_init_delay(void) | |||
40 | struct device_node *np, *cpus; | 40 | struct device_node *np, *cpus; |
41 | bool is_a7_a8_a9 = false; | 41 | bool is_a7_a8_a9 = false; |
42 | bool is_a15 = false; | 42 | bool is_a15 = false; |
43 | bool has_arch_timer = false; | ||
43 | u32 max_freq = 0; | 44 | u32 max_freq = 0; |
44 | 45 | ||
45 | cpus = of_find_node_by_path("/cpus"); | 46 | cpus = of_find_node_by_path("/cpus"); |
@@ -52,12 +53,16 @@ void __init shmobile_init_delay(void) | |||
52 | if (!of_property_read_u32(np, "clock-frequency", &freq)) | 53 | if (!of_property_read_u32(np, "clock-frequency", &freq)) |
53 | max_freq = max(max_freq, freq); | 54 | max_freq = max(max_freq, freq); |
54 | 55 | ||
55 | if (of_device_is_compatible(np, "arm,cortex-a7") || | 56 | if (of_device_is_compatible(np, "arm,cortex-a8") || |
56 | of_device_is_compatible(np, "arm,cortex-a8") || | 57 | of_device_is_compatible(np, "arm,cortex-a9")) { |
57 | of_device_is_compatible(np, "arm,cortex-a9")) | ||
58 | is_a7_a8_a9 = true; | 58 | is_a7_a8_a9 = true; |
59 | else if (of_device_is_compatible(np, "arm,cortex-a15")) | 59 | } else if (of_device_is_compatible(np, "arm,cortex-a7")) { |
60 | is_a7_a8_a9 = true; | ||
61 | has_arch_timer = true; | ||
62 | } else if (of_device_is_compatible(np, "arm,cortex-a15")) { | ||
60 | is_a15 = true; | 63 | is_a15 = true; |
64 | has_arch_timer = true; | ||
65 | } | ||
61 | } | 66 | } |
62 | 67 | ||
63 | of_node_put(cpus); | 68 | of_node_put(cpus); |
@@ -65,10 +70,12 @@ void __init shmobile_init_delay(void) | |||
65 | if (!max_freq) | 70 | if (!max_freq) |
66 | return; | 71 | return; |
67 | 72 | ||
68 | if (is_a7_a8_a9) | 73 | if (!has_arch_timer || !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) { |
69 | shmobile_setup_delay_hz(max_freq, 1, 3); | 74 | if (is_a7_a8_a9) |
70 | else if (is_a15 && !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) | 75 | shmobile_setup_delay_hz(max_freq, 1, 3); |
71 | shmobile_setup_delay_hz(max_freq, 2, 4); | 76 | else if (is_a15) |
77 | shmobile_setup_delay_hz(max_freq, 2, 4); | ||
78 | } | ||
72 | } | 79 | } |
73 | 80 | ||
74 | static void __init shmobile_late_time_init(void) | 81 | static void __init shmobile_late_time_init(void) |
diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h index 60c443dadb58..483cb467bf65 100644 --- a/arch/arm/mach-socfpga/core.h +++ b/arch/arm/mach-socfpga/core.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #define __MACH_CORE_H | 21 | #define __MACH_CORE_H |
22 | 22 | ||
23 | #define SOCFPGA_RSTMGR_CTRL 0x04 | 23 | #define SOCFPGA_RSTMGR_CTRL 0x04 |
24 | #define SOCFPGA_RSTMGR_MODMPURST 0x10 | ||
24 | #define SOCFPGA_RSTMGR_MODPERRST 0x14 | 25 | #define SOCFPGA_RSTMGR_MODPERRST 0x14 |
25 | #define SOCFPGA_RSTMGR_BRGMODRST 0x1c | 26 | #define SOCFPGA_RSTMGR_BRGMODRST 0x1c |
26 | 27 | ||
@@ -28,6 +29,8 @@ | |||
28 | #define RSTMGR_CTRL_SWCOLDRSTREQ 0x1 /* Cold Reset */ | 29 | #define RSTMGR_CTRL_SWCOLDRSTREQ 0x1 /* Cold Reset */ |
29 | #define RSTMGR_CTRL_SWWARMRSTREQ 0x2 /* Warm Reset */ | 30 | #define RSTMGR_CTRL_SWWARMRSTREQ 0x2 /* Warm Reset */ |
30 | 31 | ||
32 | #define RSTMGR_MPUMODRST_CPU1 0x2 /* CPU1 Reset */ | ||
33 | |||
31 | extern void socfpga_secondary_startup(void); | 34 | extern void socfpga_secondary_startup(void); |
32 | extern void __iomem *socfpga_scu_base_addr; | 35 | extern void __iomem *socfpga_scu_base_addr; |
33 | 36 | ||
diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c index 16ca97b039f9..c64d89b7c0ca 100644 --- a/arch/arm/mach-socfpga/platsmp.c +++ b/arch/arm/mach-socfpga/platsmp.c | |||
@@ -34,17 +34,21 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
34 | int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; | 34 | int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; |
35 | 35 | ||
36 | if (socfpga_cpu1start_addr) { | 36 | if (socfpga_cpu1start_addr) { |
37 | /* This will put CPU #1 into reset. */ | ||
38 | writel(RSTMGR_MPUMODRST_CPU1, | ||
39 | rst_manager_base_addr + SOCFPGA_RSTMGR_MODMPURST); | ||
40 | |||
37 | memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); | 41 | memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); |
38 | 42 | ||
39 | __raw_writel(virt_to_phys(socfpga_secondary_startup), | 43 | writel(virt_to_phys(socfpga_secondary_startup), |
40 | (sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff))); | 44 | sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff)); |
41 | 45 | ||
42 | flush_cache_all(); | 46 | flush_cache_all(); |
43 | smp_wmb(); | 47 | smp_wmb(); |
44 | outer_clean_range(0, trampoline_size); | 48 | outer_clean_range(0, trampoline_size); |
45 | 49 | ||
46 | /* This will release CPU #1 out of reset.*/ | 50 | /* This will release CPU #1 out of reset. */ |
47 | __raw_writel(0, rst_manager_base_addr + 0x10); | 51 | writel(0, rst_manager_base_addr + SOCFPGA_RSTMGR_MODMPURST); |
48 | } | 52 | } |
49 | 53 | ||
50 | return 0; | 54 | return 0; |
@@ -86,10 +90,9 @@ static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus) | |||
86 | */ | 90 | */ |
87 | static void socfpga_cpu_die(unsigned int cpu) | 91 | static void socfpga_cpu_die(unsigned int cpu) |
88 | { | 92 | { |
89 | cpu_do_idle(); | 93 | /* Do WFI. If we wake up early, go back into WFI */ |
90 | 94 | while (1) | |
91 | /* We should have never returned from idle */ | 95 | cpu_do_idle(); |
92 | panic("cpu %d unexpectedly exit from shutdown\n", cpu); | ||
93 | } | 96 | } |
94 | 97 | ||
95 | struct smp_operations socfpga_smp_ops __initdata = { | 98 | struct smp_operations socfpga_smp_ops __initdata = { |
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 1aaa1e15ef70..a77604fbaf25 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig | |||
@@ -42,4 +42,11 @@ config MACH_SUN8I | |||
42 | select MFD_SUN6I_PRCM | 42 | select MFD_SUN6I_PRCM |
43 | select RESET_CONTROLLER | 43 | select RESET_CONTROLLER |
44 | 44 | ||
45 | config MACH_SUN9I | ||
46 | bool "Allwinner (sun9i) SoCs support" | ||
47 | default ARCH_SUNXI | ||
48 | select ARCH_HAS_RESET_CONTROLLER | ||
49 | select ARM_GIC | ||
50 | select RESET_CONTROLLER | ||
51 | |||
45 | endif | 52 | endif |
diff --git a/arch/arm/mach-sunxi/platsmp.c b/arch/arm/mach-sunxi/platsmp.c index c53077bb8c3f..e44d028555a4 100644 --- a/arch/arm/mach-sunxi/platsmp.c +++ b/arch/arm/mach-sunxi/platsmp.c | |||
@@ -116,7 +116,7 @@ static int sun6i_smp_boot_secondary(unsigned int cpu, | |||
116 | return 0; | 116 | return 0; |
117 | } | 117 | } |
118 | 118 | ||
119 | struct smp_operations sun6i_smp_ops __initdata = { | 119 | static struct smp_operations sun6i_smp_ops __initdata = { |
120 | .smp_prepare_cpus = sun6i_smp_prepare_cpus, | 120 | .smp_prepare_cpus = sun6i_smp_prepare_cpus, |
121 | .smp_boot_secondary = sun6i_smp_boot_secondary, | 121 | .smp_boot_secondary = sun6i_smp_boot_secondary, |
122 | }; | 122 | }; |
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c index d7598aeed803..1f986758784a 100644 --- a/arch/arm/mach-sunxi/sunxi.c +++ b/arch/arm/mach-sunxi/sunxi.c | |||
@@ -63,3 +63,12 @@ static const char * const sun8i_board_dt_compat[] = { | |||
63 | DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i (A23) Family") | 63 | DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i (A23) Family") |
64 | .dt_compat = sun8i_board_dt_compat, | 64 | .dt_compat = sun8i_board_dt_compat, |
65 | MACHINE_END | 65 | MACHINE_END |
66 | |||
67 | static const char * const sun9i_board_dt_compat[] = { | ||
68 | "allwinner,sun9i-a80", | ||
69 | NULL, | ||
70 | }; | ||
71 | |||
72 | DT_MACHINE_START(SUN9I_DT, "Allwinner sun9i Family") | ||
73 | .dt_compat = sun9i_board_dt_compat, | ||
74 | MACHINE_END | ||
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c index e3ebdce3e71f..425b6c8f0cb0 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra114.c +++ b/arch/arm/mach-tegra/cpuidle-tegra114.c | |||
@@ -49,7 +49,7 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev, | |||
49 | call_firmware_op(prepare_idle); | 49 | call_firmware_op(prepare_idle); |
50 | 50 | ||
51 | /* Do suspend by ourselves if the firmware does not implement it */ | 51 | /* Do suspend by ourselves if the firmware does not implement it */ |
52 | if (call_firmware_op(do_idle) == -ENOSYS) | 52 | if (call_firmware_op(do_idle, 0) == -ENOSYS) |
53 | cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); | 53 | cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); |
54 | 54 | ||
55 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); | 55 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); |
diff --git a/arch/arm/mach-u300/dummyspichip.c b/arch/arm/mach-u300/dummyspichip.c index ec0283cf9a32..131996805690 100644 --- a/arch/arm/mach-u300/dummyspichip.c +++ b/arch/arm/mach-u300/dummyspichip.c | |||
@@ -80,8 +80,8 @@ static ssize_t dummy_looptest(struct device *dev, | |||
80 | "in 8bit mode\n"); | 80 | "in 8bit mode\n"); |
81 | status = spi_w8r8(spi, 0xAA); | 81 | status = spi_w8r8(spi, 0xAA); |
82 | if (status < 0) | 82 | if (status < 0) |
83 | pr_warning("Siple test 1: FAILURE: spi_write_then_read " | 83 | pr_warn("Simple test 1: FAILURE: spi_write_then_read failed with status %d\n", |
84 | "failed with status %d\n", status); | 84 | status); |
85 | else | 85 | else |
86 | pr_info("Simple test 1: SUCCESS!\n"); | 86 | pr_info("Simple test 1: SUCCESS!\n"); |
87 | 87 | ||
@@ -89,8 +89,8 @@ static ssize_t dummy_looptest(struct device *dev, | |||
89 | "in 8bit mode (full FIFO)\n"); | 89 | "in 8bit mode (full FIFO)\n"); |
90 | status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8); | 90 | status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8); |
91 | if (status < 0) | 91 | if (status < 0) |
92 | pr_warning("Simple test 2: FAILURE: spi_write_then_read() " | 92 | pr_warn("Simple test 2: FAILURE: spi_write_then_read() failed with status %d\n", |
93 | "failed with status %d\n", status); | 93 | status); |
94 | else | 94 | else |
95 | pr_info("Simple test 2: SUCCESS!\n"); | 95 | pr_info("Simple test 2: SUCCESS!\n"); |
96 | 96 | ||
@@ -98,8 +98,8 @@ static ssize_t dummy_looptest(struct device *dev, | |||
98 | "in 8bit mode (see if we overflow FIFO)\n"); | 98 | "in 8bit mode (see if we overflow FIFO)\n"); |
99 | status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14); | 99 | status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14); |
100 | if (status < 0) | 100 | if (status < 0) |
101 | pr_warning("Simple test 3: FAILURE: failed with status %d " | 101 | pr_warn("Simple test 3: FAILURE: failed with status %d (probably FIFO overrun)\n", |
102 | "(probably FIFO overrun)\n", status); | 102 | status); |
103 | else | 103 | else |
104 | pr_info("Simple test 3: SUCCESS!\n"); | 104 | pr_info("Simple test 3: SUCCESS!\n"); |
105 | 105 | ||
@@ -107,14 +107,14 @@ static ssize_t dummy_looptest(struct device *dev, | |||
107 | "bytes garbage with spi_read() in 8bit mode\n"); | 107 | "bytes garbage with spi_read() in 8bit mode\n"); |
108 | status = spi_write(spi, &txbuf[0], 8); | 108 | status = spi_write(spi, &txbuf[0], 8); |
109 | if (status < 0) | 109 | if (status < 0) |
110 | pr_warning("Simple test 4 step 1: FAILURE: spi_write() " | 110 | pr_warn("Simple test 4 step 1: FAILURE: spi_write() failed with status %d\n", |
111 | "failed with status %d\n", status); | 111 | status); |
112 | else | 112 | else |
113 | pr_info("Simple test 4 step 1: SUCCESS!\n"); | 113 | pr_info("Simple test 4 step 1: SUCCESS!\n"); |
114 | status = spi_read(spi, &rxbuf[0], 8); | 114 | status = spi_read(spi, &rxbuf[0], 8); |
115 | if (status < 0) | 115 | if (status < 0) |
116 | pr_warning("Simple test 4 step 2: FAILURE: spi_read() " | 116 | pr_warn("Simple test 4 step 2: FAILURE: spi_read() failed with status %d\n", |
117 | "failed with status %d\n", status); | 117 | status); |
118 | else | 118 | else |
119 | pr_info("Simple test 4 step 2: SUCCESS!\n"); | 119 | pr_info("Simple test 4 step 2: SUCCESS!\n"); |
120 | 120 | ||
@@ -122,16 +122,14 @@ static ssize_t dummy_looptest(struct device *dev, | |||
122 | "14 bytes garbage with spi_read() in 8bit mode\n"); | 122 | "14 bytes garbage with spi_read() in 8bit mode\n"); |
123 | status = spi_write(spi, &txbuf[0], 14); | 123 | status = spi_write(spi, &txbuf[0], 14); |
124 | if (status < 0) | 124 | if (status < 0) |
125 | pr_warning("Simple test 5 step 1: FAILURE: spi_write() " | 125 | pr_warn("Simple test 5 step 1: FAILURE: spi_write() failed with status %d (probably FIFO overrun)\n", |
126 | "failed with status %d (probably FIFO overrun)\n", | 126 | status); |
127 | status); | ||
128 | else | 127 | else |
129 | pr_info("Simple test 5 step 1: SUCCESS!\n"); | 128 | pr_info("Simple test 5 step 1: SUCCESS!\n"); |
130 | status = spi_read(spi, &rxbuf[0], 14); | 129 | status = spi_read(spi, &rxbuf[0], 14); |
131 | if (status < 0) | 130 | if (status < 0) |
132 | pr_warning("Simple test 5 step 2: FAILURE: spi_read() " | 131 | pr_warn("Simple test 5 step 2: FAILURE: spi_read() failed with status %d (probably FIFO overrun)\n", |
133 | "failed with status %d (probably FIFO overrun)\n", | 132 | status); |
134 | status); | ||
135 | else | 133 | else |
136 | pr_info("Simple test 5: SUCCESS!\n"); | 134 | pr_info("Simple test 5: SUCCESS!\n"); |
137 | 135 | ||
@@ -140,16 +138,14 @@ static ssize_t dummy_looptest(struct device *dev, | |||
140 | DMA_TEST_SIZE, DMA_TEST_SIZE); | 138 | DMA_TEST_SIZE, DMA_TEST_SIZE); |
141 | status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE); | 139 | status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE); |
142 | if (status < 0) | 140 | if (status < 0) |
143 | pr_warning("Simple test 6 step 1: FAILURE: spi_write() " | 141 | pr_warn("Simple test 6 step 1: FAILURE: spi_write() failed with status %d (probably FIFO overrun)\n", |
144 | "failed with status %d (probably FIFO overrun)\n", | 142 | status); |
145 | status); | ||
146 | else | 143 | else |
147 | pr_info("Simple test 6 step 1: SUCCESS!\n"); | 144 | pr_info("Simple test 6 step 1: SUCCESS!\n"); |
148 | status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE); | 145 | status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE); |
149 | if (status < 0) | 146 | if (status < 0) |
150 | pr_warning("Simple test 6 step 2: FAILURE: spi_read() " | 147 | pr_warn("Simple test 6 step 2: FAILURE: spi_read() failed with status %d (probably FIFO overrun)\n", |
151 | "failed with status %d (probably FIFO overrun)\n", | 148 | status); |
152 | status); | ||
153 | else | 149 | else |
154 | pr_info("Simple test 6: SUCCESS!\n"); | 150 | pr_info("Simple test 6: SUCCESS!\n"); |
155 | 151 | ||
@@ -169,18 +165,17 @@ static ssize_t dummy_looptest(struct device *dev, | |||
169 | pr_info("Simple test 7: SUCCESS! (expected failure with " | 165 | pr_info("Simple test 7: SUCCESS! (expected failure with " |
170 | "status EIO)\n"); | 166 | "status EIO)\n"); |
171 | else if (status < 0) | 167 | else if (status < 0) |
172 | pr_warning("Siple test 7: FAILURE: spi_write_then_read " | 168 | pr_warn("Simple test 7: FAILURE: spi_write_then_read failed with status %d\n", |
173 | "failed with status %d\n", status); | 169 | status); |
174 | else | 170 | else |
175 | pr_warning("Siple test 7: FAILURE: spi_write_then_read " | 171 | pr_warn("Simple test 7: FAILURE: spi_write_then_read succeeded but it was expected to fail!\n"); |
176 | "succeeded but it was expected to fail!\n"); | ||
177 | 172 | ||
178 | pr_info("Simple test 8: write 8 bytes, read back 8 bytes garbage " | 173 | pr_info("Simple test 8: write 8 bytes, read back 8 bytes garbage " |
179 | "in 16bit mode (full FIFO)\n"); | 174 | "in 16bit mode (full FIFO)\n"); |
180 | status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8); | 175 | status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8); |
181 | if (status < 0) | 176 | if (status < 0) |
182 | pr_warning("Simple test 8: FAILURE: spi_write_then_read() " | 177 | pr_warn("Simple test 8: FAILURE: spi_write_then_read() failed with status %d\n", |
183 | "failed with status %d\n", status); | 178 | status); |
184 | else | 179 | else |
185 | pr_info("Simple test 8: SUCCESS!\n"); | 180 | pr_info("Simple test 8: SUCCESS!\n"); |
186 | 181 | ||
@@ -188,8 +183,8 @@ static ssize_t dummy_looptest(struct device *dev, | |||
188 | "in 16bit mode (see if we overflow FIFO)\n"); | 183 | "in 16bit mode (see if we overflow FIFO)\n"); |
189 | status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14); | 184 | status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14); |
190 | if (status < 0) | 185 | if (status < 0) |
191 | pr_warning("Simple test 9: FAILURE: failed with status %d " | 186 | pr_warn("Simple test 9: FAILURE: failed with status %d (probably FIFO overrun)\n", |
192 | "(probably FIFO overrun)\n", status); | 187 | status); |
193 | else | 188 | else |
194 | pr_info("Simple test 9: SUCCESS!\n"); | 189 | pr_info("Simple test 9: SUCCESS!\n"); |
195 | 190 | ||
@@ -198,17 +193,15 @@ static ssize_t dummy_looptest(struct device *dev, | |||
198 | DMA_TEST_SIZE, DMA_TEST_SIZE); | 193 | DMA_TEST_SIZE, DMA_TEST_SIZE); |
199 | status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE); | 194 | status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE); |
200 | if (status < 0) | 195 | if (status < 0) |
201 | pr_warning("Simple test 10 step 1: FAILURE: spi_write() " | 196 | pr_warn("Simple test 10 step 1: FAILURE: spi_write() failed with status %d (probably FIFO overrun)\n", |
202 | "failed with status %d (probably FIFO overrun)\n", | 197 | status); |
203 | status); | ||
204 | else | 198 | else |
205 | pr_info("Simple test 10 step 1: SUCCESS!\n"); | 199 | pr_info("Simple test 10 step 1: SUCCESS!\n"); |
206 | 200 | ||
207 | status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE); | 201 | status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE); |
208 | if (status < 0) | 202 | if (status < 0) |
209 | pr_warning("Simple test 10 step 2: FAILURE: spi_read() " | 203 | pr_warn("Simple test 10 step 2: FAILURE: spi_read() failed with status %d (probably FIFO overrun)\n", |
210 | "failed with status %d (probably FIFO overrun)\n", | 204 | status); |
211 | status); | ||
212 | else | 205 | else |
213 | pr_info("Simple test 10: SUCCESS!\n"); | 206 | pr_info("Simple test 10: SUCCESS!\n"); |
214 | 207 | ||
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 699e8601dbf0..c9ac19b24e5a 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig | |||
@@ -32,6 +32,7 @@ config UX500_SOC_DB8500 | |||
32 | select PINCTRL_AB8540 | 32 | select PINCTRL_AB8540 |
33 | select REGULATOR | 33 | select REGULATOR |
34 | select REGULATOR_DB8500_PRCMU | 34 | select REGULATOR_DB8500_PRCMU |
35 | select PM_GENERIC_DOMAINS if PM | ||
35 | 36 | ||
36 | config MACH_MOP500 | 37 | config MACH_MOP500 |
37 | bool "U8500 Development platform, MOP500 versions" | 38 | bool "U8500 Development platform, MOP500 versions" |
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 9741de956b3e..4418a5078833 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile | |||
@@ -9,5 +9,6 @@ obj-$(CONFIG_MACH_MOP500) += board-mop500-regulators.o \ | |||
9 | board-mop500-audio.o | 9 | board-mop500-audio.o |
10 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 10 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
11 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 11 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
12 | obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o | ||
12 | 13 | ||
13 | CFLAGS_hotplug.o += -march=armv7-a | 14 | CFLAGS_hotplug.o += -march=armv7-a |
diff --git a/arch/arm/mach-ux500/pm.c b/arch/arm/mach-ux500/pm.c index b80a9a2e356e..2cb587b50905 100644 --- a/arch/arm/mach-ux500/pm.c +++ b/arch/arm/mach-ux500/pm.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/platform_data/arm-ux500-pm.h> | 17 | #include <linux/platform_data/arm-ux500-pm.h> |
18 | 18 | ||
19 | #include "db8500-regs.h" | 19 | #include "db8500-regs.h" |
20 | #include "pm_domains.h" | ||
20 | 21 | ||
21 | /* ARM WFI Standby signal register */ | 22 | /* ARM WFI Standby signal register */ |
22 | #define PRCM_ARM_WFI_STANDBY (prcmu_base + 0x130) | 23 | #define PRCM_ARM_WFI_STANDBY (prcmu_base + 0x130) |
@@ -191,4 +192,7 @@ void __init ux500_pm_init(u32 phy_base, u32 size) | |||
191 | 192 | ||
192 | /* Set up ux500 suspend callbacks. */ | 193 | /* Set up ux500 suspend callbacks. */ |
193 | suspend_set_ops(UX500_SUSPEND_OPS); | 194 | suspend_set_ops(UX500_SUSPEND_OPS); |
195 | |||
196 | /* Initialize ux500 power domains */ | ||
197 | ux500_pm_domains_init(); | ||
194 | } | 198 | } |
diff --git a/arch/arm/mach-ux500/pm_domains.c b/arch/arm/mach-ux500/pm_domains.c new file mode 100644 index 000000000000..0d4b5b46f15b --- /dev/null +++ b/arch/arm/mach-ux500/pm_domains.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Linaro Ltd. | ||
3 | * | ||
4 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | * | ||
7 | * Implements PM domains using the generic PM domain for ux500. | ||
8 | */ | ||
9 | #include <linux/printk.h> | ||
10 | #include <linux/slab.h> | ||
11 | #include <linux/err.h> | ||
12 | #include <linux/of.h> | ||
13 | #include <linux/pm_domain.h> | ||
14 | |||
15 | #include <dt-bindings/arm/ux500_pm_domains.h> | ||
16 | #include "pm_domains.h" | ||
17 | |||
18 | static int pd_power_off(struct generic_pm_domain *domain) | ||
19 | { | ||
20 | /* | ||
21 | * Handle the gating of the PM domain regulator here. | ||
22 | * | ||
23 | * Drivers/subsystems handling devices in the PM domain needs to perform | ||
24 | * register context save/restore from their respective runtime PM | ||
25 | * callbacks, to be able to enable PM domain gating/ungating. | ||
26 | */ | ||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | static int pd_power_on(struct generic_pm_domain *domain) | ||
31 | { | ||
32 | /* | ||
33 | * Handle the ungating of the PM domain regulator here. | ||
34 | * | ||
35 | * Drivers/subsystems handling devices in the PM domain needs to perform | ||
36 | * register context save/restore from their respective runtime PM | ||
37 | * callbacks, to be able to enable PM domain gating/ungating. | ||
38 | */ | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static struct generic_pm_domain ux500_pm_domain_vape = { | ||
43 | .name = "VAPE", | ||
44 | .power_off = pd_power_off, | ||
45 | .power_on = pd_power_on, | ||
46 | }; | ||
47 | |||
48 | static struct generic_pm_domain *ux500_pm_domains[NR_DOMAINS] = { | ||
49 | [DOMAIN_VAPE] = &ux500_pm_domain_vape, | ||
50 | }; | ||
51 | |||
52 | static struct of_device_id ux500_pm_domain_matches[] = { | ||
53 | { .compatible = "stericsson,ux500-pm-domains", }, | ||
54 | { }, | ||
55 | }; | ||
56 | |||
57 | int __init ux500_pm_domains_init(void) | ||
58 | { | ||
59 | struct device_node *np; | ||
60 | struct genpd_onecell_data *genpd_data; | ||
61 | int i; | ||
62 | |||
63 | np = of_find_matching_node(NULL, ux500_pm_domain_matches); | ||
64 | if (!np) | ||
65 | return -ENODEV; | ||
66 | |||
67 | genpd_data = kzalloc(sizeof(*genpd_data), GFP_KERNEL); | ||
68 | if (!genpd_data) | ||
69 | return -ENOMEM; | ||
70 | |||
71 | genpd_data->domains = ux500_pm_domains; | ||
72 | genpd_data->num_domains = ARRAY_SIZE(ux500_pm_domains); | ||
73 | |||
74 | for (i = 0; i < ARRAY_SIZE(ux500_pm_domains); ++i) | ||
75 | pm_genpd_init(ux500_pm_domains[i], NULL, false); | ||
76 | |||
77 | of_genpd_add_provider_onecell(np, genpd_data); | ||
78 | return 0; | ||
79 | } | ||
diff --git a/arch/arm/mach-ux500/pm_domains.h b/arch/arm/mach-ux500/pm_domains.h new file mode 100644 index 000000000000..263d3ba97177 --- /dev/null +++ b/arch/arm/mach-ux500/pm_domains.h | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Linaro Ltd. | ||
3 | * | ||
4 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | */ | ||
7 | |||
8 | #ifndef __MACH_UX500_PM_DOMAINS_H | ||
9 | #define __MACH_UX500_PM_DOMAINS_H | ||
10 | |||
11 | #ifdef CONFIG_PM_GENERIC_DOMAINS | ||
12 | extern int __init ux500_pm_domains_init(void); | ||
13 | #else | ||
14 | static inline int ux500_pm_domains_init(void) { return 0; } | ||
15 | #endif | ||
16 | |||
17 | #endif | ||
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 7eb94e6fc376..ab906b801047 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -21,7 +21,7 @@ config CPU_ARM7TDMI | |||
21 | 21 | ||
22 | # ARM720T | 22 | # ARM720T |
23 | config CPU_ARM720T | 23 | config CPU_ARM720T |
24 | bool "Support ARM720T processor" if ARCH_INTEGRATOR | 24 | bool "Support ARM720T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR) |
25 | select CPU_32v4T | 25 | select CPU_32v4T |
26 | select CPU_ABRT_LV4T | 26 | select CPU_ABRT_LV4T |
27 | select CPU_CACHE_V4 | 27 | select CPU_CACHE_V4 |
@@ -39,7 +39,7 @@ config CPU_ARM720T | |||
39 | 39 | ||
40 | # ARM740T | 40 | # ARM740T |
41 | config CPU_ARM740T | 41 | config CPU_ARM740T |
42 | bool "Support ARM740T processor" if ARCH_INTEGRATOR | 42 | bool "Support ARM740T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR) |
43 | depends on !MMU | 43 | depends on !MMU |
44 | select CPU_32v4T | 44 | select CPU_32v4T |
45 | select CPU_ABRT_LV4T | 45 | select CPU_ABRT_LV4T |
@@ -71,7 +71,7 @@ config CPU_ARM9TDMI | |||
71 | 71 | ||
72 | # ARM920T | 72 | # ARM920T |
73 | config CPU_ARM920T | 73 | config CPU_ARM920T |
74 | bool "Support ARM920T processor" if ARCH_INTEGRATOR | 74 | bool "Support ARM920T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR) |
75 | select CPU_32v4T | 75 | select CPU_32v4T |
76 | select CPU_ABRT_EV4T | 76 | select CPU_ABRT_EV4T |
77 | select CPU_CACHE_V4WT | 77 | select CPU_CACHE_V4WT |
@@ -89,7 +89,7 @@ config CPU_ARM920T | |||
89 | 89 | ||
90 | # ARM922T | 90 | # ARM922T |
91 | config CPU_ARM922T | 91 | config CPU_ARM922T |
92 | bool "Support ARM922T processor" if ARCH_INTEGRATOR | 92 | bool "Support ARM922T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR) |
93 | select CPU_32v4T | 93 | select CPU_32v4T |
94 | select CPU_ABRT_EV4T | 94 | select CPU_ABRT_EV4T |
95 | select CPU_CACHE_V4WT | 95 | select CPU_CACHE_V4WT |
@@ -127,7 +127,7 @@ config CPU_ARM925T | |||
127 | 127 | ||
128 | # ARM926T | 128 | # ARM926T |
129 | config CPU_ARM926T | 129 | config CPU_ARM926T |
130 | bool "Support ARM926T processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB | 130 | bool "Support ARM926T processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V5) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB) |
131 | select CPU_32v5 | 131 | select CPU_32v5 |
132 | select CPU_ABRT_EV5TJ | 132 | select CPU_ABRT_EV5TJ |
133 | select CPU_CACHE_VIVT | 133 | select CPU_CACHE_VIVT |
@@ -163,7 +163,7 @@ config CPU_FA526 | |||
163 | 163 | ||
164 | # ARM940T | 164 | # ARM940T |
165 | config CPU_ARM940T | 165 | config CPU_ARM940T |
166 | bool "Support ARM940T processor" if ARCH_INTEGRATOR | 166 | bool "Support ARM940T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR) |
167 | depends on !MMU | 167 | depends on !MMU |
168 | select CPU_32v4T | 168 | select CPU_32v4T |
169 | select CPU_ABRT_NOMMU | 169 | select CPU_ABRT_NOMMU |
@@ -181,7 +181,7 @@ config CPU_ARM940T | |||
181 | 181 | ||
182 | # ARM946E-S | 182 | # ARM946E-S |
183 | config CPU_ARM946E | 183 | config CPU_ARM946E |
184 | bool "Support ARM946E-S processor" if ARCH_INTEGRATOR | 184 | bool "Support ARM946E-S processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR) |
185 | depends on !MMU | 185 | depends on !MMU |
186 | select CPU_32v5 | 186 | select CPU_32v5 |
187 | select CPU_ABRT_NOMMU | 187 | select CPU_ABRT_NOMMU |
@@ -198,7 +198,7 @@ config CPU_ARM946E | |||
198 | 198 | ||
199 | # ARM1020 - needs validating | 199 | # ARM1020 - needs validating |
200 | config CPU_ARM1020 | 200 | config CPU_ARM1020 |
201 | bool "Support ARM1020T (rev 0) processor" if ARCH_INTEGRATOR | 201 | bool "Support ARM1020T (rev 0) processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR) |
202 | select CPU_32v5 | 202 | select CPU_32v5 |
203 | select CPU_ABRT_EV4T | 203 | select CPU_ABRT_EV4T |
204 | select CPU_CACHE_V4WT | 204 | select CPU_CACHE_V4WT |
@@ -216,7 +216,7 @@ config CPU_ARM1020 | |||
216 | 216 | ||
217 | # ARM1020E - needs validating | 217 | # ARM1020E - needs validating |
218 | config CPU_ARM1020E | 218 | config CPU_ARM1020E |
219 | bool "Support ARM1020E processor" if ARCH_INTEGRATOR | 219 | bool "Support ARM1020E processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR) |
220 | depends on n | 220 | depends on n |
221 | select CPU_32v5 | 221 | select CPU_32v5 |
222 | select CPU_ABRT_EV4T | 222 | select CPU_ABRT_EV4T |
@@ -229,7 +229,7 @@ config CPU_ARM1020E | |||
229 | 229 | ||
230 | # ARM1022E | 230 | # ARM1022E |
231 | config CPU_ARM1022 | 231 | config CPU_ARM1022 |
232 | bool "Support ARM1022E processor" if ARCH_INTEGRATOR | 232 | bool "Support ARM1022E processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR) |
233 | select CPU_32v5 | 233 | select CPU_32v5 |
234 | select CPU_ABRT_EV4T | 234 | select CPU_ABRT_EV4T |
235 | select CPU_CACHE_VIVT | 235 | select CPU_CACHE_VIVT |
@@ -247,7 +247,7 @@ config CPU_ARM1022 | |||
247 | 247 | ||
248 | # ARM1026EJ-S | 248 | # ARM1026EJ-S |
249 | config CPU_ARM1026 | 249 | config CPU_ARM1026 |
250 | bool "Support ARM1026EJ-S processor" if ARCH_INTEGRATOR | 250 | bool "Support ARM1026EJ-S processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR) |
251 | select CPU_32v5 | 251 | select CPU_32v5 |
252 | select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10 | 252 | select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10 |
253 | select CPU_CACHE_VIVT | 253 | select CPU_CACHE_VIVT |
@@ -358,7 +358,7 @@ config CPU_PJ4B | |||
358 | 358 | ||
359 | # ARMv6 | 359 | # ARMv6 |
360 | config CPU_V6 | 360 | config CPU_V6 |
361 | bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX | 361 | bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX) |
362 | select CPU_32v6 | 362 | select CPU_32v6 |
363 | select CPU_ABRT_EV6 | 363 | select CPU_ABRT_EV6 |
364 | select CPU_CACHE_V6 | 364 | select CPU_CACHE_V6 |
@@ -371,7 +371,7 @@ config CPU_V6 | |||
371 | 371 | ||
372 | # ARMv6k | 372 | # ARMv6k |
373 | config CPU_V6K | 373 | config CPU_V6K |
374 | bool "Support ARM V6K processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX | 374 | bool "Support ARM V6K processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX) |
375 | select CPU_32v6 | 375 | select CPU_32v6 |
376 | select CPU_32v6K | 376 | select CPU_32v6K |
377 | select CPU_ABRT_EV6 | 377 | select CPU_ABRT_EV6 |
@@ -385,7 +385,7 @@ config CPU_V6K | |||
385 | 385 | ||
386 | # ARMv7 | 386 | # ARMv7 |
387 | config CPU_V7 | 387 | config CPU_V7 |
388 | bool "Support ARM V7 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX | 388 | bool "Support ARM V7 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V7) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX) |
389 | select CPU_32v6K | 389 | select CPU_32v6K |
390 | select CPU_32v7 | 390 | select CPU_32v7 |
391 | select CPU_ABRT_EV7 | 391 | select CPU_ABRT_EV7 |
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index f0a008496993..87746c37f030 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile | |||
@@ -35,6 +35,7 @@ obj-$(CONFIG_SAMSUNG_DMADEV) += dma-ops.o | |||
35 | # PM support | 35 | # PM support |
36 | 36 | ||
37 | obj-$(CONFIG_PM_SLEEP) += pm-common.o | 37 | obj-$(CONFIG_PM_SLEEP) += pm-common.o |
38 | obj-$(CONFIG_EXYNOS_CPU_SUSPEND) += pm-common.o | ||
38 | obj-$(CONFIG_SAMSUNG_PM) += pm.o | 39 | obj-$(CONFIG_SAMSUNG_PM) += pm.o |
39 | obj-$(CONFIG_SAMSUNG_PM_GPIO) += pm-gpio.o | 40 | obj-$(CONFIG_SAMSUNG_PM_GPIO) += pm-gpio.o |
40 | obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o | 41 | obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o |
diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c index f2cd6a2d40b4..e7ccd21a45c9 100644 --- a/drivers/bus/brcmstb_gisb.c +++ b/drivers/bus/brcmstb_gisb.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
24 | #include <linux/of.h> | 24 | #include <linux/of.h> |
25 | #include <linux/bitops.h> | 25 | #include <linux/bitops.h> |
26 | #include <linux/pm.h> | ||
26 | 27 | ||
27 | #include <asm/bug.h> | 28 | #include <asm/bug.h> |
28 | #include <asm/signal.h> | 29 | #include <asm/signal.h> |
@@ -48,6 +49,7 @@ struct brcmstb_gisb_arb_device { | |||
48 | struct list_head next; | 49 | struct list_head next; |
49 | u32 valid_mask; | 50 | u32 valid_mask; |
50 | const char *master_names[sizeof(u32) * BITS_PER_BYTE]; | 51 | const char *master_names[sizeof(u32) * BITS_PER_BYTE]; |
52 | u32 saved_timeout; | ||
51 | }; | 53 | }; |
52 | 54 | ||
53 | static LIST_HEAD(brcmstb_gisb_arb_device_list); | 55 | static LIST_HEAD(brcmstb_gisb_arb_device_list); |
@@ -160,12 +162,6 @@ static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr, | |||
160 | return ret; | 162 | return ret; |
161 | } | 163 | } |
162 | 164 | ||
163 | void __init brcmstb_hook_fault_code(void) | ||
164 | { | ||
165 | hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0, | ||
166 | "imprecise external abort"); | ||
167 | } | ||
168 | |||
169 | static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id) | 165 | static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id) |
170 | { | 166 | { |
171 | brcmstb_gisb_arb_decode_addr(dev_id, "timeout"); | 167 | brcmstb_gisb_arb_decode_addr(dev_id, "timeout"); |
@@ -261,12 +257,48 @@ static int brcmstb_gisb_arb_probe(struct platform_device *pdev) | |||
261 | 257 | ||
262 | list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list); | 258 | list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list); |
263 | 259 | ||
260 | hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0, | ||
261 | "imprecise external abort"); | ||
262 | |||
264 | dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n", | 263 | dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n", |
265 | gdev->base, timeout_irq, tea_irq); | 264 | gdev->base, timeout_irq, tea_irq); |
266 | 265 | ||
267 | return 0; | 266 | return 0; |
268 | } | 267 | } |
269 | 268 | ||
269 | #ifdef CONFIG_PM_SLEEP | ||
270 | static int brcmstb_gisb_arb_suspend(struct device *dev) | ||
271 | { | ||
272 | struct platform_device *pdev = to_platform_device(dev); | ||
273 | struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev); | ||
274 | |||
275 | gdev->saved_timeout = ioread32(gdev->base + ARB_TIMER); | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | /* Make sure we provide the same timeout value that was configured before, and | ||
281 | * do this before the GISB timeout interrupt handler has any chance to run. | ||
282 | */ | ||
283 | static int brcmstb_gisb_arb_resume_noirq(struct device *dev) | ||
284 | { | ||
285 | struct platform_device *pdev = to_platform_device(dev); | ||
286 | struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev); | ||
287 | |||
288 | iowrite32(gdev->saved_timeout, gdev->base + ARB_TIMER); | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | #else | ||
293 | #define brcmstb_gisb_arb_suspend NULL | ||
294 | #define brcmstb_gisb_arb_resume_noirq NULL | ||
295 | #endif | ||
296 | |||
297 | static const struct dev_pm_ops brcmstb_gisb_arb_pm_ops = { | ||
298 | .suspend = brcmstb_gisb_arb_suspend, | ||
299 | .resume_noirq = brcmstb_gisb_arb_resume_noirq, | ||
300 | }; | ||
301 | |||
270 | static const struct of_device_id brcmstb_gisb_arb_of_match[] = { | 302 | static const struct of_device_id brcmstb_gisb_arb_of_match[] = { |
271 | { .compatible = "brcm,gisb-arb" }, | 303 | { .compatible = "brcm,gisb-arb" }, |
272 | { }, | 304 | { }, |
@@ -278,6 +310,7 @@ static struct platform_driver brcmstb_gisb_arb_driver = { | |||
278 | .name = "brcm-gisb-arb", | 310 | .name = "brcm-gisb-arb", |
279 | .owner = THIS_MODULE, | 311 | .owner = THIS_MODULE, |
280 | .of_match_table = brcmstb_gisb_arb_of_match, | 312 | .of_match_table = brcmstb_gisb_arb_of_match, |
313 | .pm = &brcmstb_gisb_arb_pm_ops, | ||
281 | }, | 314 | }, |
282 | }; | 315 | }; |
283 | 316 | ||
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index 26c3779d871d..eb7682dc123b 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/of_address.h> | 57 | #include <linux/of_address.h> |
58 | #include <linux/debugfs.h> | 58 | #include <linux/debugfs.h> |
59 | #include <linux/log2.h> | 59 | #include <linux/log2.h> |
60 | #include <linux/syscore_ops.h> | ||
60 | 61 | ||
61 | /* | 62 | /* |
62 | * DDR target is the same on all platforms. | 63 | * DDR target is the same on all platforms. |
@@ -94,20 +95,42 @@ | |||
94 | 95 | ||
95 | #define DOVE_DDR_BASE_CS_OFF(n) ((n) << 4) | 96 | #define DOVE_DDR_BASE_CS_OFF(n) ((n) << 4) |
96 | 97 | ||
98 | /* Relative to mbusbridge_base */ | ||
99 | #define MBUS_BRIDGE_CTRL_OFF 0x0 | ||
100 | #define MBUS_BRIDGE_BASE_OFF 0x4 | ||
101 | |||
102 | /* Maximum number of windows, for all known platforms */ | ||
103 | #define MBUS_WINS_MAX 20 | ||
104 | |||
97 | struct mvebu_mbus_state; | 105 | struct mvebu_mbus_state; |
98 | 106 | ||
99 | struct mvebu_mbus_soc_data { | 107 | struct mvebu_mbus_soc_data { |
100 | unsigned int num_wins; | 108 | unsigned int num_wins; |
101 | unsigned int num_remappable_wins; | 109 | unsigned int num_remappable_wins; |
110 | bool has_mbus_bridge; | ||
102 | unsigned int (*win_cfg_offset)(const int win); | 111 | unsigned int (*win_cfg_offset)(const int win); |
103 | void (*setup_cpu_target)(struct mvebu_mbus_state *s); | 112 | void (*setup_cpu_target)(struct mvebu_mbus_state *s); |
113 | int (*save_cpu_target)(struct mvebu_mbus_state *s, | ||
114 | u32 *store_addr); | ||
104 | int (*show_cpu_target)(struct mvebu_mbus_state *s, | 115 | int (*show_cpu_target)(struct mvebu_mbus_state *s, |
105 | struct seq_file *seq, void *v); | 116 | struct seq_file *seq, void *v); |
106 | }; | 117 | }; |
107 | 118 | ||
119 | /* | ||
120 | * Used to store the state of one MBus window accross suspend/resume. | ||
121 | */ | ||
122 | struct mvebu_mbus_win_data { | ||
123 | u32 ctrl; | ||
124 | u32 base; | ||
125 | u32 remap_lo; | ||
126 | u32 remap_hi; | ||
127 | }; | ||
128 | |||
108 | struct mvebu_mbus_state { | 129 | struct mvebu_mbus_state { |
109 | void __iomem *mbuswins_base; | 130 | void __iomem *mbuswins_base; |
110 | void __iomem *sdramwins_base; | 131 | void __iomem *sdramwins_base; |
132 | void __iomem *mbusbridge_base; | ||
133 | phys_addr_t sdramwins_phys_base; | ||
111 | struct dentry *debugfs_root; | 134 | struct dentry *debugfs_root; |
112 | struct dentry *debugfs_sdram; | 135 | struct dentry *debugfs_sdram; |
113 | struct dentry *debugfs_devs; | 136 | struct dentry *debugfs_devs; |
@@ -115,6 +138,11 @@ struct mvebu_mbus_state { | |||
115 | struct resource pcie_io_aperture; | 138 | struct resource pcie_io_aperture; |
116 | const struct mvebu_mbus_soc_data *soc; | 139 | const struct mvebu_mbus_soc_data *soc; |
117 | int hw_io_coherency; | 140 | int hw_io_coherency; |
141 | |||
142 | /* Used during suspend/resume */ | ||
143 | u32 mbus_bridge_ctrl; | ||
144 | u32 mbus_bridge_base; | ||
145 | struct mvebu_mbus_win_data wins[MBUS_WINS_MAX]; | ||
118 | }; | 146 | }; |
119 | 147 | ||
120 | static struct mvebu_mbus_state mbus_state; | 148 | static struct mvebu_mbus_state mbus_state; |
@@ -516,6 +544,28 @@ mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus) | |||
516 | mvebu_mbus_dram_info.num_cs = cs; | 544 | mvebu_mbus_dram_info.num_cs = cs; |
517 | } | 545 | } |
518 | 546 | ||
547 | static int | ||
548 | mvebu_mbus_default_save_cpu_target(struct mvebu_mbus_state *mbus, | ||
549 | u32 *store_addr) | ||
550 | { | ||
551 | int i; | ||
552 | |||
553 | for (i = 0; i < 4; i++) { | ||
554 | u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i)); | ||
555 | u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i)); | ||
556 | |||
557 | writel(mbus->sdramwins_phys_base + DDR_BASE_CS_OFF(i), | ||
558 | store_addr++); | ||
559 | writel(base, store_addr++); | ||
560 | writel(mbus->sdramwins_phys_base + DDR_SIZE_CS_OFF(i), | ||
561 | store_addr++); | ||
562 | writel(size, store_addr++); | ||
563 | } | ||
564 | |||
565 | /* We've written 16 words to the store address */ | ||
566 | return 16; | ||
567 | } | ||
568 | |||
519 | static void __init | 569 | static void __init |
520 | mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus) | 570 | mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus) |
521 | { | 571 | { |
@@ -546,10 +596,35 @@ mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus) | |||
546 | mvebu_mbus_dram_info.num_cs = cs; | 596 | mvebu_mbus_dram_info.num_cs = cs; |
547 | } | 597 | } |
548 | 598 | ||
599 | static int | ||
600 | mvebu_mbus_dove_save_cpu_target(struct mvebu_mbus_state *mbus, | ||
601 | u32 *store_addr) | ||
602 | { | ||
603 | int i; | ||
604 | |||
605 | for (i = 0; i < 2; i++) { | ||
606 | u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i)); | ||
607 | |||
608 | writel(mbus->sdramwins_phys_base + DOVE_DDR_BASE_CS_OFF(i), | ||
609 | store_addr++); | ||
610 | writel(map, store_addr++); | ||
611 | } | ||
612 | |||
613 | /* We've written 4 words to the store address */ | ||
614 | return 4; | ||
615 | } | ||
616 | |||
617 | int mvebu_mbus_save_cpu_target(u32 *store_addr) | ||
618 | { | ||
619 | return mbus_state.soc->save_cpu_target(&mbus_state, store_addr); | ||
620 | } | ||
621 | |||
549 | static const struct mvebu_mbus_soc_data armada_370_xp_mbus_data = { | 622 | static const struct mvebu_mbus_soc_data armada_370_xp_mbus_data = { |
550 | .num_wins = 20, | 623 | .num_wins = 20, |
551 | .num_remappable_wins = 8, | 624 | .num_remappable_wins = 8, |
625 | .has_mbus_bridge = true, | ||
552 | .win_cfg_offset = armada_370_xp_mbus_win_offset, | 626 | .win_cfg_offset = armada_370_xp_mbus_win_offset, |
627 | .save_cpu_target = mvebu_mbus_default_save_cpu_target, | ||
553 | .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, | 628 | .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, |
554 | .show_cpu_target = mvebu_sdram_debug_show_orion, | 629 | .show_cpu_target = mvebu_sdram_debug_show_orion, |
555 | }; | 630 | }; |
@@ -558,6 +633,7 @@ static const struct mvebu_mbus_soc_data kirkwood_mbus_data = { | |||
558 | .num_wins = 8, | 633 | .num_wins = 8, |
559 | .num_remappable_wins = 4, | 634 | .num_remappable_wins = 4, |
560 | .win_cfg_offset = orion_mbus_win_offset, | 635 | .win_cfg_offset = orion_mbus_win_offset, |
636 | .save_cpu_target = mvebu_mbus_default_save_cpu_target, | ||
561 | .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, | 637 | .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, |
562 | .show_cpu_target = mvebu_sdram_debug_show_orion, | 638 | .show_cpu_target = mvebu_sdram_debug_show_orion, |
563 | }; | 639 | }; |
@@ -566,6 +642,7 @@ static const struct mvebu_mbus_soc_data dove_mbus_data = { | |||
566 | .num_wins = 8, | 642 | .num_wins = 8, |
567 | .num_remappable_wins = 4, | 643 | .num_remappable_wins = 4, |
568 | .win_cfg_offset = orion_mbus_win_offset, | 644 | .win_cfg_offset = orion_mbus_win_offset, |
645 | .save_cpu_target = mvebu_mbus_dove_save_cpu_target, | ||
569 | .setup_cpu_target = mvebu_mbus_dove_setup_cpu_target, | 646 | .setup_cpu_target = mvebu_mbus_dove_setup_cpu_target, |
570 | .show_cpu_target = mvebu_sdram_debug_show_dove, | 647 | .show_cpu_target = mvebu_sdram_debug_show_dove, |
571 | }; | 648 | }; |
@@ -578,6 +655,7 @@ static const struct mvebu_mbus_soc_data orion5x_4win_mbus_data = { | |||
578 | .num_wins = 8, | 655 | .num_wins = 8, |
579 | .num_remappable_wins = 4, | 656 | .num_remappable_wins = 4, |
580 | .win_cfg_offset = orion_mbus_win_offset, | 657 | .win_cfg_offset = orion_mbus_win_offset, |
658 | .save_cpu_target = mvebu_mbus_default_save_cpu_target, | ||
581 | .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, | 659 | .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, |
582 | .show_cpu_target = mvebu_sdram_debug_show_orion, | 660 | .show_cpu_target = mvebu_sdram_debug_show_orion, |
583 | }; | 661 | }; |
@@ -586,6 +664,7 @@ static const struct mvebu_mbus_soc_data orion5x_2win_mbus_data = { | |||
586 | .num_wins = 8, | 664 | .num_wins = 8, |
587 | .num_remappable_wins = 2, | 665 | .num_remappable_wins = 2, |
588 | .win_cfg_offset = orion_mbus_win_offset, | 666 | .win_cfg_offset = orion_mbus_win_offset, |
667 | .save_cpu_target = mvebu_mbus_default_save_cpu_target, | ||
589 | .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, | 668 | .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, |
590 | .show_cpu_target = mvebu_sdram_debug_show_orion, | 669 | .show_cpu_target = mvebu_sdram_debug_show_orion, |
591 | }; | 670 | }; |
@@ -594,6 +673,7 @@ static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = { | |||
594 | .num_wins = 14, | 673 | .num_wins = 14, |
595 | .num_remappable_wins = 8, | 674 | .num_remappable_wins = 8, |
596 | .win_cfg_offset = mv78xx0_mbus_win_offset, | 675 | .win_cfg_offset = mv78xx0_mbus_win_offset, |
676 | .save_cpu_target = mvebu_mbus_default_save_cpu_target, | ||
597 | .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, | 677 | .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, |
598 | .show_cpu_target = mvebu_sdram_debug_show_orion, | 678 | .show_cpu_target = mvebu_sdram_debug_show_orion, |
599 | }; | 679 | }; |
@@ -698,11 +778,73 @@ static __init int mvebu_mbus_debugfs_init(void) | |||
698 | } | 778 | } |
699 | fs_initcall(mvebu_mbus_debugfs_init); | 779 | fs_initcall(mvebu_mbus_debugfs_init); |
700 | 780 | ||
781 | static int mvebu_mbus_suspend(void) | ||
782 | { | ||
783 | struct mvebu_mbus_state *s = &mbus_state; | ||
784 | int win; | ||
785 | |||
786 | if (!s->mbusbridge_base) | ||
787 | return -ENODEV; | ||
788 | |||
789 | for (win = 0; win < s->soc->num_wins; win++) { | ||
790 | void __iomem *addr = s->mbuswins_base + | ||
791 | s->soc->win_cfg_offset(win); | ||
792 | |||
793 | s->wins[win].base = readl(addr + WIN_BASE_OFF); | ||
794 | s->wins[win].ctrl = readl(addr + WIN_CTRL_OFF); | ||
795 | |||
796 | if (win >= s->soc->num_remappable_wins) | ||
797 | continue; | ||
798 | |||
799 | s->wins[win].remap_lo = readl(addr + WIN_REMAP_LO_OFF); | ||
800 | s->wins[win].remap_hi = readl(addr + WIN_REMAP_HI_OFF); | ||
801 | } | ||
802 | |||
803 | s->mbus_bridge_ctrl = readl(s->mbusbridge_base + | ||
804 | MBUS_BRIDGE_CTRL_OFF); | ||
805 | s->mbus_bridge_base = readl(s->mbusbridge_base + | ||
806 | MBUS_BRIDGE_BASE_OFF); | ||
807 | |||
808 | return 0; | ||
809 | } | ||
810 | |||
811 | static void mvebu_mbus_resume(void) | ||
812 | { | ||
813 | struct mvebu_mbus_state *s = &mbus_state; | ||
814 | int win; | ||
815 | |||
816 | writel(s->mbus_bridge_ctrl, | ||
817 | s->mbusbridge_base + MBUS_BRIDGE_CTRL_OFF); | ||
818 | writel(s->mbus_bridge_base, | ||
819 | s->mbusbridge_base + MBUS_BRIDGE_BASE_OFF); | ||
820 | |||
821 | for (win = 0; win < s->soc->num_wins; win++) { | ||
822 | void __iomem *addr = s->mbuswins_base + | ||
823 | s->soc->win_cfg_offset(win); | ||
824 | |||
825 | writel(s->wins[win].base, addr + WIN_BASE_OFF); | ||
826 | writel(s->wins[win].ctrl, addr + WIN_CTRL_OFF); | ||
827 | |||
828 | if (win >= s->soc->num_remappable_wins) | ||
829 | continue; | ||
830 | |||
831 | writel(s->wins[win].remap_lo, addr + WIN_REMAP_LO_OFF); | ||
832 | writel(s->wins[win].remap_hi, addr + WIN_REMAP_HI_OFF); | ||
833 | } | ||
834 | } | ||
835 | |||
836 | struct syscore_ops mvebu_mbus_syscore_ops = { | ||
837 | .suspend = mvebu_mbus_suspend, | ||
838 | .resume = mvebu_mbus_resume, | ||
839 | }; | ||
840 | |||
701 | static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, | 841 | static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, |
702 | phys_addr_t mbuswins_phys_base, | 842 | phys_addr_t mbuswins_phys_base, |
703 | size_t mbuswins_size, | 843 | size_t mbuswins_size, |
704 | phys_addr_t sdramwins_phys_base, | 844 | phys_addr_t sdramwins_phys_base, |
705 | size_t sdramwins_size) | 845 | size_t sdramwins_size, |
846 | phys_addr_t mbusbridge_phys_base, | ||
847 | size_t mbusbridge_size) | ||
706 | { | 848 | { |
707 | int win; | 849 | int win; |
708 | 850 | ||
@@ -716,11 +858,26 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, | |||
716 | return -ENOMEM; | 858 | return -ENOMEM; |
717 | } | 859 | } |
718 | 860 | ||
861 | mbus->sdramwins_phys_base = sdramwins_phys_base; | ||
862 | |||
863 | if (mbusbridge_phys_base) { | ||
864 | mbus->mbusbridge_base = ioremap(mbusbridge_phys_base, | ||
865 | mbusbridge_size); | ||
866 | if (!mbus->mbusbridge_base) { | ||
867 | iounmap(mbus->sdramwins_base); | ||
868 | iounmap(mbus->mbuswins_base); | ||
869 | return -ENOMEM; | ||
870 | } | ||
871 | } else | ||
872 | mbus->mbusbridge_base = NULL; | ||
873 | |||
719 | for (win = 0; win < mbus->soc->num_wins; win++) | 874 | for (win = 0; win < mbus->soc->num_wins; win++) |
720 | mvebu_mbus_disable_window(mbus, win); | 875 | mvebu_mbus_disable_window(mbus, win); |
721 | 876 | ||
722 | mbus->soc->setup_cpu_target(mbus); | 877 | mbus->soc->setup_cpu_target(mbus); |
723 | 878 | ||
879 | register_syscore_ops(&mvebu_mbus_syscore_ops); | ||
880 | |||
724 | return 0; | 881 | return 0; |
725 | } | 882 | } |
726 | 883 | ||
@@ -746,7 +903,7 @@ int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base, | |||
746 | mbuswins_phys_base, | 903 | mbuswins_phys_base, |
747 | mbuswins_size, | 904 | mbuswins_size, |
748 | sdramwins_phys_base, | 905 | sdramwins_phys_base, |
749 | sdramwins_size); | 906 | sdramwins_size, 0, 0); |
750 | } | 907 | } |
751 | 908 | ||
752 | #ifdef CONFIG_OF | 909 | #ifdef CONFIG_OF |
@@ -887,7 +1044,7 @@ static void __init mvebu_mbus_get_pcie_resources(struct device_node *np, | |||
887 | 1044 | ||
888 | int __init mvebu_mbus_dt_init(bool is_coherent) | 1045 | int __init mvebu_mbus_dt_init(bool is_coherent) |
889 | { | 1046 | { |
890 | struct resource mbuswins_res, sdramwins_res; | 1047 | struct resource mbuswins_res, sdramwins_res, mbusbridge_res; |
891 | struct device_node *np, *controller; | 1048 | struct device_node *np, *controller; |
892 | const struct of_device_id *of_id; | 1049 | const struct of_device_id *of_id; |
893 | const __be32 *prop; | 1050 | const __be32 *prop; |
@@ -923,6 +1080,19 @@ int __init mvebu_mbus_dt_init(bool is_coherent) | |||
923 | return -EINVAL; | 1080 | return -EINVAL; |
924 | } | 1081 | } |
925 | 1082 | ||
1083 | /* | ||
1084 | * Set the resource to 0 so that it can be left unmapped by | ||
1085 | * mvebu_mbus_common_init() if the DT doesn't carry the | ||
1086 | * necessary information. This is needed to preserve backward | ||
1087 | * compatibility. | ||
1088 | */ | ||
1089 | memset(&mbusbridge_res, 0, sizeof(mbusbridge_res)); | ||
1090 | |||
1091 | if (mbus_state.soc->has_mbus_bridge) { | ||
1092 | if (of_address_to_resource(controller, 2, &mbusbridge_res)) | ||
1093 | pr_warn(FW_WARN "deprecated mbus-mvebu Device Tree, suspend/resume will not work\n"); | ||
1094 | } | ||
1095 | |||
926 | mbus_state.hw_io_coherency = is_coherent; | 1096 | mbus_state.hw_io_coherency = is_coherent; |
927 | 1097 | ||
928 | /* Get optional pcie-{mem,io}-aperture properties */ | 1098 | /* Get optional pcie-{mem,io}-aperture properties */ |
@@ -933,7 +1103,9 @@ int __init mvebu_mbus_dt_init(bool is_coherent) | |||
933 | mbuswins_res.start, | 1103 | mbuswins_res.start, |
934 | resource_size(&mbuswins_res), | 1104 | resource_size(&mbuswins_res), |
935 | sdramwins_res.start, | 1105 | sdramwins_res.start, |
936 | resource_size(&sdramwins_res)); | 1106 | resource_size(&sdramwins_res), |
1107 | mbusbridge_res.start, | ||
1108 | resource_size(&mbusbridge_res)); | ||
937 | if (ret) | 1109 | if (ret) |
938 | return ret; | 1110 | return ret; |
939 | 1111 | ||
diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index b7fcb469c87a..0d4d1216f2dd 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
22 | #include <linux/syscore_ops.h> | ||
22 | 23 | ||
23 | #include "common.h" | 24 | #include "common.h" |
24 | 25 | ||
@@ -177,14 +178,17 @@ struct clk_gating_ctrl { | |||
177 | spinlock_t *lock; | 178 | spinlock_t *lock; |
178 | struct clk **gates; | 179 | struct clk **gates; |
179 | int num_gates; | 180 | int num_gates; |
181 | void __iomem *base; | ||
182 | u32 saved_reg; | ||
180 | }; | 183 | }; |
181 | 184 | ||
182 | #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) | 185 | #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) |
183 | 186 | ||
187 | static struct clk_gating_ctrl *ctrl; | ||
188 | |||
184 | static struct clk *clk_gating_get_src( | 189 | static struct clk *clk_gating_get_src( |
185 | struct of_phandle_args *clkspec, void *data) | 190 | struct of_phandle_args *clkspec, void *data) |
186 | { | 191 | { |
187 | struct clk_gating_ctrl *ctrl = (struct clk_gating_ctrl *)data; | ||
188 | int n; | 192 | int n; |
189 | 193 | ||
190 | if (clkspec->args_count < 1) | 194 | if (clkspec->args_count < 1) |
@@ -199,15 +203,35 @@ static struct clk *clk_gating_get_src( | |||
199 | return ERR_PTR(-ENODEV); | 203 | return ERR_PTR(-ENODEV); |
200 | } | 204 | } |
201 | 205 | ||
206 | static int mvebu_clk_gating_suspend(void) | ||
207 | { | ||
208 | ctrl->saved_reg = readl(ctrl->base); | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static void mvebu_clk_gating_resume(void) | ||
213 | { | ||
214 | writel(ctrl->saved_reg, ctrl->base); | ||
215 | } | ||
216 | |||
217 | static struct syscore_ops clk_gate_syscore_ops = { | ||
218 | .suspend = mvebu_clk_gating_suspend, | ||
219 | .resume = mvebu_clk_gating_resume, | ||
220 | }; | ||
221 | |||
202 | void __init mvebu_clk_gating_setup(struct device_node *np, | 222 | void __init mvebu_clk_gating_setup(struct device_node *np, |
203 | const struct clk_gating_soc_desc *desc) | 223 | const struct clk_gating_soc_desc *desc) |
204 | { | 224 | { |
205 | struct clk_gating_ctrl *ctrl; | ||
206 | struct clk *clk; | 225 | struct clk *clk; |
207 | void __iomem *base; | 226 | void __iomem *base; |
208 | const char *default_parent = NULL; | 227 | const char *default_parent = NULL; |
209 | int n; | 228 | int n; |
210 | 229 | ||
230 | if (ctrl) { | ||
231 | pr_err("mvebu-clk-gating: cannot instantiate more than one gatable clock device\n"); | ||
232 | return; | ||
233 | } | ||
234 | |||
211 | base = of_iomap(np, 0); | 235 | base = of_iomap(np, 0); |
212 | if (WARN_ON(!base)) | 236 | if (WARN_ON(!base)) |
213 | return; | 237 | return; |
@@ -225,6 +249,8 @@ void __init mvebu_clk_gating_setup(struct device_node *np, | |||
225 | /* lock must already be initialized */ | 249 | /* lock must already be initialized */ |
226 | ctrl->lock = &ctrl_gating_lock; | 250 | ctrl->lock = &ctrl_gating_lock; |
227 | 251 | ||
252 | ctrl->base = base; | ||
253 | |||
228 | /* Count, allocate, and register clock gates */ | 254 | /* Count, allocate, and register clock gates */ |
229 | for (n = 0; desc[n].name;) | 255 | for (n = 0; desc[n].name;) |
230 | n++; | 256 | n++; |
@@ -246,6 +272,8 @@ void __init mvebu_clk_gating_setup(struct device_node *np, | |||
246 | 272 | ||
247 | of_clk_add_provider(np, clk_gating_get_src, ctrl); | 273 | of_clk_add_provider(np, clk_gating_get_src, ctrl); |
248 | 274 | ||
275 | register_syscore_ops(&clk_gate_syscore_ops); | ||
276 | |||
249 | return; | 277 | return; |
250 | gates_out: | 278 | gates_out: |
251 | kfree(ctrl); | 279 | kfree(ctrl); |
diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c index 00d1d00a41de..979e81389cdd 100644 --- a/drivers/clk/samsung/clk-exynos5440.c +++ b/drivers/clk/samsung/clk-exynos5440.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/clk-provider.h> | 15 | #include <linux/clk-provider.h> |
16 | #include <linux/of.h> | 16 | #include <linux/of.h> |
17 | #include <linux/of_address.h> | 17 | #include <linux/of_address.h> |
18 | #include <linux/notifier.h> | ||
19 | #include <linux/reboot.h> | ||
18 | 20 | ||
19 | #include "clk.h" | 21 | #include "clk.h" |
20 | #include "clk-pll.h" | 22 | #include "clk-pll.h" |
@@ -23,6 +25,8 @@ | |||
23 | #define CPU_CLK_STATUS 0xfc | 25 | #define CPU_CLK_STATUS 0xfc |
24 | #define MISC_DOUT1 0x558 | 26 | #define MISC_DOUT1 0x558 |
25 | 27 | ||
28 | static void __iomem *reg_base; | ||
29 | |||
26 | /* parent clock name list */ | 30 | /* parent clock name list */ |
27 | PNAME(mout_armclk_p) = { "cplla", "cpllb" }; | 31 | PNAME(mout_armclk_p) = { "cplla", "cpllb" }; |
28 | PNAME(mout_spi_p) = { "div125", "div200" }; | 32 | PNAME(mout_spi_p) = { "div125", "div200" }; |
@@ -89,10 +93,30 @@ static const struct of_device_id ext_clk_match[] __initconst = { | |||
89 | {}, | 93 | {}, |
90 | }; | 94 | }; |
91 | 95 | ||
96 | static int exynos5440_clk_restart_notify(struct notifier_block *this, | ||
97 | unsigned long code, void *unused) | ||
98 | { | ||
99 | u32 val, status; | ||
100 | |||
101 | status = readl_relaxed(reg_base + 0xbc); | ||
102 | val = readl_relaxed(reg_base + 0xcc); | ||
103 | val = (val & 0xffff0000) | (status & 0xffff); | ||
104 | writel_relaxed(val, reg_base + 0xcc); | ||
105 | |||
106 | return NOTIFY_DONE; | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * Exynos5440 Clock restart notifier, handles restart functionality | ||
111 | */ | ||
112 | static struct notifier_block exynos5440_clk_restart_handler = { | ||
113 | .notifier_call = exynos5440_clk_restart_notify, | ||
114 | .priority = 128, | ||
115 | }; | ||
116 | |||
92 | /* register exynos5440 clocks */ | 117 | /* register exynos5440 clocks */ |
93 | static void __init exynos5440_clk_init(struct device_node *np) | 118 | static void __init exynos5440_clk_init(struct device_node *np) |
94 | { | 119 | { |
95 | void __iomem *reg_base; | ||
96 | struct samsung_clk_provider *ctx; | 120 | struct samsung_clk_provider *ctx; |
97 | 121 | ||
98 | reg_base = of_iomap(np, 0); | 122 | reg_base = of_iomap(np, 0); |
@@ -125,6 +149,9 @@ static void __init exynos5440_clk_init(struct device_node *np) | |||
125 | 149 | ||
126 | samsung_clk_of_add_provider(np, ctx); | 150 | samsung_clk_of_add_provider(np, ctx); |
127 | 151 | ||
152 | if (register_restart_handler(&exynos5440_clk_restart_handler)) | ||
153 | pr_warn("exynos5440 clock can't register restart handler\n"); | ||
154 | |||
128 | pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk")); | 155 | pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk")); |
129 | pr_info("exynos5440 clock initialization complete\n"); | 156 | pr_info("exynos5440 clock initialization complete\n"); |
130 | } | 157 | } |
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index 79791e1bf282..85ac0dd501de 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c | |||
@@ -33,6 +33,9 @@ static const struct clk_ops dpll_m4xen_ck_ops = { | |||
33 | .recalc_rate = &omap4_dpll_regm4xen_recalc, | 33 | .recalc_rate = &omap4_dpll_regm4xen_recalc, |
34 | .round_rate = &omap4_dpll_regm4xen_round_rate, | 34 | .round_rate = &omap4_dpll_regm4xen_round_rate, |
35 | .set_rate = &omap3_noncore_dpll_set_rate, | 35 | .set_rate = &omap3_noncore_dpll_set_rate, |
36 | .set_parent = &omap3_noncore_dpll_set_parent, | ||
37 | .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, | ||
38 | .determine_rate = &omap4_dpll_regm4xen_determine_rate, | ||
36 | .get_parent = &omap2_init_dpll_parent, | 39 | .get_parent = &omap2_init_dpll_parent, |
37 | }; | 40 | }; |
38 | #else | 41 | #else |
@@ -53,6 +56,9 @@ static const struct clk_ops dpll_ck_ops = { | |||
53 | .recalc_rate = &omap3_dpll_recalc, | 56 | .recalc_rate = &omap3_dpll_recalc, |
54 | .round_rate = &omap2_dpll_round_rate, | 57 | .round_rate = &omap2_dpll_round_rate, |
55 | .set_rate = &omap3_noncore_dpll_set_rate, | 58 | .set_rate = &omap3_noncore_dpll_set_rate, |
59 | .set_parent = &omap3_noncore_dpll_set_parent, | ||
60 | .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, | ||
61 | .determine_rate = &omap3_noncore_dpll_determine_rate, | ||
56 | .get_parent = &omap2_init_dpll_parent, | 62 | .get_parent = &omap2_init_dpll_parent, |
57 | }; | 63 | }; |
58 | 64 | ||
@@ -61,6 +67,9 @@ static const struct clk_ops dpll_no_gate_ck_ops = { | |||
61 | .get_parent = &omap2_init_dpll_parent, | 67 | .get_parent = &omap2_init_dpll_parent, |
62 | .round_rate = &omap2_dpll_round_rate, | 68 | .round_rate = &omap2_dpll_round_rate, |
63 | .set_rate = &omap3_noncore_dpll_set_rate, | 69 | .set_rate = &omap3_noncore_dpll_set_rate, |
70 | .set_parent = &omap3_noncore_dpll_set_parent, | ||
71 | .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, | ||
72 | .determine_rate = &omap3_noncore_dpll_determine_rate, | ||
64 | }; | 73 | }; |
65 | #else | 74 | #else |
66 | static const struct clk_ops dpll_core_ck_ops = {}; | 75 | static const struct clk_ops dpll_core_ck_ops = {}; |
@@ -97,6 +106,9 @@ static const struct clk_ops omap3_dpll_ck_ops = { | |||
97 | .get_parent = &omap2_init_dpll_parent, | 106 | .get_parent = &omap2_init_dpll_parent, |
98 | .recalc_rate = &omap3_dpll_recalc, | 107 | .recalc_rate = &omap3_dpll_recalc, |
99 | .set_rate = &omap3_noncore_dpll_set_rate, | 108 | .set_rate = &omap3_noncore_dpll_set_rate, |
109 | .set_parent = &omap3_noncore_dpll_set_parent, | ||
110 | .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, | ||
111 | .determine_rate = &omap3_noncore_dpll_determine_rate, | ||
100 | .round_rate = &omap2_dpll_round_rate, | 112 | .round_rate = &omap2_dpll_round_rate, |
101 | }; | 113 | }; |
102 | 114 | ||
@@ -106,6 +118,9 @@ static const struct clk_ops omap3_dpll_per_ck_ops = { | |||
106 | .get_parent = &omap2_init_dpll_parent, | 118 | .get_parent = &omap2_init_dpll_parent, |
107 | .recalc_rate = &omap3_dpll_recalc, | 119 | .recalc_rate = &omap3_dpll_recalc, |
108 | .set_rate = &omap3_dpll4_set_rate, | 120 | .set_rate = &omap3_dpll4_set_rate, |
121 | .set_parent = &omap3_noncore_dpll_set_parent, | ||
122 | .set_rate_and_parent = &omap3_dpll4_set_rate_and_parent, | ||
123 | .determine_rate = &omap3_noncore_dpll_determine_rate, | ||
109 | .round_rate = &omap2_dpll_round_rate, | 124 | .round_rate = &omap2_dpll_round_rate, |
110 | }; | 125 | }; |
111 | #endif | 126 | #endif |
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 90420600e1eb..f657a48d20eb 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
@@ -32,6 +32,7 @@ config ARMADA_370_XP_TIMER | |||
32 | 32 | ||
33 | config MESON6_TIMER | 33 | config MESON6_TIMER |
34 | bool | 34 | bool |
35 | select CLKSRC_MMIO | ||
35 | 36 | ||
36 | config ORION_TIMER | 37 | config ORION_TIMER |
37 | select CLKSRC_OF | 38 | select CLKSRC_OF |
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 756f6f10efa0..fae0435cc23d 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
@@ -45,4 +45,5 @@ obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o | |||
45 | obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o | 45 | obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o |
46 | obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o | 46 | obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o |
47 | obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o | 47 | obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o |
48 | obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o | ||
48 | obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o | 49 | obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o |
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c index 0451e62fac7a..ff37d3abb806 100644 --- a/drivers/clocksource/time-armada-370-xp.c +++ b/drivers/clocksource/time-armada-370-xp.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/module.h> | 43 | #include <linux/module.h> |
44 | #include <linux/sched_clock.h> | 44 | #include <linux/sched_clock.h> |
45 | #include <linux/percpu.h> | 45 | #include <linux/percpu.h> |
46 | #include <linux/syscore_ops.h> | ||
46 | 47 | ||
47 | /* | 48 | /* |
48 | * Timer block registers. | 49 | * Timer block registers. |
@@ -223,6 +224,28 @@ static struct notifier_block armada_370_xp_timer_cpu_nb = { | |||
223 | .notifier_call = armada_370_xp_timer_cpu_notify, | 224 | .notifier_call = armada_370_xp_timer_cpu_notify, |
224 | }; | 225 | }; |
225 | 226 | ||
227 | static u32 timer0_ctrl_reg, timer0_local_ctrl_reg; | ||
228 | |||
229 | static int armada_370_xp_timer_suspend(void) | ||
230 | { | ||
231 | timer0_ctrl_reg = readl(timer_base + TIMER_CTRL_OFF); | ||
232 | timer0_local_ctrl_reg = readl(local_base + TIMER_CTRL_OFF); | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static void armada_370_xp_timer_resume(void) | ||
237 | { | ||
238 | writel(0xffffffff, timer_base + TIMER0_VAL_OFF); | ||
239 | writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); | ||
240 | writel(timer0_ctrl_reg, timer_base + TIMER_CTRL_OFF); | ||
241 | writel(timer0_local_ctrl_reg, local_base + TIMER_CTRL_OFF); | ||
242 | } | ||
243 | |||
244 | struct syscore_ops armada_370_xp_timer_syscore_ops = { | ||
245 | .suspend = armada_370_xp_timer_suspend, | ||
246 | .resume = armada_370_xp_timer_resume, | ||
247 | }; | ||
248 | |||
226 | static void __init armada_370_xp_timer_common_init(struct device_node *np) | 249 | static void __init armada_370_xp_timer_common_init(struct device_node *np) |
227 | { | 250 | { |
228 | u32 clr = 0, set = 0; | 251 | u32 clr = 0, set = 0; |
@@ -285,6 +308,8 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np) | |||
285 | /* Immediately configure the timer on the boot CPU */ | 308 | /* Immediately configure the timer on the boot CPU */ |
286 | if (!res) | 309 | if (!res) |
287 | armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt)); | 310 | armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt)); |
311 | |||
312 | register_syscore_ops(&armada_370_xp_timer_syscore_ops); | ||
288 | } | 313 | } |
289 | 314 | ||
290 | static void __init armada_xp_timer_init(struct device_node *np) | 315 | static void __init armada_xp_timer_init(struct device_node *np) |
diff --git a/drivers/clocksource/timer-integrator-ap.c b/drivers/clocksource/timer-integrator-ap.c new file mode 100644 index 000000000000..b9efd30513d5 --- /dev/null +++ b/drivers/clocksource/timer-integrator-ap.c | |||
@@ -0,0 +1,210 @@ | |||
1 | /* | ||
2 | * Integrator/AP timer driver | ||
3 | * Copyright (C) 2000-2003 Deep Blue Solutions Ltd | ||
4 | * Copyright (c) 2014, Linaro Limited | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/clk.h> | ||
22 | #include <linux/clocksource.h> | ||
23 | #include <linux/of_irq.h> | ||
24 | #include <linux/of_address.h> | ||
25 | #include <linux/of_platform.h> | ||
26 | #include <linux/clockchips.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/sched_clock.h> | ||
29 | #include <asm/hardware/arm_timer.h> | ||
30 | |||
31 | static void __iomem * sched_clk_base; | ||
32 | |||
33 | static u64 notrace integrator_read_sched_clock(void) | ||
34 | { | ||
35 | return -readl(sched_clk_base + TIMER_VALUE); | ||
36 | } | ||
37 | |||
38 | static void integrator_clocksource_init(unsigned long inrate, | ||
39 | void __iomem *base) | ||
40 | { | ||
41 | u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; | ||
42 | unsigned long rate = inrate; | ||
43 | |||
44 | if (rate >= 1500000) { | ||
45 | rate /= 16; | ||
46 | ctrl |= TIMER_CTRL_DIV16; | ||
47 | } | ||
48 | |||
49 | writel(0xffff, base + TIMER_LOAD); | ||
50 | writel(ctrl, base + TIMER_CTRL); | ||
51 | |||
52 | clocksource_mmio_init(base + TIMER_VALUE, "timer2", | ||
53 | rate, 200, 16, clocksource_mmio_readl_down); | ||
54 | |||
55 | sched_clk_base = base; | ||
56 | sched_clock_register(integrator_read_sched_clock, 16, rate); | ||
57 | } | ||
58 | |||
59 | static unsigned long timer_reload; | ||
60 | static void __iomem * clkevt_base; | ||
61 | |||
62 | /* | ||
63 | * IRQ handler for the timer | ||
64 | */ | ||
65 | static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id) | ||
66 | { | ||
67 | struct clock_event_device *evt = dev_id; | ||
68 | |||
69 | /* clear the interrupt */ | ||
70 | writel(1, clkevt_base + TIMER_INTCLR); | ||
71 | |||
72 | evt->event_handler(evt); | ||
73 | |||
74 | return IRQ_HANDLED; | ||
75 | } | ||
76 | |||
77 | static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) | ||
78 | { | ||
79 | u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE; | ||
80 | |||
81 | /* Disable timer */ | ||
82 | writel(ctrl, clkevt_base + TIMER_CTRL); | ||
83 | |||
84 | switch (mode) { | ||
85 | case CLOCK_EVT_MODE_PERIODIC: | ||
86 | /* Enable the timer and start the periodic tick */ | ||
87 | writel(timer_reload, clkevt_base + TIMER_LOAD); | ||
88 | ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; | ||
89 | writel(ctrl, clkevt_base + TIMER_CTRL); | ||
90 | break; | ||
91 | case CLOCK_EVT_MODE_ONESHOT: | ||
92 | /* Leave the timer disabled, .set_next_event will enable it */ | ||
93 | ctrl &= ~TIMER_CTRL_PERIODIC; | ||
94 | writel(ctrl, clkevt_base + TIMER_CTRL); | ||
95 | break; | ||
96 | case CLOCK_EVT_MODE_UNUSED: | ||
97 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
98 | case CLOCK_EVT_MODE_RESUME: | ||
99 | default: | ||
100 | /* Just leave in disabled state */ | ||
101 | break; | ||
102 | } | ||
103 | |||
104 | } | ||
105 | |||
106 | static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt) | ||
107 | { | ||
108 | unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); | ||
109 | |||
110 | writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); | ||
111 | writel(next, clkevt_base + TIMER_LOAD); | ||
112 | writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static struct clock_event_device integrator_clockevent = { | ||
118 | .name = "timer1", | ||
119 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
120 | .set_mode = clkevt_set_mode, | ||
121 | .set_next_event = clkevt_set_next_event, | ||
122 | .rating = 300, | ||
123 | }; | ||
124 | |||
125 | static struct irqaction integrator_timer_irq = { | ||
126 | .name = "timer", | ||
127 | .flags = IRQF_TIMER | IRQF_IRQPOLL, | ||
128 | .handler = integrator_timer_interrupt, | ||
129 | .dev_id = &integrator_clockevent, | ||
130 | }; | ||
131 | |||
132 | static void integrator_clockevent_init(unsigned long inrate, | ||
133 | void __iomem *base, int irq) | ||
134 | { | ||
135 | unsigned long rate = inrate; | ||
136 | unsigned int ctrl = 0; | ||
137 | |||
138 | clkevt_base = base; | ||
139 | /* Calculate and program a divisor */ | ||
140 | if (rate > 0x100000 * HZ) { | ||
141 | rate /= 256; | ||
142 | ctrl |= TIMER_CTRL_DIV256; | ||
143 | } else if (rate > 0x10000 * HZ) { | ||
144 | rate /= 16; | ||
145 | ctrl |= TIMER_CTRL_DIV16; | ||
146 | } | ||
147 | timer_reload = rate / HZ; | ||
148 | writel(ctrl, clkevt_base + TIMER_CTRL); | ||
149 | |||
150 | setup_irq(irq, &integrator_timer_irq); | ||
151 | clockevents_config_and_register(&integrator_clockevent, | ||
152 | rate, | ||
153 | 1, | ||
154 | 0xffffU); | ||
155 | } | ||
156 | |||
157 | static void __init integrator_ap_timer_init_of(struct device_node *node) | ||
158 | { | ||
159 | const char *path; | ||
160 | void __iomem *base; | ||
161 | int err; | ||
162 | int irq; | ||
163 | struct clk *clk; | ||
164 | unsigned long rate; | ||
165 | struct device_node *pri_node; | ||
166 | struct device_node *sec_node; | ||
167 | |||
168 | base = of_io_request_and_map(node, 0, "integrator-timer"); | ||
169 | if (!base) | ||
170 | return; | ||
171 | |||
172 | clk = of_clk_get(node, 0); | ||
173 | if (IS_ERR(clk)) { | ||
174 | pr_err("No clock for %s\n", node->name); | ||
175 | return; | ||
176 | } | ||
177 | clk_prepare_enable(clk); | ||
178 | rate = clk_get_rate(clk); | ||
179 | writel(0, base + TIMER_CTRL); | ||
180 | |||
181 | err = of_property_read_string(of_aliases, | ||
182 | "arm,timer-primary", &path); | ||
183 | if (WARN_ON(err)) | ||
184 | return; | ||
185 | pri_node = of_find_node_by_path(path); | ||
186 | err = of_property_read_string(of_aliases, | ||
187 | "arm,timer-secondary", &path); | ||
188 | if (WARN_ON(err)) | ||
189 | return; | ||
190 | sec_node = of_find_node_by_path(path); | ||
191 | |||
192 | if (node == pri_node) { | ||
193 | /* The primary timer lacks IRQ, use as clocksource */ | ||
194 | integrator_clocksource_init(rate, base); | ||
195 | return; | ||
196 | } | ||
197 | |||
198 | if (node == sec_node) { | ||
199 | /* The secondary timer will drive the clock event */ | ||
200 | irq = irq_of_parse_and_map(node, 0); | ||
201 | integrator_clockevent_init(rate, base, irq); | ||
202 | return; | ||
203 | } | ||
204 | |||
205 | pr_info("Timer @%p unused\n", base); | ||
206 | clk_disable_unprepare(clk); | ||
207 | } | ||
208 | |||
209 | CLOCKSOURCE_OF_DECLARE(integrator_ap_timer, "arm,integrator-timer", | ||
210 | integrator_ap_timer_init_of); | ||
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 6a2e168c3ab0..b907550ae9a5 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/of_pci.h> | 26 | #include <linux/of_pci.h> |
27 | #include <linux/irqdomain.h> | 27 | #include <linux/irqdomain.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/syscore_ops.h> | ||
29 | #include <linux/msi.h> | 30 | #include <linux/msi.h> |
30 | #include <asm/mach/arch.h> | 31 | #include <asm/mach/arch.h> |
31 | #include <asm/exception.h> | 32 | #include <asm/exception.h> |
@@ -67,6 +68,7 @@ | |||
67 | static void __iomem *per_cpu_int_base; | 68 | static void __iomem *per_cpu_int_base; |
68 | static void __iomem *main_int_base; | 69 | static void __iomem *main_int_base; |
69 | static struct irq_domain *armada_370_xp_mpic_domain; | 70 | static struct irq_domain *armada_370_xp_mpic_domain; |
71 | static u32 doorbell_mask_reg; | ||
70 | #ifdef CONFIG_PCI_MSI | 72 | #ifdef CONFIG_PCI_MSI |
71 | static struct irq_domain *armada_370_xp_msi_domain; | 73 | static struct irq_domain *armada_370_xp_msi_domain; |
72 | static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR); | 74 | static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR); |
@@ -485,6 +487,54 @@ armada_370_xp_handle_irq(struct pt_regs *regs) | |||
485 | } while (1); | 487 | } while (1); |
486 | } | 488 | } |
487 | 489 | ||
490 | static int armada_370_xp_mpic_suspend(void) | ||
491 | { | ||
492 | doorbell_mask_reg = readl(per_cpu_int_base + | ||
493 | ARMADA_370_XP_IN_DRBEL_MSK_OFFS); | ||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | static void armada_370_xp_mpic_resume(void) | ||
498 | { | ||
499 | int nirqs; | ||
500 | irq_hw_number_t irq; | ||
501 | |||
502 | /* Re-enable interrupts */ | ||
503 | nirqs = (readl(main_int_base + ARMADA_370_XP_INT_CONTROL) >> 2) & 0x3ff; | ||
504 | for (irq = 0; irq < nirqs; irq++) { | ||
505 | struct irq_data *data; | ||
506 | int virq; | ||
507 | |||
508 | virq = irq_linear_revmap(armada_370_xp_mpic_domain, irq); | ||
509 | if (virq == 0) | ||
510 | continue; | ||
511 | |||
512 | if (irq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) | ||
513 | writel(irq, per_cpu_int_base + | ||
514 | ARMADA_370_XP_INT_CLEAR_MASK_OFFS); | ||
515 | else | ||
516 | writel(irq, main_int_base + | ||
517 | ARMADA_370_XP_INT_SET_ENABLE_OFFS); | ||
518 | |||
519 | data = irq_get_irq_data(virq); | ||
520 | if (!irqd_irq_disabled(data)) | ||
521 | armada_370_xp_irq_unmask(data); | ||
522 | } | ||
523 | |||
524 | /* Reconfigure doorbells for IPIs and MSIs */ | ||
525 | writel(doorbell_mask_reg, | ||
526 | per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS); | ||
527 | if (doorbell_mask_reg & IPI_DOORBELL_MASK) | ||
528 | writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); | ||
529 | if (doorbell_mask_reg & PCI_MSI_DOORBELL_MASK) | ||
530 | writel(1, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); | ||
531 | } | ||
532 | |||
533 | struct syscore_ops armada_370_xp_mpic_syscore_ops = { | ||
534 | .suspend = armada_370_xp_mpic_suspend, | ||
535 | .resume = armada_370_xp_mpic_resume, | ||
536 | }; | ||
537 | |||
488 | static int __init armada_370_xp_mpic_of_init(struct device_node *node, | 538 | static int __init armada_370_xp_mpic_of_init(struct device_node *node, |
489 | struct device_node *parent) | 539 | struct device_node *parent) |
490 | { | 540 | { |
@@ -541,6 +591,8 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, | |||
541 | armada_370_xp_mpic_handle_cascade_irq); | 591 | armada_370_xp_mpic_handle_cascade_irq); |
542 | } | 592 | } |
543 | 593 | ||
594 | register_syscore_ops(&armada_370_xp_mpic_syscore_ops); | ||
595 | |||
544 | return 0; | 596 | return 0; |
545 | } | 597 | } |
546 | 598 | ||
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index f65ff49bb275..028e76504519 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig | |||
@@ -71,6 +71,15 @@ config POWER_RESET_HISI | |||
71 | help | 71 | help |
72 | Reboot support for Hisilicon boards. | 72 | Reboot support for Hisilicon boards. |
73 | 73 | ||
74 | config POWER_RESET_IMX | ||
75 | bool "IMX6 power-off driver" | ||
76 | depends on POWER_RESET && SOC_IMX6 | ||
77 | help | ||
78 | This driver support power off external PMIC by PMIC_ON_REQ on i.mx6 | ||
79 | boards.If you want to use other pin to control external power,please | ||
80 | say N here or disable in dts to make sure pm_power_off never be | ||
81 | overwrote wrongly by this driver. | ||
82 | |||
74 | config POWER_RESET_MSM | 83 | config POWER_RESET_MSM |
75 | bool "Qualcomm MSM power-off driver" | 84 | bool "Qualcomm MSM power-off driver" |
76 | depends on ARCH_QCOM | 85 | depends on ARCH_QCOM |
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index 76ce1c59469b..1d4804d6b323 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile | |||
@@ -6,6 +6,7 @@ obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o | |||
6 | obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o | 6 | obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o |
7 | obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o | 7 | obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o |
8 | obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o | 8 | obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o |
9 | obj-$(CONFIG_POWER_RESET_IMX) += imx-snvs-poweroff.o | ||
9 | obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o | 10 | obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o |
10 | obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o | 11 | obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o |
11 | obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o | 12 | obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o |
diff --git a/drivers/power/reset/imx-snvs-poweroff.c b/drivers/power/reset/imx-snvs-poweroff.c new file mode 100644 index 000000000000..ad6ce5020ea7 --- /dev/null +++ b/drivers/power/reset/imx-snvs-poweroff.c | |||
@@ -0,0 +1,66 @@ | |||
1 | /* Power off driver for i.mx6 | ||
2 | * Copyright (c) 2014, FREESCALE CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * based on msm-poweroff.c | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 and | ||
8 | * only version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/err.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/of_address.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | |||
26 | static void __iomem *snvs_base; | ||
27 | |||
28 | static void do_imx_poweroff(void) | ||
29 | { | ||
30 | u32 value = readl(snvs_base); | ||
31 | |||
32 | /* set TOP and DP_EN bit */ | ||
33 | writel(value | 0x60, snvs_base); | ||
34 | } | ||
35 | |||
36 | static int imx_poweroff_probe(struct platform_device *pdev) | ||
37 | { | ||
38 | snvs_base = of_iomap(pdev->dev.of_node, 0); | ||
39 | if (!snvs_base) { | ||
40 | dev_err(&pdev->dev, "failed to get memory\n"); | ||
41 | return -ENODEV; | ||
42 | } | ||
43 | |||
44 | pm_power_off = do_imx_poweroff; | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static const struct of_device_id of_imx_poweroff_match[] = { | ||
49 | { .compatible = "fsl,sec-v4.0-poweroff", }, | ||
50 | {}, | ||
51 | }; | ||
52 | MODULE_DEVICE_TABLE(of, of_imx_poweroff_match); | ||
53 | |||
54 | static struct platform_driver imx_poweroff_driver = { | ||
55 | .probe = imx_poweroff_probe, | ||
56 | .driver = { | ||
57 | .name = "imx-snvs-poweroff", | ||
58 | .of_match_table = of_match_ptr(of_imx_poweroff_match), | ||
59 | }, | ||
60 | }; | ||
61 | |||
62 | static int __init imx_poweroff_init(void) | ||
63 | { | ||
64 | return platform_driver_register(&imx_poweroff_driver); | ||
65 | } | ||
66 | device_initcall(imx_poweroff_init); | ||
diff --git a/drivers/soc/versatile/Kconfig b/drivers/soc/versatile/Kconfig index bf5ee9c85330..a928a7fc6be4 100644 --- a/drivers/soc/versatile/Kconfig +++ b/drivers/soc/versatile/Kconfig | |||
@@ -1,6 +1,15 @@ | |||
1 | # | 1 | # |
2 | # ARM Versatile SoC drivers | 2 | # ARM Versatile SoC drivers |
3 | # | 3 | # |
4 | config SOC_INTEGRATOR_CM | ||
5 | bool "SoC bus device for the ARM Integrator platform core modules" | ||
6 | depends on ARCH_INTEGRATOR | ||
7 | select SOC_BUS | ||
8 | help | ||
9 | Include support for the SoC bus on the ARM Integrator platform | ||
10 | core modules providing some sysfs information about the ASIC | ||
11 | variant. | ||
12 | |||
4 | config SOC_REALVIEW | 13 | config SOC_REALVIEW |
5 | bool "SoC bus device for the ARM RealView platforms" | 14 | bool "SoC bus device for the ARM RealView platforms" |
6 | depends on ARCH_REALVIEW | 15 | depends on ARCH_REALVIEW |
diff --git a/drivers/soc/versatile/Makefile b/drivers/soc/versatile/Makefile index ad547435648e..cf612fe3a659 100644 --- a/drivers/soc/versatile/Makefile +++ b/drivers/soc/versatile/Makefile | |||
@@ -1 +1,2 @@ | |||
1 | obj-$(CONFIG_SOC_INTEGRATOR_CM) += soc-integrator.o | ||
1 | obj-$(CONFIG_SOC_REALVIEW) += soc-realview.o | 2 | obj-$(CONFIG_SOC_REALVIEW) += soc-realview.o |
diff --git a/drivers/soc/versatile/soc-integrator.c b/drivers/soc/versatile/soc-integrator.c new file mode 100644 index 000000000000..a5d7d39ae0ad --- /dev/null +++ b/drivers/soc/versatile/soc-integrator.c | |||
@@ -0,0 +1,155 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Linaro Ltd. | ||
3 | * | ||
4 | * Author: Linus Walleij <linus.walleij@linaro.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2, as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/io.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/sys_soc.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/mfd/syscon.h> | ||
17 | #include <linux/regmap.h> | ||
18 | #include <linux/of.h> | ||
19 | |||
20 | #define INTEGRATOR_HDR_ID_OFFSET 0x00 | ||
21 | |||
22 | static u32 integrator_coreid; | ||
23 | |||
24 | static const struct of_device_id integrator_cm_match[] = { | ||
25 | { .compatible = "arm,core-module-integrator", }, | ||
26 | { } | ||
27 | }; | ||
28 | |||
29 | static const char *integrator_arch_str(u32 id) | ||
30 | { | ||
31 | switch ((id >> 16) & 0xff) { | ||
32 | case 0x00: | ||
33 | return "ASB little-endian"; | ||
34 | case 0x01: | ||
35 | return "AHB little-endian"; | ||
36 | case 0x03: | ||
37 | return "AHB-Lite system bus, bi-endian"; | ||
38 | case 0x04: | ||
39 | return "AHB"; | ||
40 | case 0x08: | ||
41 | return "AHB system bus, ASB processor bus"; | ||
42 | default: | ||
43 | return "Unknown"; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | static const char *integrator_fpga_str(u32 id) | ||
48 | { | ||
49 | switch ((id >> 12) & 0xf) { | ||
50 | case 0x01: | ||
51 | return "XC4062"; | ||
52 | case 0x02: | ||
53 | return "XC4085"; | ||
54 | case 0x03: | ||
55 | return "XVC600"; | ||
56 | case 0x04: | ||
57 | return "EPM7256AE (Altera PLD)"; | ||
58 | default: | ||
59 | return "Unknown"; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | static ssize_t integrator_get_manf(struct device *dev, | ||
64 | struct device_attribute *attr, | ||
65 | char *buf) | ||
66 | { | ||
67 | return sprintf(buf, "%02x\n", integrator_coreid >> 24); | ||
68 | } | ||
69 | |||
70 | static struct device_attribute integrator_manf_attr = | ||
71 | __ATTR(manufacturer, S_IRUGO, integrator_get_manf, NULL); | ||
72 | |||
73 | static ssize_t integrator_get_arch(struct device *dev, | ||
74 | struct device_attribute *attr, | ||
75 | char *buf) | ||
76 | { | ||
77 | return sprintf(buf, "%s\n", integrator_arch_str(integrator_coreid)); | ||
78 | } | ||
79 | |||
80 | static struct device_attribute integrator_arch_attr = | ||
81 | __ATTR(arch, S_IRUGO, integrator_get_arch, NULL); | ||
82 | |||
83 | static ssize_t integrator_get_fpga(struct device *dev, | ||
84 | struct device_attribute *attr, | ||
85 | char *buf) | ||
86 | { | ||
87 | return sprintf(buf, "%s\n", integrator_fpga_str(integrator_coreid)); | ||
88 | } | ||
89 | |||
90 | static struct device_attribute integrator_fpga_attr = | ||
91 | __ATTR(fpga, S_IRUGO, integrator_get_fpga, NULL); | ||
92 | |||
93 | static ssize_t integrator_get_build(struct device *dev, | ||
94 | struct device_attribute *attr, | ||
95 | char *buf) | ||
96 | { | ||
97 | return sprintf(buf, "%02x\n", (integrator_coreid >> 4) & 0xFF); | ||
98 | } | ||
99 | |||
100 | static struct device_attribute integrator_build_attr = | ||
101 | __ATTR(build, S_IRUGO, integrator_get_build, NULL); | ||
102 | |||
103 | static int __init integrator_soc_init(void) | ||
104 | { | ||
105 | static struct regmap *syscon_regmap; | ||
106 | struct soc_device *soc_dev; | ||
107 | struct soc_device_attribute *soc_dev_attr; | ||
108 | struct device_node *np; | ||
109 | struct device *dev; | ||
110 | u32 val; | ||
111 | int ret; | ||
112 | |||
113 | np = of_find_matching_node(NULL, integrator_cm_match); | ||
114 | if (!np) | ||
115 | return -ENODEV; | ||
116 | |||
117 | syscon_regmap = syscon_node_to_regmap(np); | ||
118 | if (IS_ERR(syscon_regmap)) | ||
119 | return PTR_ERR(syscon_regmap); | ||
120 | |||
121 | ret = regmap_read(syscon_regmap, INTEGRATOR_HDR_ID_OFFSET, | ||
122 | &val); | ||
123 | if (ret) | ||
124 | return -ENODEV; | ||
125 | integrator_coreid = val; | ||
126 | |||
127 | soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); | ||
128 | if (!soc_dev_attr) | ||
129 | return -ENOMEM; | ||
130 | |||
131 | soc_dev_attr->soc_id = "Integrator"; | ||
132 | soc_dev_attr->machine = "Integrator"; | ||
133 | soc_dev_attr->family = "Versatile"; | ||
134 | soc_dev = soc_device_register(soc_dev_attr); | ||
135 | if (IS_ERR(soc_dev)) { | ||
136 | kfree(soc_dev_attr); | ||
137 | return -ENODEV; | ||
138 | } | ||
139 | dev = soc_device_to_device(soc_dev); | ||
140 | |||
141 | device_create_file(dev, &integrator_manf_attr); | ||
142 | device_create_file(dev, &integrator_arch_attr); | ||
143 | device_create_file(dev, &integrator_fpga_attr); | ||
144 | device_create_file(dev, &integrator_build_attr); | ||
145 | |||
146 | dev_info(dev, "Detected ARM core module:\n"); | ||
147 | dev_info(dev, " Manufacturer: %02x\n", (val >> 24)); | ||
148 | dev_info(dev, " Architecture: %s\n", integrator_arch_str(val)); | ||
149 | dev_info(dev, " FPGA: %s\n", integrator_fpga_str(val)); | ||
150 | dev_info(dev, " Build: %02x\n", (val >> 4) & 0xFF); | ||
151 | dev_info(dev, " Rev: %c\n", ('A' + (val & 0x03))); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | device_initcall(integrator_soc_init); | ||
diff --git a/include/dt-bindings/arm/ux500_pm_domains.h b/include/dt-bindings/arm/ux500_pm_domains.h new file mode 100644 index 000000000000..398a6c0288d1 --- /dev/null +++ b/include/dt-bindings/arm/ux500_pm_domains.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Linaro Ltd. | ||
3 | * | ||
4 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | */ | ||
7 | #ifndef _DT_BINDINGS_ARM_UX500_PM_DOMAINS_H | ||
8 | #define _DT_BINDINGS_ARM_UX500_PM_DOMAINS_H | ||
9 | |||
10 | #define DOMAIN_VAPE 0 | ||
11 | |||
12 | /* Number of PM domains. */ | ||
13 | #define NR_DOMAINS (DOMAIN_VAPE + 1) | ||
14 | |||
15 | #endif | ||
diff --git a/include/dt-bindings/clock/imx5-clock.h b/include/dt-bindings/clock/imx5-clock.h index 5f2667ecd98e..f4b7478e23c8 100644 --- a/include/dt-bindings/clock/imx5-clock.h +++ b/include/dt-bindings/clock/imx5-clock.h | |||
@@ -198,6 +198,9 @@ | |||
198 | #define IMX5_CLK_OCRAM 186 | 198 | #define IMX5_CLK_OCRAM 186 |
199 | #define IMX5_CLK_SAHARA_IPG_GATE 187 | 199 | #define IMX5_CLK_SAHARA_IPG_GATE 187 |
200 | #define IMX5_CLK_SATA_REF 188 | 200 | #define IMX5_CLK_SATA_REF 188 |
201 | #define IMX5_CLK_END 189 | 201 | #define IMX5_CLK_STEP_SEL 189 |
202 | #define IMX5_CLK_CPU_PODF_SEL 190 | ||
203 | #define IMX5_CLK_ARM 191 | ||
204 | #define IMX5_CLK_END 192 | ||
202 | 205 | ||
203 | #endif /* __DT_BINDINGS_CLOCK_IMX5_H */ | 206 | #endif /* __DT_BINDINGS_CLOCK_IMX5_H */ |
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index f75acbf70e96..74e5341463c9 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h | |||
@@ -254,13 +254,26 @@ extern const struct clk_ops ti_clk_mux_ops; | |||
254 | void omap2_init_clk_hw_omap_clocks(struct clk *clk); | 254 | void omap2_init_clk_hw_omap_clocks(struct clk *clk); |
255 | int omap3_noncore_dpll_enable(struct clk_hw *hw); | 255 | int omap3_noncore_dpll_enable(struct clk_hw *hw); |
256 | void omap3_noncore_dpll_disable(struct clk_hw *hw); | 256 | void omap3_noncore_dpll_disable(struct clk_hw *hw); |
257 | int omap3_noncore_dpll_set_parent(struct clk_hw *hw, u8 index); | ||
257 | int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, | 258 | int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, |
258 | unsigned long parent_rate); | 259 | unsigned long parent_rate); |
260 | int omap3_noncore_dpll_set_rate_and_parent(struct clk_hw *hw, | ||
261 | unsigned long rate, | ||
262 | unsigned long parent_rate, | ||
263 | u8 index); | ||
264 | long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, | ||
265 | unsigned long rate, | ||
266 | unsigned long *best_parent_rate, | ||
267 | struct clk **best_parent_clk); | ||
259 | unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, | 268 | unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, |
260 | unsigned long parent_rate); | 269 | unsigned long parent_rate); |
261 | long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw, | 270 | long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw, |
262 | unsigned long target_rate, | 271 | unsigned long target_rate, |
263 | unsigned long *parent_rate); | 272 | unsigned long *parent_rate); |
273 | long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, | ||
274 | unsigned long rate, | ||
275 | unsigned long *best_parent_rate, | ||
276 | struct clk **best_parent_clk); | ||
264 | u8 omap2_init_dpll_parent(struct clk_hw *hw); | 277 | u8 omap2_init_dpll_parent(struct clk_hw *hw); |
265 | unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate); | 278 | unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate); |
266 | long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, | 279 | long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, |
@@ -278,6 +291,8 @@ int omap2_clk_disable_autoidle_all(void); | |||
278 | void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks); | 291 | void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks); |
279 | int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate, | 292 | int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate, |
280 | unsigned long parent_rate); | 293 | unsigned long parent_rate); |
294 | int omap3_dpll4_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, | ||
295 | unsigned long parent_rate, u8 index); | ||
281 | int omap2_dflt_clk_enable(struct clk_hw *hw); | 296 | int omap2_dflt_clk_enable(struct clk_hw *hw); |
282 | void omap2_dflt_clk_disable(struct clk_hw *hw); | 297 | void omap2_dflt_clk_disable(struct clk_hw *hw); |
283 | int omap2_dflt_clk_is_enabled(struct clk_hw *hw); | 298 | int omap2_dflt_clk_is_enabled(struct clk_hw *hw); |
diff --git a/include/linux/mbus.h b/include/linux/mbus.h index 550c88fb0267..611b69fa8594 100644 --- a/include/linux/mbus.h +++ b/include/linux/mbus.h | |||
@@ -61,6 +61,7 @@ static inline const struct mbus_dram_target_info *mv_mbus_dram_info(void) | |||
61 | } | 61 | } |
62 | #endif | 62 | #endif |
63 | 63 | ||
64 | int mvebu_mbus_save_cpu_target(u32 *store_addr); | ||
64 | void mvebu_mbus_get_pcie_mem_aperture(struct resource *res); | 65 | void mvebu_mbus_get_pcie_mem_aperture(struct resource *res); |
65 | void mvebu_mbus_get_pcie_io_aperture(struct resource *res); | 66 | void mvebu_mbus_get_pcie_io_aperture(struct resource *res); |
66 | int mvebu_mbus_add_window_remap_by_id(unsigned int target, | 67 | int mvebu_mbus_add_window_remap_by_id(unsigned int target, |
diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h index ff44374a1a4e..c877cad61a13 100644 --- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h +++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h | |||
@@ -395,4 +395,43 @@ | |||
395 | #define IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK (0x3 << 17) | 395 | #define IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK (0x3 << 17) |
396 | #define IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK (0x1 << 14) | 396 | #define IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK (0x1 << 14) |
397 | 397 | ||
398 | /* For imx6sx iomux gpr register field define */ | ||
399 | #define IMX6SX_GPR1_VDEC_SW_RST_MASK (0x1 << 20) | ||
400 | #define IMX6SX_GPR1_VDEC_SW_RST_RESET (0x1 << 20) | ||
401 | #define IMX6SX_GPR1_VDEC_SW_RST_RELEASE (0x0 << 20) | ||
402 | #define IMX6SX_GPR1_VADC_SW_RST_MASK (0x1 << 19) | ||
403 | #define IMX6SX_GPR1_VADC_SW_RST_RESET (0x1 << 19) | ||
404 | #define IMX6SX_GPR1_VADC_SW_RST_RELEASE (0x0 << 19) | ||
405 | #define IMX6SX_GPR1_FEC_CLOCK_MUX_SEL_MASK (0x3 << 13) | ||
406 | #define IMX6SX_GPR1_FEC_CLOCK_PAD_DIR_MASK (0x3 << 17) | ||
407 | #define IMX6SX_GPR1_FEC_CLOCK_MUX_SEL_EXT (0x3 << 13) | ||
408 | |||
409 | #define IMX6SX_GPR4_FEC_ENET1_STOP_REQ (0x1 << 3) | ||
410 | #define IMX6SX_GPR4_FEC_ENET2_STOP_REQ (0x1 << 4) | ||
411 | |||
412 | #define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_MASK (0x1 << 3) | ||
413 | #define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_LCDIF1 (0x0 << 3) | ||
414 | #define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_LCDIF2 (0x1 << 3) | ||
415 | |||
416 | #define IMX6SX_GPR5_CSI2_MUX_CTRL_MASK (0x3 << 27) | ||
417 | #define IMX6SX_GPR5_CSI2_MUX_CTRL_EXT_PIN (0x0 << 27) | ||
418 | #define IMX6SX_GPR5_CSI2_MUX_CTRL_CVD (0x1 << 27) | ||
419 | #define IMX6SX_GPR5_CSI2_MUX_CTRL_VDAC_TO_CSI (0x2 << 27) | ||
420 | #define IMX6SX_GPR5_CSI2_MUX_CTRL_GND (0x3 << 27) | ||
421 | #define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_MASK (0x1 << 26) | ||
422 | #define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_ENABLE (0x1 << 26) | ||
423 | #define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_DISABLE (0x0 << 26) | ||
424 | #define IMX6SX_GPR5_CSI1_MUX_CTRL_MASK (0x3 << 4) | ||
425 | #define IMX6SX_GPR5_CSI1_MUX_CTRL_EXT_PIN (0x0 << 4) | ||
426 | #define IMX6SX_GPR5_CSI1_MUX_CTRL_CVD (0x1 << 4) | ||
427 | #define IMX6SX_GPR5_CSI1_MUX_CTRL_VDAC_TO_CSI (0x2 << 4) | ||
428 | #define IMX6SX_GPR5_CSI1_MUX_CTRL_GND (0x3 << 4) | ||
429 | |||
430 | #define IMX6SX_GPR5_DISP_MUX_DCIC2_LCDIF2 (0x0 << 2) | ||
431 | #define IMX6SX_GPR5_DISP_MUX_DCIC2_LVDS (0x1 << 2) | ||
432 | #define IMX6SX_GPR5_DISP_MUX_DCIC2_MASK (0x1 << 2) | ||
433 | #define IMX6SX_GPR5_DISP_MUX_DCIC1_LCDIF1 (0x0 << 1) | ||
434 | #define IMX6SX_GPR5_DISP_MUX_DCIC1_LVDS (0x1 << 1) | ||
435 | #define IMX6SX_GPR5_DISP_MUX_DCIC1_MASK (0x1 << 1) | ||
436 | |||
398 | #endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */ | 437 | #endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */ |