aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-22 12:18:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-22 12:18:17 -0400
commit7d2b6ef19cf0f98cef17aa5185de3631a618710a (patch)
treed4e87f3c47837fef59ef15273f89f68b73d963af
parent5c73cc4b6c83e88863a5de869cc5df3b913aef4a (diff)
parent7415d97ee2b809119270fc3a365968ff8d4f544b (diff)
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Olof Johansson: "Driver updates for v4.1. Some of these are for drivers/soc, where we find more and more SoC-specific drivers these days. Some are for other driver subsystems where we have received acks from the appropriate maintainers. The larger parts of this branch are: - MediaTek support for their PMIC wrapper interface, a high-level interface for talking to the system PMIC over a dedicated I2C interface. - Qualcomm SCM driver has been moved to drivers/firmware. It's used for CPU up/down and needs to be in a shared location for arm/arm64 common code. - cleanup of ARM-CCI PMU code. - another set of cleanusp to the OMAP GPMC code" * tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (43 commits) soc/mediatek: Remove unused variables clocksource: atmel-st: select MFD_SYSCON soc: mediatek: Add PMIC wrapper for MT8135 and MT8173 SoCs arm-cci: Fix CCI PMU event validation arm-cci: Split the code for PMU vs driver support arm-cci: Get rid of secure transactions for PMU driver arm-cci: Abstract the CCI400 PMU specific definitions arm-cci: Rearrange code for splitting PMU vs driver code drivers: cci: reject groups spanning multiple HW PMUs ARM: at91: remove useless include clocksource: atmel-st: remove mach/hardware dependency clocksource: atmel-st: use syscon/regmap ARM: at91: time: move the system timer driver to drivers/clocksource ARM: at91: properly initialize timer ARM: at91: at91rm9200: remove deprecated arm_pm_restart watchdog: at91rm9200: implement restart handler watchdog: at91rm9200: use the system timer syscon mfd: syscon: Add atmel system timer registers definition ARM: at91/dt: declare atmel,at91rm9200-st as a syscon soc: qcom: gsbi: Add support for ADM CRCI muxing ...
-rw-r--r--Documentation/devicetree/bindings/arm/atmel-at91.txt4
-rw-r--r--Documentation/devicetree/bindings/arm/cci.txt7
-rw-r--r--Documentation/devicetree/bindings/bus/renesas,bsc.txt46
-rw-r--r--Documentation/devicetree/bindings/bus/simple-pm-bus.txt44
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt30
-rw-r--r--MAINTAINERS1
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/boot/dts/at91rm9200.dtsi6
-rw-r--r--arch/arm/include/asm/arm-cci.h42
-rw-r--r--arch/arm/mach-at91/Kconfig1
-rw-r--r--arch/arm/mach-at91/Makefile2
-rw-r--r--arch/arm/mach-at91/at91rm9200.c19
-rw-r--r--arch/arm/mach-at91/generic.h3
-rw-r--r--arch/arm/mach-at91/include/mach/at91_st.h61
-rw-r--r--arch/arm/mach-exynos/Kconfig2
-rw-r--r--arch/arm/mach-mediatek/Kconfig1
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.c18
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c4
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c4
-rw-r--r--arch/arm/mach-qcom/Kconfig3
-rw-r--r--arch/arm/mach-qcom/Makefile3
-rw-r--r--arch/arm/mach-qcom/platsmp.c23
-rw-r--r--arch/arm/mach-qcom/scm-boot.c39
-rw-r--r--arch/arm/mach-qcom/scm-boot.h26
-rw-r--r--arch/arm/mach-qcom/scm.c326
-rw-r--r--arch/arm/mach-qcom/scm.h25
-rw-r--r--arch/arm/mach-vexpress/Kconfig4
-rw-r--r--arch/arm64/include/asm/arm-cci.h27
-rw-r--r--drivers/bus/Kconfig73
-rw-r--r--drivers/bus/Makefile17
-rw-r--r--drivers/bus/arm-cci.c517
-rw-r--r--drivers/bus/simple-pm-bus.c58
-rw-r--r--drivers/clocksource/Kconfig5
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/timer-atmel-st.c (renamed from arch/arm/mach-at91/at91rm9200_time.c)117
-rw-r--r--drivers/firmware/Kconfig4
-rw-r--r--drivers/firmware/Makefile2
-rw-r--r--drivers/firmware/qcom_scm.c494
-rw-r--r--drivers/memory/omap-gpmc.c358
-rw-r--r--drivers/soc/Kconfig1
-rw-r--r--drivers/soc/Makefile1
-rw-r--r--drivers/soc/mediatek/Kconfig11
-rw-r--r--drivers/soc/mediatek/Makefile1
-rw-r--r--drivers/soc/mediatek/mtk-pmic-wrap.c975
-rw-r--r--drivers/soc/qcom/Kconfig1
-rw-r--r--drivers/soc/qcom/qcom_gsbi.c152
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c61
-rw-r--r--include/linux/arm-cci.h9
-rw-r--r--include/linux/mfd/syscon/atmel-st.h49
-rw-r--r--include/linux/omap-gpmc.h3
-rw-r--r--include/linux/qcom_scm.h28
52 files changed, 2753 insertions, 960 deletions
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt
index ad319f84f560..2e99b5b57350 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt
@@ -46,10 +46,12 @@ PIT Timer required properties:
46 shared across all System Controller members. 46 shared across all System Controller members.
47 47
48System Timer (ST) required properties: 48System Timer (ST) required properties:
49- compatible: Should be "atmel,at91rm9200-st" 49- compatible: Should be "atmel,at91rm9200-st", "syscon", "simple-mfd"
50- reg: Should contain registers location and length 50- reg: Should contain registers location and length
51- interrupts: Should contain interrupt for the ST which is the IRQ line 51- interrupts: Should contain interrupt for the ST which is the IRQ line
52 shared across all System Controller members. 52 shared across all System Controller members.
53Its subnodes can be:
54- watchdog: compatible should be "atmel,at91rm9200-wdt"
53 55
54TC/TCLIB Timer required properties: 56TC/TCLIB Timer required properties:
55- compatible: Should be "atmel,<chip>-tcb". 57- compatible: Should be "atmel,<chip>-tcb".
diff --git a/Documentation/devicetree/bindings/arm/cci.txt b/Documentation/devicetree/bindings/arm/cci.txt
index f28d82bbbc56..3c5c631328d3 100644
--- a/Documentation/devicetree/bindings/arm/cci.txt
+++ b/Documentation/devicetree/bindings/arm/cci.txt
@@ -94,8 +94,11 @@ specific to ARM.
94 - compatible 94 - compatible
95 Usage: required 95 Usage: required
96 Value type: <string> 96 Value type: <string>
97 Definition: must be "arm,cci-400-pmu" 97 Definition: Must contain one of:
98 98 "arm,cci-400-pmu,r0"
99 "arm,cci-400-pmu,r1"
100 "arm,cci-400-pmu" - DEPRECATED, permitted only where OS has
101 secure acces to CCI registers
99 - reg: 102 - reg:
100 Usage: required 103 Usage: required
101 Value type: Integer cells. A register entry, expressed 104 Value type: Integer cells. A register entry, expressed
diff --git a/Documentation/devicetree/bindings/bus/renesas,bsc.txt b/Documentation/devicetree/bindings/bus/renesas,bsc.txt
new file mode 100644
index 000000000000..90e947269437
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/renesas,bsc.txt
@@ -0,0 +1,46 @@
1Renesas Bus State Controller (BSC)
2==================================
3
4The Renesas Bus State Controller (BSC, sometimes called "LBSC within Bus
5Bridge", or "External Bus Interface") can be found in several Renesas ARM SoCs.
6It provides an external bus for connecting multiple external devices to the
7SoC, driving several chip select lines, for e.g. NOR FLASH, Ethernet and USB.
8
9While the BSC is a fairly simple memory-mapped bus, it may be part of a PM
10domain, and may have a gateable functional clock.
11Before a device connected to the BSC can be accessed, the PM domain
12containing the BSC must be powered on, and the functional clock
13driving the BSC must be enabled.
14
15The bindings for the BSC extend the bindings for "simple-pm-bus".
16
17
18Required properties
19 - compatible: Must contain an SoC-specific value, and "renesas,bsc" and
20 "simple-pm-bus" as fallbacks.
21 SoC-specific values can be:
22 "renesas,bsc-r8a73a4" for R-Mobile APE6 (r8a73a4)
23 "renesas,bsc-sh73a0" for SH-Mobile AG5 (sh73a0)
24 - #address-cells, #size-cells, ranges: Must describe the mapping between
25 parent address and child address spaces.
26 - reg: Must contain the base address and length to access the bus controller.
27
28Optional properties:
29 - interrupts: Must contain a reference to the BSC interrupt, if available.
30 - clocks: Must contain a reference to the functional clock, if available.
31 - power-domains: Must contain a reference to the PM domain, if available.
32
33
34Example:
35
36 bsc: bus@fec10000 {
37 compatible = "renesas,bsc-sh73a0", "renesas,bsc",
38 "simple-pm-bus";
39 #address-cells = <1>;
40 #size-cells = <1>;
41 ranges = <0 0 0x20000000>;
42 reg = <0xfec10000 0x400>;
43 interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
44 clocks = <&zb_clk>;
45 power-domains = <&pd_a4s>;
46 };
diff --git a/Documentation/devicetree/bindings/bus/simple-pm-bus.txt b/Documentation/devicetree/bindings/bus/simple-pm-bus.txt
new file mode 100644
index 000000000000..d032237512c2
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/simple-pm-bus.txt
@@ -0,0 +1,44 @@
1Simple Power-Managed Bus
2========================
3
4A Simple Power-Managed Bus is a transparent bus that doesn't need a real
5driver, as it's typically initialized by the boot loader.
6
7However, its bus controller is part of a PM domain, or under the control of a
8functional clock. Hence, the bus controller's PM domain and/or clock must be
9enabled for child devices connected to the bus (either on-SoC or externally)
10to function.
11
12While "simple-pm-bus" follows the "simple-bus" set of properties, as specified
13in ePAPR, it is not an extension of "simple-bus".
14
15
16Required properties:
17 - compatible: Must contain at least "simple-pm-bus".
18 Must not contain "simple-bus".
19 It's recommended to let this be preceded by one or more
20 vendor-specific compatible values.
21 - #address-cells, #size-cells, ranges: Must describe the mapping between
22 parent address and child address spaces.
23
24Optional platform-specific properties for clock or PM domain control (at least
25one of them is required):
26 - clocks: Must contain a reference to the functional clock(s),
27 - power-domains: Must contain a reference to the PM domain.
28Please refer to the binding documentation for the clock and/or PM domain
29providers for more details.
30
31
32Example:
33
34 bsc: bus@fec10000 {
35 compatible = "renesas,bsc-sh73a0", "renesas,bsc",
36 "simple-pm-bus";
37 #address-cells = <1>;
38 #size-cells = <1>;
39 ranges = <0 0 0x20000000>;
40 reg = <0xfec10000 0x400>;
41 interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
42 clocks = <&zb_clk>;
43 power-domains = <&pd_a4s>;
44 };
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt
index 4ce24d425bf1..2f5ede39bea2 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt
@@ -6,7 +6,8 @@ configuration settings. The mode setting will govern the input/output mode of
6the 4 GSBI IOs. 6the 4 GSBI IOs.
7 7
8Required properties: 8Required properties:
9- compatible: must contain "qcom,gsbi-v1.0.0" for APQ8064/IPQ8064 9- compatible: Should contain "qcom,gsbi-v1.0.0"
10- cell-index: Should contain the GSBI index
10- reg: Address range for GSBI registers 11- reg: Address range for GSBI registers
11- clocks: required clock 12- clocks: required clock
12- clock-names: must contain "iface" entry 13- clock-names: must contain "iface" entry
@@ -16,6 +17,8 @@ Required properties:
16Optional properties: 17Optional properties:
17- qcom,crci : indicates CRCI MUX value for QUP CRCI ports. Please reference 18- qcom,crci : indicates CRCI MUX value for QUP CRCI ports. Please reference
18 dt-bindings/soc/qcom,gsbi.h for valid CRCI mux values. 19 dt-bindings/soc/qcom,gsbi.h for valid CRCI mux values.
20- syscon-tcsr: indicates phandle of TCSR syscon node. Required if child uses
21 dma.
19 22
20Required properties if child node exists: 23Required properties if child node exists:
21- #address-cells: Must be 1 24- #address-cells: Must be 1
@@ -39,6 +42,7 @@ Example for APQ8064:
39 42
40 gsbi4@16300000 { 43 gsbi4@16300000 {
41 compatible = "qcom,gsbi-v1.0.0"; 44 compatible = "qcom,gsbi-v1.0.0";
45 cell-index = <4>;
42 reg = <0x16300000 0x100>; 46 reg = <0x16300000 0x100>;
43 clocks = <&gcc GSBI4_H_CLK>; 47 clocks = <&gcc GSBI4_H_CLK>;
44 clock-names = "iface"; 48 clock-names = "iface";
@@ -48,22 +52,24 @@ Example for APQ8064:
48 qcom,mode = <GSBI_PROT_I2C_UART>; 52 qcom,mode = <GSBI_PROT_I2C_UART>;
49 qcom,crci = <GSBI_CRCI_QUP>; 53 qcom,crci = <GSBI_CRCI_QUP>;
50 54
55 syscon-tcsr = <&tcsr>;
56
51 /* child nodes go under here */ 57 /* child nodes go under here */
52 58
53 i2c_qup4: i2c@16380000 { 59 i2c_qup4: i2c@16380000 {
54 compatible = "qcom,i2c-qup-v1.1.1"; 60 compatible = "qcom,i2c-qup-v1.1.1";
55 reg = <0x16380000 0x1000>; 61 reg = <0x16380000 0x1000>;
56 interrupts = <0 153 0>; 62 interrupts = <0 153 0>;
57 63
58 clocks = <&gcc GSBI4_QUP_CLK>, <&gcc GSBI4_H_CLK>; 64 clocks = <&gcc GSBI4_QUP_CLK>, <&gcc GSBI4_H_CLK>;
59 clock-names = "core", "iface"; 65 clock-names = "core", "iface";
60 66
61 clock-frequency = <200000>; 67 clock-frequency = <200000>;
62 68
63 #address-cells = <1>; 69 #address-cells = <1>;
64 #size-cells = <0>; 70 #size-cells = <0>;
65 71
66 }; 72 };
67 73
68 uart4: serial@16340000 { 74 uart4: serial@16340000 {
69 compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; 75 compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
@@ -76,3 +82,7 @@ Example for APQ8064:
76 }; 82 };
77 }; 83 };
78 84
85 tcsr: syscon@1a400000 {
86 compatible = "qcom,apq8064-tcsr", "syscon";
87 reg = <0x1a400000 0x100>;
88 };
diff --git a/MAINTAINERS b/MAINTAINERS
index fadb73c40e28..39fb0435362c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1327,6 +1327,7 @@ F: drivers/tty/serial/msm_serial.h
1327F: drivers/tty/serial/msm_serial.c 1327F: drivers/tty/serial/msm_serial.c
1328F: drivers/*/pm8???-* 1328F: drivers/*/pm8???-*
1329F: drivers/mfd/ssbi.c 1329F: drivers/mfd/ssbi.c
1330F: drivers/firmware/qcom_scm.c
1330T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git 1331T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git
1331 1332
1332ARM/RADISYS ENP2611 MACHINE SUPPORT 1333ARM/RADISYS ENP2611 MACHINE SUPPORT
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d74c9ea6eb06..29e80adbf6cc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2146,6 +2146,8 @@ source "net/Kconfig"
2146 2146
2147source "drivers/Kconfig" 2147source "drivers/Kconfig"
2148 2148
2149source "drivers/firmware/Kconfig"
2150
2149source "fs/Kconfig" 2151source "fs/Kconfig"
2150 2152
2151source "arch/arm/Kconfig.debug" 2153source "arch/arm/Kconfig.debug"
diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
index c515e4b160be..4fb333bd1f85 100644
--- a/arch/arm/boot/dts/at91rm9200.dtsi
+++ b/arch/arm/boot/dts/at91rm9200.dtsi
@@ -356,9 +356,13 @@
356 }; 356 };
357 357
358 st: timer@fffffd00 { 358 st: timer@fffffd00 {
359 compatible = "atmel,at91rm9200-st"; 359 compatible = "atmel,at91rm9200-st", "syscon", "simple-mfd";
360 reg = <0xfffffd00 0x100>; 360 reg = <0xfffffd00 0x100>;
361 interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; 361 interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
362
363 watchdog {
364 compatible = "atmel,at91rm9200-wdt";
365 };
362 }; 366 };
363 367
364 rtc: rtc@fffffe00 { 368 rtc: rtc@fffffe00 {
diff --git a/arch/arm/include/asm/arm-cci.h b/arch/arm/include/asm/arm-cci.h
new file mode 100644
index 000000000000..fe77f7ab7e6b
--- /dev/null
+++ b/arch/arm/include/asm/arm-cci.h
@@ -0,0 +1,42 @@
1/*
2 * arch/arm/include/asm/arm-cci.h
3 *
4 * Copyright (C) 2015 ARM Ltd.
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 * 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 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef __ASM_ARM_CCI_H
20#define __ASM_ARM_CCI_H
21
22#ifdef CONFIG_MCPM
23#include <asm/mcpm.h>
24
25/*
26 * We don't have a reliable way of detecting whether,
27 * if we have access to secure-only registers, unless
28 * mcpm is registered.
29 */
30static inline bool platform_has_secure_cci_access(void)
31{
32 return mcpm_is_available();
33}
34
35#else
36static inline bool platform_has_secure_cci_access(void)
37{
38 return false;
39}
40#endif
41
42#endif
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 4da6bae047f3..24b59c75f6af 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -77,6 +77,7 @@ if SOC_SAM_V4_V5
77config SOC_AT91RM9200 77config SOC_AT91RM9200
78 bool "AT91RM9200" 78 bool "AT91RM9200"
79 select ATMEL_AIC_IRQ 79 select ATMEL_AIC_IRQ
80 select ATMEL_ST
80 select COMMON_CLK_AT91 81 select COMMON_CLK_AT91
81 select CPU_ARM920T 82 select CPU_ARM920T
82 select GENERIC_CLOCKEVENTS 83 select GENERIC_CLOCKEVENTS
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index ea54c9824d89..38aaef7b994e 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -7,7 +7,7 @@ obj-y := soc.o
7obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o 7obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o
8 8
9# CPU-specific support 9# CPU-specific support
10obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o at91rm9200_time.o 10obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o
11obj-$(CONFIG_SOC_AT91SAM9) += at91sam9.o 11obj-$(CONFIG_SOC_AT91SAM9) += at91sam9.o
12obj-$(CONFIG_SOC_SAMA5) += sama5.o 12obj-$(CONFIG_SOC_SAMA5) += sama5.o
13 13
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index bfc9aed90b91..eaf58f88ef5d 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -15,8 +15,6 @@
15#include <asm/mach/arch.h> 15#include <asm/mach/arch.h>
16#include <asm/system_misc.h> 16#include <asm/system_misc.h>
17 17
18#include <mach/at91_st.h>
19
20#include "generic.h" 18#include "generic.h"
21#include "soc.h" 19#include "soc.h"
22 20
@@ -25,21 +23,6 @@ static const struct at91_soc rm9200_socs[] = {
25 { /* sentinel */ }, 23 { /* sentinel */ },
26}; 24};
27 25
28static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd)
29{
30 /*
31 * Perform a hardware reset with the use of the Watchdog timer.
32 */
33 at91_st_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
34 at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
35}
36
37static void __init at91rm9200_dt_timer_init(void)
38{
39 of_clk_init(NULL);
40 at91rm9200_timer_init();
41}
42
43static void __init at91rm9200_dt_device_init(void) 26static void __init at91rm9200_dt_device_init(void)
44{ 27{
45 struct soc_device *soc; 28 struct soc_device *soc;
@@ -52,7 +35,6 @@ static void __init at91rm9200_dt_device_init(void)
52 of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev); 35 of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev);
53 36
54 arm_pm_idle = at91rm9200_idle; 37 arm_pm_idle = at91rm9200_idle;
55 arm_pm_restart = at91rm9200_restart;
56 at91rm9200_pm_init(); 38 at91rm9200_pm_init();
57} 39}
58 40
@@ -62,7 +44,6 @@ static const char *at91rm9200_dt_board_compat[] __initconst = {
62}; 44};
63 45
64DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200") 46DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200")
65 .init_time = at91rm9200_dt_timer_init,
66 .init_machine = at91rm9200_dt_device_init, 47 .init_machine = at91rm9200_dt_device_init,
67 .dt_compat = at91rm9200_dt_board_compat, 48 .dt_compat = at91rm9200_dt_board_compat,
68MACHINE_END 49MACHINE_END
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 2b396c4e1fc1..b0fa7dc7286d 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -18,9 +18,6 @@
18extern void __init at91_map_io(void); 18extern void __init at91_map_io(void);
19extern void __init at91_alt_map_io(void); 19extern void __init at91_alt_map_io(void);
20 20
21 /* Timer */
22extern void at91rm9200_timer_init(void);
23
24/* idle */ 21/* idle */
25extern void at91rm9200_idle(void); 22extern void at91rm9200_idle(void);
26extern void at91sam9_idle(void); 23extern void at91sam9_idle(void);
diff --git a/arch/arm/mach-at91/include/mach/at91_st.h b/arch/arm/mach-at91/include/mach/at91_st.h
deleted file mode 100644
index 67fdbd13c3ed..000000000000
--- a/arch/arm/mach-at91/include/mach/at91_st.h
+++ /dev/null
@@ -1,61 +0,0 @@
1/*
2 * arch/arm/mach-at91/include/mach/at91_st.h
3 *
4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People
6 *
7 * System Timer (ST) - System peripherals registers.
8 * Based on AT91RM9200 datasheet revision E.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 */
15
16#ifndef AT91_ST_H
17#define AT91_ST_H
18
19#ifndef __ASSEMBLY__
20extern void __iomem *at91_st_base;
21
22#define at91_st_read(field) \
23 __raw_readl(at91_st_base + field)
24
25#define at91_st_write(field, value) \
26 __raw_writel(value, at91_st_base + field)
27#else
28.extern at91_st_base
29#endif
30
31#define AT91_ST_CR 0x00 /* Control Register */
32#define AT91_ST_WDRST (1 << 0) /* Watchdog Timer Restart */
33
34#define AT91_ST_PIMR 0x04 /* Period Interval Mode Register */
35#define AT91_ST_PIV (0xffff << 0) /* Period Interval Value */
36
37#define AT91_ST_WDMR 0x08 /* Watchdog Mode Register */
38#define AT91_ST_WDV (0xffff << 0) /* Watchdog Counter Value */
39#define AT91_ST_RSTEN (1 << 16) /* Reset Enable */
40#define AT91_ST_EXTEN (1 << 17) /* External Signal Assertion Enable */
41
42#define AT91_ST_RTMR 0x0c /* Real-time Mode Register */
43#define AT91_ST_RTPRES (0xffff << 0) /* Real-time Prescalar Value */
44
45#define AT91_ST_SR 0x10 /* Status Register */
46#define AT91_ST_PITS (1 << 0) /* Period Interval Timer Status */
47#define AT91_ST_WDOVF (1 << 1) /* Watchdog Overflow */
48#define AT91_ST_RTTINC (1 << 2) /* Real-time Timer Increment */
49#define AT91_ST_ALMS (1 << 3) /* Alarm Status */
50
51#define AT91_ST_IER 0x14 /* Interrupt Enable Register */
52#define AT91_ST_IDR 0x18 /* Interrupt Disable Register */
53#define AT91_ST_IMR 0x1c /* Interrupt Mask Register */
54
55#define AT91_ST_RTAR 0x20 /* Real-time Alarm Register */
56#define AT91_ST_ALMV (0xfffff << 0) /* Alarm Value */
57
58#define AT91_ST_CRTR 0x24 /* Current Real-time Register */
59#define AT91_ST_CRTV (0xfffff << 0) /* Current Real-Time Value */
60
61#endif
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 603820e5aba7..81064cd61a0a 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -123,7 +123,7 @@ config SOC_EXYNOS5800
123config EXYNOS5420_MCPM 123config EXYNOS5420_MCPM
124 bool "Exynos5420 Multi-Cluster PM support" 124 bool "Exynos5420 Multi-Cluster PM support"
125 depends on MCPM && SOC_EXYNOS5420 125 depends on MCPM && SOC_EXYNOS5420
126 select ARM_CCI 126 select ARM_CCI400_PORT_CTRL
127 select ARM_CPU_SUSPEND 127 select ARM_CPU_SUSPEND
128 help 128 help
129 This is needed to provide CPU and cluster power management 129 This is needed to provide CPU and cluster power management
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index f7e463ca0287..9f59e58da3a4 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -1,6 +1,7 @@
1menuconfig ARCH_MEDIATEK 1menuconfig ARCH_MEDIATEK
2 bool "Mediatek MT65xx & MT81xx 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 PINCTRL
4 select MTK_TIMER 5 select MTK_TIMER
5 help 6 help
6 Support for Mediatek MT65xx & MT81xx SoCs 7 Support for Mediatek MT65xx & MT81xx SoCs
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index d5951b17b736..72918c4973ea 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -96,14 +96,6 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
96 gpmc_nand_res[1].start = gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE); 96 gpmc_nand_res[1].start = gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
97 gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT); 97 gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
98 98
99 if (gpmc_t) {
100 err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t);
101 if (err < 0) {
102 pr_err("omap2-gpmc: Unable to set gpmc timings: %d\n", err);
103 return err;
104 }
105 }
106
107 memset(&s, 0, sizeof(struct gpmc_settings)); 99 memset(&s, 0, sizeof(struct gpmc_settings));
108 if (gpmc_nand_data->of_node) 100 if (gpmc_nand_data->of_node)
109 gpmc_read_settings_dt(gpmc_nand_data->of_node, &s); 101 gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
@@ -111,6 +103,16 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
111 gpmc_set_legacy(gpmc_nand_data, &s); 103 gpmc_set_legacy(gpmc_nand_data, &s);
112 104
113 s.device_nand = true; 105 s.device_nand = true;
106
107 if (gpmc_t) {
108 err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t, &s);
109 if (err < 0) {
110 pr_err("omap2-gpmc: Unable to set gpmc timings: %d\n",
111 err);
112 return err;
113 }
114 }
115
114 err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s); 116 err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s);
115 if (err < 0) 117 if (err < 0)
116 goto out_free_cs; 118 goto out_free_cs;
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 53d197e0c1f3..f899e77ff5e6 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -293,7 +293,7 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
293 if (ret < 0) 293 if (ret < 0)
294 return ret; 294 return ret;
295 295
296 ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t); 296 ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t, &onenand_async);
297 if (ret < 0) 297 if (ret < 0)
298 return ret; 298 return ret;
299 299
@@ -331,7 +331,7 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
331 if (ret < 0) 331 if (ret < 0)
332 return ret; 332 return ret;
333 333
334 ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t); 334 ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t, &onenand_sync);
335 if (ret < 0) 335 if (ret < 0)
336 return ret; 336 return ret;
337 337
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index 8333400898fb..e554d9e66a1c 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -71,7 +71,7 @@ static int tusb_set_async_mode(unsigned sysclk_ps)
71 71
72 gpmc_calc_timings(&t, &tusb_async, &dev_t); 72 gpmc_calc_timings(&t, &tusb_async, &dev_t);
73 73
74 return gpmc_cs_set_timings(async_cs, &t); 74 return gpmc_cs_set_timings(async_cs, &t, &tusb_async);
75} 75}
76 76
77static int tusb_set_sync_mode(unsigned sysclk_ps) 77static int tusb_set_sync_mode(unsigned sysclk_ps)
@@ -98,7 +98,7 @@ static int tusb_set_sync_mode(unsigned sysclk_ps)
98 98
99 gpmc_calc_timings(&t, &tusb_sync, &dev_t); 99 gpmc_calc_timings(&t, &tusb_sync, &dev_t);
100 100
101 return gpmc_cs_set_timings(sync_cs, &t); 101 return gpmc_cs_set_timings(sync_cs, &t, &tusb_sync);
102} 102}
103 103
104/* tusb driver calls this when it changes the chip's clocking */ 104/* tusb driver calls this when it changes the chip's clocking */
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index 48003ea652b9..2256cd1e25d1 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -22,7 +22,4 @@ config ARCH_MSM8974
22 bool "Enable support for MSM8974" 22 bool "Enable support for MSM8974"
23 select HAVE_ARM_ARCH_TIMER 23 select HAVE_ARM_ARCH_TIMER
24 24
25config QCOM_SCM
26 bool
27
28endif 25endif
diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
index 8f756ae1ae31..e324375fa919 100644
--- a/arch/arm/mach-qcom/Makefile
+++ b/arch/arm/mach-qcom/Makefile
@@ -1,5 +1,2 @@
1obj-y := board.o 1obj-y := board.o
2obj-$(CONFIG_SMP) += platsmp.o 2obj-$(CONFIG_SMP) += platsmp.o
3obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
4
5CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
index 09cffed4c0a4..5cde63a64b34 100644
--- a/arch/arm/mach-qcom/platsmp.c
+++ b/arch/arm/mach-qcom/platsmp.c
@@ -17,10 +17,10 @@
17#include <linux/of_address.h> 17#include <linux/of_address.h>
18#include <linux/smp.h> 18#include <linux/smp.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/qcom_scm.h>
20 21
21#include <asm/smp_plat.h> 22#include <asm/smp_plat.h>
22 23
23#include "scm-boot.h"
24 24
25#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x35a0 25#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x35a0
26#define SCSS_CPU1CORE_RESET 0x2d80 26#define SCSS_CPU1CORE_RESET 0x2d80
@@ -319,25 +319,10 @@ static int kpssv2_boot_secondary(unsigned int cpu, struct task_struct *idle)
319 319
320static void __init qcom_smp_prepare_cpus(unsigned int max_cpus) 320static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
321{ 321{
322 int cpu, map; 322 int cpu;
323 unsigned int flags = 0;
324 static const int cold_boot_flags[] = {
325 0,
326 SCM_FLAG_COLDBOOT_CPU1,
327 SCM_FLAG_COLDBOOT_CPU2,
328 SCM_FLAG_COLDBOOT_CPU3,
329 };
330
331 for_each_present_cpu(cpu) {
332 map = cpu_logical_map(cpu);
333 if (WARN_ON(map >= ARRAY_SIZE(cold_boot_flags))) {
334 set_cpu_present(cpu, false);
335 continue;
336 }
337 flags |= cold_boot_flags[map];
338 }
339 323
340 if (scm_set_boot_addr(virt_to_phys(secondary_startup_arm), flags)) { 324 if (qcom_scm_set_cold_boot_addr(secondary_startup_arm,
325 cpu_present_mask)) {
341 for_each_present_cpu(cpu) { 326 for_each_present_cpu(cpu) {
342 if (cpu == smp_processor_id()) 327 if (cpu == smp_processor_id())
343 continue; 328 continue;
diff --git a/arch/arm/mach-qcom/scm-boot.c b/arch/arm/mach-qcom/scm-boot.c
deleted file mode 100644
index e8ff7beb6218..000000000000
--- a/arch/arm/mach-qcom/scm-boot.c
+++ /dev/null
@@ -1,39 +0,0 @@
1/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/slab.h>
20
21#include "scm.h"
22#include "scm-boot.h"
23
24/*
25 * Set the cold/warm boot address for one of the CPU cores.
26 */
27int scm_set_boot_addr(u32 addr, int flags)
28{
29 struct {
30 __le32 flags;
31 __le32 addr;
32 } cmd;
33
34 cmd.addr = cpu_to_le32(addr);
35 cmd.flags = cpu_to_le32(flags);
36 return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
37 &cmd, sizeof(cmd), NULL, 0);
38}
39EXPORT_SYMBOL(scm_set_boot_addr);
diff --git a/arch/arm/mach-qcom/scm-boot.h b/arch/arm/mach-qcom/scm-boot.h
deleted file mode 100644
index 3e210fb818bb..000000000000
--- a/arch/arm/mach-qcom/scm-boot.h
+++ /dev/null
@@ -1,26 +0,0 @@
1/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#ifndef __MACH_SCM_BOOT_H
13#define __MACH_SCM_BOOT_H
14
15#define SCM_BOOT_ADDR 0x1
16#define SCM_FLAG_COLDBOOT_CPU1 0x01
17#define SCM_FLAG_COLDBOOT_CPU2 0x08
18#define SCM_FLAG_COLDBOOT_CPU3 0x20
19#define SCM_FLAG_WARMBOOT_CPU0 0x04
20#define SCM_FLAG_WARMBOOT_CPU1 0x02
21#define SCM_FLAG_WARMBOOT_CPU2 0x10
22#define SCM_FLAG_WARMBOOT_CPU3 0x40
23
24int scm_set_boot_addr(u32 addr, int flags);
25
26#endif
diff --git a/arch/arm/mach-qcom/scm.c b/arch/arm/mach-qcom/scm.c
deleted file mode 100644
index 1d9cf18c7091..000000000000
--- a/arch/arm/mach-qcom/scm.c
+++ /dev/null
@@ -1,326 +0,0 @@
1/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/slab.h>
19#include <linux/io.h>
20#include <linux/module.h>
21#include <linux/mutex.h>
22#include <linux/errno.h>
23#include <linux/err.h>
24
25#include <asm/outercache.h>
26#include <asm/cacheflush.h>
27
28#include "scm.h"
29
30#define SCM_ENOMEM -5
31#define SCM_EOPNOTSUPP -4
32#define SCM_EINVAL_ADDR -3
33#define SCM_EINVAL_ARG -2
34#define SCM_ERROR -1
35#define SCM_INTERRUPTED 1
36
37static DEFINE_MUTEX(scm_lock);
38
39/**
40 * struct scm_command - one SCM command buffer
41 * @len: total available memory for command and response
42 * @buf_offset: start of command buffer
43 * @resp_hdr_offset: start of response buffer
44 * @id: command to be executed
45 * @buf: buffer returned from scm_get_command_buffer()
46 *
47 * An SCM command is laid out in memory as follows:
48 *
49 * ------------------- <--- struct scm_command
50 * | command header |
51 * ------------------- <--- scm_get_command_buffer()
52 * | command buffer |
53 * ------------------- <--- struct scm_response and
54 * | response header | scm_command_to_response()
55 * ------------------- <--- scm_get_response_buffer()
56 * | response buffer |
57 * -------------------
58 *
59 * There can be arbitrary padding between the headers and buffers so
60 * you should always use the appropriate scm_get_*_buffer() routines
61 * to access the buffers in a safe manner.
62 */
63struct scm_command {
64 __le32 len;
65 __le32 buf_offset;
66 __le32 resp_hdr_offset;
67 __le32 id;
68 __le32 buf[0];
69};
70
71/**
72 * struct scm_response - one SCM response buffer
73 * @len: total available memory for response
74 * @buf_offset: start of response data relative to start of scm_response
75 * @is_complete: indicates if the command has finished processing
76 */
77struct scm_response {
78 __le32 len;
79 __le32 buf_offset;
80 __le32 is_complete;
81};
82
83/**
84 * alloc_scm_command() - Allocate an SCM command
85 * @cmd_size: size of the command buffer
86 * @resp_size: size of the response buffer
87 *
88 * Allocate an SCM command, including enough room for the command
89 * and response headers as well as the command and response buffers.
90 *
91 * Returns a valid &scm_command on success or %NULL if the allocation fails.
92 */
93static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
94{
95 struct scm_command *cmd;
96 size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
97 resp_size;
98 u32 offset;
99
100 cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
101 if (cmd) {
102 cmd->len = cpu_to_le32(len);
103 offset = offsetof(struct scm_command, buf);
104 cmd->buf_offset = cpu_to_le32(offset);
105 cmd->resp_hdr_offset = cpu_to_le32(offset + cmd_size);
106 }
107 return cmd;
108}
109
110/**
111 * free_scm_command() - Free an SCM command
112 * @cmd: command to free
113 *
114 * Free an SCM command.
115 */
116static inline void free_scm_command(struct scm_command *cmd)
117{
118 kfree(cmd);
119}
120
121/**
122 * scm_command_to_response() - Get a pointer to a scm_response
123 * @cmd: command
124 *
125 * Returns a pointer to a response for a command.
126 */
127static inline struct scm_response *scm_command_to_response(
128 const struct scm_command *cmd)
129{
130 return (void *)cmd + le32_to_cpu(cmd->resp_hdr_offset);
131}
132
133/**
134 * scm_get_command_buffer() - Get a pointer to a command buffer
135 * @cmd: command
136 *
137 * Returns a pointer to the command buffer of a command.
138 */
139static inline void *scm_get_command_buffer(const struct scm_command *cmd)
140{
141 return (void *)cmd->buf;
142}
143
144/**
145 * scm_get_response_buffer() - Get a pointer to a response buffer
146 * @rsp: response
147 *
148 * Returns a pointer to a response buffer of a response.
149 */
150static inline void *scm_get_response_buffer(const struct scm_response *rsp)
151{
152 return (void *)rsp + le32_to_cpu(rsp->buf_offset);
153}
154
155static int scm_remap_error(int err)
156{
157 pr_err("scm_call failed with error code %d\n", err);
158 switch (err) {
159 case SCM_ERROR:
160 return -EIO;
161 case SCM_EINVAL_ADDR:
162 case SCM_EINVAL_ARG:
163 return -EINVAL;
164 case SCM_EOPNOTSUPP:
165 return -EOPNOTSUPP;
166 case SCM_ENOMEM:
167 return -ENOMEM;
168 }
169 return -EINVAL;
170}
171
172static u32 smc(u32 cmd_addr)
173{
174 int context_id;
175 register u32 r0 asm("r0") = 1;
176 register u32 r1 asm("r1") = (u32)&context_id;
177 register u32 r2 asm("r2") = cmd_addr;
178 do {
179 asm volatile(
180 __asmeq("%0", "r0")
181 __asmeq("%1", "r0")
182 __asmeq("%2", "r1")
183 __asmeq("%3", "r2")
184#ifdef REQUIRES_SEC
185 ".arch_extension sec\n"
186#endif
187 "smc #0 @ switch to secure world\n"
188 : "=r" (r0)
189 : "r" (r0), "r" (r1), "r" (r2)
190 : "r3");
191 } while (r0 == SCM_INTERRUPTED);
192
193 return r0;
194}
195
196static int __scm_call(const struct scm_command *cmd)
197{
198 int ret;
199 u32 cmd_addr = virt_to_phys(cmd);
200
201 /*
202 * Flush the command buffer so that the secure world sees
203 * the correct data.
204 */
205 __cpuc_flush_dcache_area((void *)cmd, cmd->len);
206 outer_flush_range(cmd_addr, cmd_addr + cmd->len);
207
208 ret = smc(cmd_addr);
209 if (ret < 0)
210 ret = scm_remap_error(ret);
211
212 return ret;
213}
214
215static void scm_inv_range(unsigned long start, unsigned long end)
216{
217 u32 cacheline_size, ctr;
218
219 asm volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (ctr));
220 cacheline_size = 4 << ((ctr >> 16) & 0xf);
221
222 start = round_down(start, cacheline_size);
223 end = round_up(end, cacheline_size);
224 outer_inv_range(start, end);
225 while (start < end) {
226 asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
227 : "memory");
228 start += cacheline_size;
229 }
230 dsb();
231 isb();
232}
233
234/**
235 * scm_call() - Send an SCM command
236 * @svc_id: service identifier
237 * @cmd_id: command identifier
238 * @cmd_buf: command buffer
239 * @cmd_len: length of the command buffer
240 * @resp_buf: response buffer
241 * @resp_len: length of the response buffer
242 *
243 * Sends a command to the SCM and waits for the command to finish processing.
244 *
245 * A note on cache maintenance:
246 * Note that any buffers that are expected to be accessed by the secure world
247 * must be flushed before invoking scm_call and invalidated in the cache
248 * immediately after scm_call returns. Cache maintenance on the command and
249 * response buffers is taken care of by scm_call; however, callers are
250 * responsible for any other cached buffers passed over to the secure world.
251 */
252int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
253 void *resp_buf, size_t resp_len)
254{
255 int ret;
256 struct scm_command *cmd;
257 struct scm_response *rsp;
258 unsigned long start, end;
259
260 cmd = alloc_scm_command(cmd_len, resp_len);
261 if (!cmd)
262 return -ENOMEM;
263
264 cmd->id = cpu_to_le32((svc_id << 10) | cmd_id);
265 if (cmd_buf)
266 memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
267
268 mutex_lock(&scm_lock);
269 ret = __scm_call(cmd);
270 mutex_unlock(&scm_lock);
271 if (ret)
272 goto out;
273
274 rsp = scm_command_to_response(cmd);
275 start = (unsigned long)rsp;
276
277 do {
278 scm_inv_range(start, start + sizeof(*rsp));
279 } while (!rsp->is_complete);
280
281 end = (unsigned long)scm_get_response_buffer(rsp) + resp_len;
282 scm_inv_range(start, end);
283
284 if (resp_buf)
285 memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
286out:
287 free_scm_command(cmd);
288 return ret;
289}
290EXPORT_SYMBOL(scm_call);
291
292u32 scm_get_version(void)
293{
294 int context_id;
295 static u32 version = -1;
296 register u32 r0 asm("r0");
297 register u32 r1 asm("r1");
298
299 if (version != -1)
300 return version;
301
302 mutex_lock(&scm_lock);
303
304 r0 = 0x1 << 8;
305 r1 = (u32)&context_id;
306 do {
307 asm volatile(
308 __asmeq("%0", "r0")
309 __asmeq("%1", "r1")
310 __asmeq("%2", "r0")
311 __asmeq("%3", "r1")
312#ifdef REQUIRES_SEC
313 ".arch_extension sec\n"
314#endif
315 "smc #0 @ switch to secure world\n"
316 : "=r" (r0), "=r" (r1)
317 : "r" (r0), "r" (r1)
318 : "r2", "r3");
319 } while (r0 == SCM_INTERRUPTED);
320
321 version = r1;
322 mutex_unlock(&scm_lock);
323
324 return version;
325}
326EXPORT_SYMBOL(scm_get_version);
diff --git a/arch/arm/mach-qcom/scm.h b/arch/arm/mach-qcom/scm.h
deleted file mode 100644
index 00b31ea58f29..000000000000
--- a/arch/arm/mach-qcom/scm.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#ifndef __MACH_SCM_H
13#define __MACH_SCM_H
14
15#define SCM_SVC_BOOT 0x1
16#define SCM_SVC_PIL 0x2
17
18extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
19 void *resp_buf, size_t resp_len);
20
21#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
22
23extern u32 scm_get_version(void);
24
25#endif
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index 4be537977040..10f9389572da 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -54,7 +54,7 @@ config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
54config ARCH_VEXPRESS_DCSCB 54config ARCH_VEXPRESS_DCSCB
55 bool "Dual Cluster System Control Block (DCSCB) support" 55 bool "Dual Cluster System Control Block (DCSCB) support"
56 depends on MCPM 56 depends on MCPM
57 select ARM_CCI 57 select ARM_CCI400_PORT_CTRL
58 help 58 help
59 Support for the Dual Cluster System Configuration Block (DCSCB). 59 Support for the Dual Cluster System Configuration Block (DCSCB).
60 This is needed to provide CPU and cluster power management 60 This is needed to provide CPU and cluster power management
@@ -72,7 +72,7 @@ config ARCH_VEXPRESS_SPC
72config ARCH_VEXPRESS_TC2_PM 72config ARCH_VEXPRESS_TC2_PM
73 bool "Versatile Express TC2 power management" 73 bool "Versatile Express TC2 power management"
74 depends on MCPM 74 depends on MCPM
75 select ARM_CCI 75 select ARM_CCI400_PORT_CTRL
76 select ARCH_VEXPRESS_SPC 76 select ARCH_VEXPRESS_SPC
77 select ARM_CPU_SUSPEND 77 select ARM_CPU_SUSPEND
78 help 78 help
diff --git a/arch/arm64/include/asm/arm-cci.h b/arch/arm64/include/asm/arm-cci.h
new file mode 100644
index 000000000000..f0b63712e10e
--- /dev/null
+++ b/arch/arm64/include/asm/arm-cci.h
@@ -0,0 +1,27 @@
1/*
2 * arch/arm64/include/asm/arm-cci.h
3 *
4 * Copyright (C) 2015 ARM Ltd.
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 * 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 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef __ASM_ARM_CCI_H
20#define __ASM_ARM_CCI_H
21
22static inline bool platform_has_secure_cci_access(void)
23{
24 return false;
25}
26
27#endif
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index cbddbaddb347..a1d4af6df3f5 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -4,6 +4,41 @@
4 4
5menu "Bus devices" 5menu "Bus devices"
6 6
7config ARM_CCI
8 bool
9
10config ARM_CCI400_COMMON
11 bool
12 select ARM_CCI
13
14config ARM_CCI400_PMU
15 bool "ARM CCI400 PMU support"
16 default y
17 depends on ARM || ARM64
18 depends on HW_PERF_EVENTS
19 select ARM_CCI400_COMMON
20 help
21 Support for PMU events monitoring on the ARM CCI cache coherent
22 interconnect.
23
24 If unsure, say Y
25
26config ARM_CCI400_PORT_CTRL
27 bool
28 depends on ARM && OF && CPU_V7
29 select ARM_CCI400_COMMON
30 help
31 Low level power management driver for CCI400 cache coherent
32 interconnect for ARM platforms.
33
34config ARM_CCN
35 bool "ARM CCN driver support"
36 depends on ARM || ARM64
37 depends on PERF_EVENTS
38 help
39 PMU (perf) driver supporting the ARM CCN (Cache Coherent Network)
40 interconnect.
41
7config BRCMSTB_GISB_ARB 42config BRCMSTB_GISB_ARB
8 bool "Broadcom STB GISB bus arbiter" 43 bool "Broadcom STB GISB bus arbiter"
9 depends on ARM || MIPS 44 depends on ARM || MIPS
@@ -40,15 +75,6 @@ config MVEBU_MBUS
40 Driver needed for the MBus configuration on Marvell EBU SoCs 75 Driver needed for the MBus configuration on Marvell EBU SoCs
41 (Kirkwood, Dove, Orion5x, MV78XX0 and Armada 370/XP). 76 (Kirkwood, Dove, Orion5x, MV78XX0 and Armada 370/XP).
42 77
43config OMAP_OCP2SCP
44 tristate "OMAP OCP2SCP DRIVER"
45 depends on ARCH_OMAP2PLUS
46 help
47 Driver to enable ocp2scp module which transforms ocp interface
48 protocol to scp protocol. In OMAP4, USB PHY is connected via
49 OCP2SCP and in OMAP5, both USB PHY and SATA PHY is connected via
50 OCP2SCP.
51
52config OMAP_INTERCONNECT 78config OMAP_INTERCONNECT
53 tristate "OMAP INTERCONNECT DRIVER" 79 tristate "OMAP INTERCONNECT DRIVER"
54 depends on ARCH_OMAP2PLUS 80 depends on ARCH_OMAP2PLUS
@@ -56,20 +82,27 @@ config OMAP_INTERCONNECT
56 help 82 help
57 Driver to enable OMAP interconnect error handling driver. 83 Driver to enable OMAP interconnect error handling driver.
58 84
59config ARM_CCI 85config OMAP_OCP2SCP
60 bool "ARM CCI driver support" 86 tristate "OMAP OCP2SCP DRIVER"
61 depends on ARM && OF && CPU_V7 87 depends on ARCH_OMAP2PLUS
62 help 88 help
63 Driver supporting the CCI cache coherent interconnect for ARM 89 Driver to enable ocp2scp module which transforms ocp interface
64 platforms. 90 protocol to scp protocol. In OMAP4, USB PHY is connected via
91 OCP2SCP and in OMAP5, both USB PHY and SATA PHY is connected via
92 OCP2SCP.
65 93
66config ARM_CCN 94config SIMPLE_PM_BUS
67 bool "ARM CCN driver support" 95 bool "Simple Power-Managed Bus Driver"
68 depends on ARM || ARM64 96 depends on OF && PM
69 depends on PERF_EVENTS 97 depends on ARCH_SHMOBILE || COMPILE_TEST
70 help 98 help
71 PMU (perf) driver supporting the ARM CCN (Cache Coherent Network) 99 Driver for transparent busses that don't need a real driver, but
72 interconnect. 100 where the bus controller is part of a PM domain, or under the control
101 of a functional clock, and thus relies on runtime PM for managing
102 this PM domain and/or clock.
103 An example of such a bus controller is the Renesas Bus State
104 Controller (BSC, sometimes called "LBSC within Bus Bridge", or
105 "External Bus Interface") as found on several Renesas ARM SoCs.
73 106
74config VEXPRESS_CONFIG 107config VEXPRESS_CONFIG
75 bool "Versatile Express configuration bus" 108 bool "Versatile Express configuration bus"
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 807dd17ef2f8..790e7b933fb2 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -2,17 +2,18 @@
2# Makefile for the bus drivers. 2# Makefile for the bus drivers.
3# 3#
4 4
5# Interconnect bus drivers for ARM platforms
6obj-$(CONFIG_ARM_CCI) += arm-cci.o
7obj-$(CONFIG_ARM_CCN) += arm-ccn.o
8
5obj-$(CONFIG_BRCMSTB_GISB_ARB) += brcmstb_gisb.o 9obj-$(CONFIG_BRCMSTB_GISB_ARB) += brcmstb_gisb.o
6obj-$(CONFIG_IMX_WEIM) += imx-weim.o 10obj-$(CONFIG_IMX_WEIM) += imx-weim.o
7obj-$(CONFIG_MIPS_CDMM) += mips_cdmm.o 11obj-$(CONFIG_MIPS_CDMM) += mips_cdmm.o
8obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o 12obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o
9obj-$(CONFIG_OMAP_OCP2SCP) += omap-ocp2scp.o
10 13
11# Interconnect bus driver for OMAP SoCs. 14# Interconnect bus driver for OMAP SoCs.
12obj-$(CONFIG_OMAP_INTERCONNECT) += omap_l3_smx.o omap_l3_noc.o 15obj-$(CONFIG_OMAP_INTERCONNECT) += omap_l3_smx.o omap_l3_noc.o
13 16
14# Interconnect bus drivers for ARM platforms 17obj-$(CONFIG_OMAP_OCP2SCP) += omap-ocp2scp.o
15obj-$(CONFIG_ARM_CCI) += arm-cci.o 18obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o
16obj-$(CONFIG_ARM_CCN) += arm-ccn.o
17
18obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o 19obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 84fd66057dad..b854125e4831 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -29,41 +29,36 @@
29#include <asm/cacheflush.h> 29#include <asm/cacheflush.h>
30#include <asm/smp_plat.h> 30#include <asm/smp_plat.h>
31 31
32#define DRIVER_NAME "CCI-400" 32static void __iomem *cci_ctrl_base;
33#define DRIVER_NAME_PMU DRIVER_NAME " PMU" 33static unsigned long cci_ctrl_phys;
34
35#define CCI_PORT_CTRL 0x0
36#define CCI_CTRL_STATUS 0xc
37
38#define CCI_ENABLE_SNOOP_REQ 0x1
39#define CCI_ENABLE_DVM_REQ 0x2
40#define CCI_ENABLE_REQ (CCI_ENABLE_SNOOP_REQ | CCI_ENABLE_DVM_REQ)
41 34
35#ifdef CONFIG_ARM_CCI400_PORT_CTRL
42struct cci_nb_ports { 36struct cci_nb_ports {
43 unsigned int nb_ace; 37 unsigned int nb_ace;
44 unsigned int nb_ace_lite; 38 unsigned int nb_ace_lite;
45}; 39};
46 40
47enum cci_ace_port_type { 41static const struct cci_nb_ports cci400_ports = {
48 ACE_INVALID_PORT = 0x0, 42 .nb_ace = 2,
49 ACE_PORT, 43 .nb_ace_lite = 3
50 ACE_LITE_PORT,
51}; 44};
52 45
53struct cci_ace_port { 46#define CCI400_PORTS_DATA (&cci400_ports)
54 void __iomem *base; 47#else
55 unsigned long phys; 48#define CCI400_PORTS_DATA (NULL)
56 enum cci_ace_port_type type; 49#endif
57 struct device_node *dn;
58};
59 50
60static struct cci_ace_port *ports; 51static const struct of_device_id arm_cci_matches[] = {
61static unsigned int nb_cci_ports; 52#ifdef CONFIG_ARM_CCI400_COMMON
53 {.compatible = "arm,cci-400", .data = CCI400_PORTS_DATA },
54#endif
55 {},
56};
62 57
63static void __iomem *cci_ctrl_base; 58#ifdef CONFIG_ARM_CCI400_PMU
64static unsigned long cci_ctrl_phys;
65 59
66#ifdef CONFIG_HW_PERF_EVENTS 60#define DRIVER_NAME "CCI-400"
61#define DRIVER_NAME_PMU DRIVER_NAME " PMU"
67 62
68#define CCI_PMCR 0x0100 63#define CCI_PMCR 0x0100
69#define CCI_PID2 0x0fe8 64#define CCI_PID2 0x0fe8
@@ -75,20 +70,6 @@ static unsigned long cci_ctrl_phys;
75#define CCI_PID2_REV_MASK 0xf0 70#define CCI_PID2_REV_MASK 0xf0
76#define CCI_PID2_REV_SHIFT 4 71#define CCI_PID2_REV_SHIFT 4
77 72
78/* Port ids */
79#define CCI_PORT_S0 0
80#define CCI_PORT_S1 1
81#define CCI_PORT_S2 2
82#define CCI_PORT_S3 3
83#define CCI_PORT_S4 4
84#define CCI_PORT_M0 5
85#define CCI_PORT_M1 6
86#define CCI_PORT_M2 7
87
88#define CCI_REV_R0 0
89#define CCI_REV_R1 1
90#define CCI_REV_R1_PX 5
91
92#define CCI_PMU_EVT_SEL 0x000 73#define CCI_PMU_EVT_SEL 0x000
93#define CCI_PMU_CNTR 0x004 74#define CCI_PMU_CNTR 0x004
94#define CCI_PMU_CNTR_CTRL 0x008 75#define CCI_PMU_CNTR_CTRL 0x008
@@ -100,76 +81,22 @@ static unsigned long cci_ctrl_phys;
100 81
101#define CCI_PMU_CNTR_MASK ((1ULL << 32) -1) 82#define CCI_PMU_CNTR_MASK ((1ULL << 32) -1)
102 83
103/* 84#define CCI_PMU_EVENT_MASK 0xffUL
104 * Instead of an event id to monitor CCI cycles, a dedicated counter is
105 * provided. Use 0xff to represent CCI cycles and hope that no future revisions
106 * make use of this event in hardware.
107 */
108enum cci400_perf_events {
109 CCI_PMU_CYCLES = 0xff
110};
111
112#define CCI_PMU_EVENT_MASK 0xff
113#define CCI_PMU_EVENT_SOURCE(event) ((event >> 5) & 0x7) 85#define CCI_PMU_EVENT_SOURCE(event) ((event >> 5) & 0x7)
114#define CCI_PMU_EVENT_CODE(event) (event & 0x1f) 86#define CCI_PMU_EVENT_CODE(event) (event & 0x1f)
115 87
116#define CCI_PMU_MAX_HW_EVENTS 5 /* CCI PMU has 4 counters + 1 cycle counter */ 88#define CCI_PMU_MAX_HW_EVENTS 5 /* CCI PMU has 4 counters + 1 cycle counter */
117 89
118#define CCI_PMU_CYCLE_CNTR_IDX 0 90/* Types of interfaces that can generate events */
119#define CCI_PMU_CNTR0_IDX 1 91enum {
120#define CCI_PMU_CNTR_LAST(cci_pmu) (CCI_PMU_CYCLE_CNTR_IDX + cci_pmu->num_events - 1) 92 CCI_IF_SLAVE,
121 93 CCI_IF_MASTER,
122/* 94 CCI_IF_MAX,
123 * CCI PMU event id is an 8-bit value made of two parts - bits 7:5 for one of 8
124 * ports and bits 4:0 are event codes. There are different event codes
125 * associated with each port type.
126 *
127 * Additionally, the range of events associated with the port types changed
128 * between Rev0 and Rev1.
129 *
130 * The constants below define the range of valid codes for each port type for
131 * the different revisions and are used to validate the event to be monitored.
132 */
133
134#define CCI_REV_R0_SLAVE_PORT_MIN_EV 0x00
135#define CCI_REV_R0_SLAVE_PORT_MAX_EV 0x13
136#define CCI_REV_R0_MASTER_PORT_MIN_EV 0x14
137#define CCI_REV_R0_MASTER_PORT_MAX_EV 0x1a
138
139#define CCI_REV_R1_SLAVE_PORT_MIN_EV 0x00
140#define CCI_REV_R1_SLAVE_PORT_MAX_EV 0x14
141#define CCI_REV_R1_MASTER_PORT_MIN_EV 0x00
142#define CCI_REV_R1_MASTER_PORT_MAX_EV 0x11
143
144struct pmu_port_event_ranges {
145 u8 slave_min;
146 u8 slave_max;
147 u8 master_min;
148 u8 master_max;
149};
150
151static struct pmu_port_event_ranges port_event_range[] = {
152 [CCI_REV_R0] = {
153 .slave_min = CCI_REV_R0_SLAVE_PORT_MIN_EV,
154 .slave_max = CCI_REV_R0_SLAVE_PORT_MAX_EV,
155 .master_min = CCI_REV_R0_MASTER_PORT_MIN_EV,
156 .master_max = CCI_REV_R0_MASTER_PORT_MAX_EV,
157 },
158 [CCI_REV_R1] = {
159 .slave_min = CCI_REV_R1_SLAVE_PORT_MIN_EV,
160 .slave_max = CCI_REV_R1_SLAVE_PORT_MAX_EV,
161 .master_min = CCI_REV_R1_MASTER_PORT_MIN_EV,
162 .master_max = CCI_REV_R1_MASTER_PORT_MAX_EV,
163 },
164}; 95};
165 96
166/* 97struct event_range {
167 * Export different PMU names for the different revisions so userspace knows 98 u32 min;
168 * because the event ids are different 99 u32 max;
169 */
170static char *const pmu_names[] = {
171 [CCI_REV_R0] = "CCI_400",
172 [CCI_REV_R1] = "CCI_400_r1",
173}; 100};
174 101
175struct cci_pmu_hw_events { 102struct cci_pmu_hw_events {
@@ -178,13 +105,20 @@ struct cci_pmu_hw_events {
178 raw_spinlock_t pmu_lock; 105 raw_spinlock_t pmu_lock;
179}; 106};
180 107
108struct cci_pmu_model {
109 char *name;
110 struct event_range event_ranges[CCI_IF_MAX];
111};
112
113static struct cci_pmu_model cci_pmu_models[];
114
181struct cci_pmu { 115struct cci_pmu {
182 void __iomem *base; 116 void __iomem *base;
183 struct pmu pmu; 117 struct pmu pmu;
184 int nr_irqs; 118 int nr_irqs;
185 int irqs[CCI_PMU_MAX_HW_EVENTS]; 119 int irqs[CCI_PMU_MAX_HW_EVENTS];
186 unsigned long active_irqs; 120 unsigned long active_irqs;
187 struct pmu_port_event_ranges *port_ranges; 121 const struct cci_pmu_model *model;
188 struct cci_pmu_hw_events hw_events; 122 struct cci_pmu_hw_events hw_events;
189 struct platform_device *plat_device; 123 struct platform_device *plat_device;
190 int num_events; 124 int num_events;
@@ -196,52 +130,63 @@ static struct cci_pmu *pmu;
196 130
197#define to_cci_pmu(c) (container_of(c, struct cci_pmu, pmu)) 131#define to_cci_pmu(c) (container_of(c, struct cci_pmu, pmu))
198 132
199static bool is_duplicate_irq(int irq, int *irqs, int nr_irqs) 133/* Port ids */
200{ 134#define CCI_PORT_S0 0
201 int i; 135#define CCI_PORT_S1 1
202 136#define CCI_PORT_S2 2
203 for (i = 0; i < nr_irqs; i++) 137#define CCI_PORT_S3 3
204 if (irq == irqs[i]) 138#define CCI_PORT_S4 4
205 return true; 139#define CCI_PORT_M0 5
206 140#define CCI_PORT_M1 6
207 return false; 141#define CCI_PORT_M2 7
208}
209 142
210static int probe_cci_revision(void) 143#define CCI_REV_R0 0
211{ 144#define CCI_REV_R1 1
212 int rev; 145#define CCI_REV_R1_PX 5
213 rev = readl_relaxed(cci_ctrl_base + CCI_PID2) & CCI_PID2_REV_MASK;
214 rev >>= CCI_PID2_REV_SHIFT;
215 146
216 if (rev < CCI_REV_R1_PX) 147/*
217 return CCI_REV_R0; 148 * Instead of an event id to monitor CCI cycles, a dedicated counter is
218 else 149 * provided. Use 0xff to represent CCI cycles and hope that no future revisions
219 return CCI_REV_R1; 150 * make use of this event in hardware.
220} 151 */
152enum cci400_perf_events {
153 CCI_PMU_CYCLES = 0xff
154};
221 155
222static struct pmu_port_event_ranges *port_range_by_rev(void) 156#define CCI_PMU_CYCLE_CNTR_IDX 0
223{ 157#define CCI_PMU_CNTR0_IDX 1
224 int rev = probe_cci_revision(); 158#define CCI_PMU_CNTR_LAST(cci_pmu) (CCI_PMU_CYCLE_CNTR_IDX + cci_pmu->num_events - 1)
225 159
226 return &port_event_range[rev]; 160/*
227} 161 * CCI PMU event id is an 8-bit value made of two parts - bits 7:5 for one of 8
162 * ports and bits 4:0 are event codes. There are different event codes
163 * associated with each port type.
164 *
165 * Additionally, the range of events associated with the port types changed
166 * between Rev0 and Rev1.
167 *
168 * The constants below define the range of valid codes for each port type for
169 * the different revisions and are used to validate the event to be monitored.
170 */
228 171
229static int pmu_is_valid_slave_event(u8 ev_code) 172#define CCI_REV_R0_SLAVE_PORT_MIN_EV 0x00
230{ 173#define CCI_REV_R0_SLAVE_PORT_MAX_EV 0x13
231 return pmu->port_ranges->slave_min <= ev_code && 174#define CCI_REV_R0_MASTER_PORT_MIN_EV 0x14
232 ev_code <= pmu->port_ranges->slave_max; 175#define CCI_REV_R0_MASTER_PORT_MAX_EV 0x1a
233}
234 176
235static int pmu_is_valid_master_event(u8 ev_code) 177#define CCI_REV_R1_SLAVE_PORT_MIN_EV 0x00
236{ 178#define CCI_REV_R1_SLAVE_PORT_MAX_EV 0x14
237 return pmu->port_ranges->master_min <= ev_code && 179#define CCI_REV_R1_MASTER_PORT_MIN_EV 0x00
238 ev_code <= pmu->port_ranges->master_max; 180#define CCI_REV_R1_MASTER_PORT_MAX_EV 0x11
239}
240 181
241static int pmu_validate_hw_event(u8 hw_event) 182static int pmu_validate_hw_event(unsigned long hw_event)
242{ 183{
243 u8 ev_source = CCI_PMU_EVENT_SOURCE(hw_event); 184 u8 ev_source = CCI_PMU_EVENT_SOURCE(hw_event);
244 u8 ev_code = CCI_PMU_EVENT_CODE(hw_event); 185 u8 ev_code = CCI_PMU_EVENT_CODE(hw_event);
186 int if_type;
187
188 if (hw_event & ~CCI_PMU_EVENT_MASK)
189 return -ENOENT;
245 190
246 switch (ev_source) { 191 switch (ev_source) {
247 case CCI_PORT_S0: 192 case CCI_PORT_S0:
@@ -250,21 +195,44 @@ static int pmu_validate_hw_event(u8 hw_event)
250 case CCI_PORT_S3: 195 case CCI_PORT_S3:
251 case CCI_PORT_S4: 196 case CCI_PORT_S4:
252 /* Slave Interface */ 197 /* Slave Interface */
253 if (pmu_is_valid_slave_event(ev_code)) 198 if_type = CCI_IF_SLAVE;
254 return hw_event;
255 break; 199 break;
256 case CCI_PORT_M0: 200 case CCI_PORT_M0:
257 case CCI_PORT_M1: 201 case CCI_PORT_M1:
258 case CCI_PORT_M2: 202 case CCI_PORT_M2:
259 /* Master Interface */ 203 /* Master Interface */
260 if (pmu_is_valid_master_event(ev_code)) 204 if_type = CCI_IF_MASTER;
261 return hw_event;
262 break; 205 break;
206 default:
207 return -ENOENT;
263 } 208 }
264 209
210 if (ev_code >= pmu->model->event_ranges[if_type].min &&
211 ev_code <= pmu->model->event_ranges[if_type].max)
212 return hw_event;
213
265 return -ENOENT; 214 return -ENOENT;
266} 215}
267 216
217static int probe_cci_revision(void)
218{
219 int rev;
220 rev = readl_relaxed(cci_ctrl_base + CCI_PID2) & CCI_PID2_REV_MASK;
221 rev >>= CCI_PID2_REV_SHIFT;
222
223 if (rev < CCI_REV_R1_PX)
224 return CCI_REV_R0;
225 else
226 return CCI_REV_R1;
227}
228
229static const struct cci_pmu_model *probe_cci_model(struct platform_device *pdev)
230{
231 if (platform_has_secure_cci_access())
232 return &cci_pmu_models[probe_cci_revision()];
233 return NULL;
234}
235
268static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx) 236static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx)
269{ 237{
270 return CCI_PMU_CYCLE_CNTR_IDX <= idx && 238 return CCI_PMU_CYCLE_CNTR_IDX <= idx &&
@@ -293,7 +261,6 @@ static void pmu_enable_counter(int idx)
293 261
294static void pmu_set_event(int idx, unsigned long event) 262static void pmu_set_event(int idx, unsigned long event)
295{ 263{
296 event &= CCI_PMU_EVENT_MASK;
297 pmu_write_register(event, idx, CCI_PMU_EVT_SEL); 264 pmu_write_register(event, idx, CCI_PMU_EVT_SEL);
298} 265}
299 266
@@ -310,7 +277,7 @@ static int pmu_get_event_idx(struct cci_pmu_hw_events *hw, struct perf_event *ev
310{ 277{
311 struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu); 278 struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
312 struct hw_perf_event *hw_event = &event->hw; 279 struct hw_perf_event *hw_event = &event->hw;
313 unsigned long cci_event = hw_event->config_base & CCI_PMU_EVENT_MASK; 280 unsigned long cci_event = hw_event->config_base;
314 int idx; 281 int idx;
315 282
316 if (cci_event == CCI_PMU_CYCLES) { 283 if (cci_event == CCI_PMU_CYCLES) {
@@ -331,7 +298,7 @@ static int pmu_get_event_idx(struct cci_pmu_hw_events *hw, struct perf_event *ev
331static int pmu_map_event(struct perf_event *event) 298static int pmu_map_event(struct perf_event *event)
332{ 299{
333 int mapping; 300 int mapping;
334 u8 config = event->attr.config & CCI_PMU_EVENT_MASK; 301 unsigned long config = event->attr.config;
335 302
336 if (event->attr.type < PERF_TYPE_MAX) 303 if (event->attr.type < PERF_TYPE_MAX)
337 return -ENOENT; 304 return -ENOENT;
@@ -660,12 +627,21 @@ static void cci_pmu_del(struct perf_event *event, int flags)
660} 627}
661 628
662static int 629static int
663validate_event(struct cci_pmu_hw_events *hw_events, 630validate_event(struct pmu *cci_pmu,
664 struct perf_event *event) 631 struct cci_pmu_hw_events *hw_events,
632 struct perf_event *event)
665{ 633{
666 if (is_software_event(event)) 634 if (is_software_event(event))
667 return 1; 635 return 1;
668 636
637 /*
638 * Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The
639 * core perf code won't check that the pmu->ctx == leader->ctx
640 * until after pmu->event_init(event).
641 */
642 if (event->pmu != cci_pmu)
643 return 0;
644
669 if (event->state < PERF_EVENT_STATE_OFF) 645 if (event->state < PERF_EVENT_STATE_OFF)
670 return 1; 646 return 1;
671 647
@@ -687,15 +663,15 @@ validate_group(struct perf_event *event)
687 .used_mask = CPU_BITS_NONE, 663 .used_mask = CPU_BITS_NONE,
688 }; 664 };
689 665
690 if (!validate_event(&fake_pmu, leader)) 666 if (!validate_event(event->pmu, &fake_pmu, leader))
691 return -EINVAL; 667 return -EINVAL;
692 668
693 list_for_each_entry(sibling, &leader->sibling_list, group_entry) { 669 list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
694 if (!validate_event(&fake_pmu, sibling)) 670 if (!validate_event(event->pmu, &fake_pmu, sibling))
695 return -EINVAL; 671 return -EINVAL;
696 } 672 }
697 673
698 if (!validate_event(&fake_pmu, event)) 674 if (!validate_event(event->pmu, &fake_pmu, event))
699 return -EINVAL; 675 return -EINVAL;
700 676
701 return 0; 677 return 0;
@@ -831,9 +807,9 @@ static const struct attribute_group *pmu_attr_groups[] = {
831 807
832static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev) 808static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev)
833{ 809{
834 char *name = pmu_names[probe_cci_revision()]; 810 char *name = cci_pmu->model->name;
835 cci_pmu->pmu = (struct pmu) { 811 cci_pmu->pmu = (struct pmu) {
836 .name = pmu_names[probe_cci_revision()], 812 .name = cci_pmu->model->name,
837 .task_ctx_nr = perf_invalid_context, 813 .task_ctx_nr = perf_invalid_context,
838 .pmu_enable = cci_pmu_enable, 814 .pmu_enable = cci_pmu_enable,
839 .pmu_disable = cci_pmu_disable, 815 .pmu_disable = cci_pmu_disable,
@@ -886,22 +862,93 @@ static struct notifier_block cci_pmu_cpu_nb = {
886 .priority = CPU_PRI_PERF + 1, 862 .priority = CPU_PRI_PERF + 1,
887}; 863};
888 864
865static struct cci_pmu_model cci_pmu_models[] = {
866 [CCI_REV_R0] = {
867 .name = "CCI_400",
868 .event_ranges = {
869 [CCI_IF_SLAVE] = {
870 CCI_REV_R0_SLAVE_PORT_MIN_EV,
871 CCI_REV_R0_SLAVE_PORT_MAX_EV,
872 },
873 [CCI_IF_MASTER] = {
874 CCI_REV_R0_MASTER_PORT_MIN_EV,
875 CCI_REV_R0_MASTER_PORT_MAX_EV,
876 },
877 },
878 },
879 [CCI_REV_R1] = {
880 .name = "CCI_400_r1",
881 .event_ranges = {
882 [CCI_IF_SLAVE] = {
883 CCI_REV_R1_SLAVE_PORT_MIN_EV,
884 CCI_REV_R1_SLAVE_PORT_MAX_EV,
885 },
886 [CCI_IF_MASTER] = {
887 CCI_REV_R1_MASTER_PORT_MIN_EV,
888 CCI_REV_R1_MASTER_PORT_MAX_EV,
889 },
890 },
891 },
892};
893
889static const struct of_device_id arm_cci_pmu_matches[] = { 894static const struct of_device_id arm_cci_pmu_matches[] = {
890 { 895 {
891 .compatible = "arm,cci-400-pmu", 896 .compatible = "arm,cci-400-pmu",
897 .data = NULL,
898 },
899 {
900 .compatible = "arm,cci-400-pmu,r0",
901 .data = &cci_pmu_models[CCI_REV_R0],
902 },
903 {
904 .compatible = "arm,cci-400-pmu,r1",
905 .data = &cci_pmu_models[CCI_REV_R1],
892 }, 906 },
893 {}, 907 {},
894}; 908};
895 909
910static inline const struct cci_pmu_model *get_cci_model(struct platform_device *pdev)
911{
912 const struct of_device_id *match = of_match_node(arm_cci_pmu_matches,
913 pdev->dev.of_node);
914 if (!match)
915 return NULL;
916 if (match->data)
917 return match->data;
918
919 dev_warn(&pdev->dev, "DEPRECATED compatible property,"
920 "requires secure access to CCI registers");
921 return probe_cci_model(pdev);
922}
923
924static bool is_duplicate_irq(int irq, int *irqs, int nr_irqs)
925{
926 int i;
927
928 for (i = 0; i < nr_irqs; i++)
929 if (irq == irqs[i])
930 return true;
931
932 return false;
933}
934
896static int cci_pmu_probe(struct platform_device *pdev) 935static int cci_pmu_probe(struct platform_device *pdev)
897{ 936{
898 struct resource *res; 937 struct resource *res;
899 int i, ret, irq; 938 int i, ret, irq;
939 const struct cci_pmu_model *model;
940
941 model = get_cci_model(pdev);
942 if (!model) {
943 dev_warn(&pdev->dev, "CCI PMU version not supported\n");
944 return -ENODEV;
945 }
900 946
901 pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL); 947 pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL);
902 if (!pmu) 948 if (!pmu)
903 return -ENOMEM; 949 return -ENOMEM;
904 950
951 pmu->model = model;
905 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 952 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
906 pmu->base = devm_ioremap_resource(&pdev->dev, res); 953 pmu->base = devm_ioremap_resource(&pdev->dev, res);
907 if (IS_ERR(pmu->base)) 954 if (IS_ERR(pmu->base))
@@ -933,12 +980,6 @@ static int cci_pmu_probe(struct platform_device *pdev)
933 return -EINVAL; 980 return -EINVAL;
934 } 981 }
935 982
936 pmu->port_ranges = port_range_by_rev();
937 if (!pmu->port_ranges) {
938 dev_warn(&pdev->dev, "CCI PMU version not supported\n");
939 return -EINVAL;
940 }
941
942 raw_spin_lock_init(&pmu->hw_events.pmu_lock); 983 raw_spin_lock_init(&pmu->hw_events.pmu_lock);
943 mutex_init(&pmu->reserve_mutex); 984 mutex_init(&pmu->reserve_mutex);
944 atomic_set(&pmu->active_events, 0); 985 atomic_set(&pmu->active_events, 0);
@@ -952,6 +993,7 @@ static int cci_pmu_probe(struct platform_device *pdev)
952 if (ret) 993 if (ret)
953 return ret; 994 return ret;
954 995
996 pr_info("ARM %s PMU driver probed", pmu->model->name);
955 return 0; 997 return 0;
956} 998}
957 999
@@ -963,7 +1005,66 @@ static int cci_platform_probe(struct platform_device *pdev)
963 return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); 1005 return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
964} 1006}
965 1007
966#endif /* CONFIG_HW_PERF_EVENTS */ 1008static struct platform_driver cci_pmu_driver = {
1009 .driver = {
1010 .name = DRIVER_NAME_PMU,
1011 .of_match_table = arm_cci_pmu_matches,
1012 },
1013 .probe = cci_pmu_probe,
1014};
1015
1016static struct platform_driver cci_platform_driver = {
1017 .driver = {
1018 .name = DRIVER_NAME,
1019 .of_match_table = arm_cci_matches,
1020 },
1021 .probe = cci_platform_probe,
1022};
1023
1024static int __init cci_platform_init(void)
1025{
1026 int ret;
1027
1028 ret = platform_driver_register(&cci_pmu_driver);
1029 if (ret)
1030 return ret;
1031
1032 return platform_driver_register(&cci_platform_driver);
1033}
1034
1035#else /* !CONFIG_ARM_CCI400_PMU */
1036
1037static int __init cci_platform_init(void)
1038{
1039 return 0;
1040}
1041
1042#endif /* CONFIG_ARM_CCI400_PMU */
1043
1044#ifdef CONFIG_ARM_CCI400_PORT_CTRL
1045
1046#define CCI_PORT_CTRL 0x0
1047#define CCI_CTRL_STATUS 0xc
1048
1049#define CCI_ENABLE_SNOOP_REQ 0x1
1050#define CCI_ENABLE_DVM_REQ 0x2
1051#define CCI_ENABLE_REQ (CCI_ENABLE_SNOOP_REQ | CCI_ENABLE_DVM_REQ)
1052
1053enum cci_ace_port_type {
1054 ACE_INVALID_PORT = 0x0,
1055 ACE_PORT,
1056 ACE_LITE_PORT,
1057};
1058
1059struct cci_ace_port {
1060 void __iomem *base;
1061 unsigned long phys;
1062 enum cci_ace_port_type type;
1063 struct device_node *dn;
1064};
1065
1066static struct cci_ace_port *ports;
1067static unsigned int nb_cci_ports;
967 1068
968struct cpu_port { 1069struct cpu_port {
969 u64 mpidr; 1070 u64 mpidr;
@@ -1284,36 +1385,20 @@ int notrace __cci_control_port_by_index(u32 port, bool enable)
1284} 1385}
1285EXPORT_SYMBOL_GPL(__cci_control_port_by_index); 1386EXPORT_SYMBOL_GPL(__cci_control_port_by_index);
1286 1387
1287static const struct cci_nb_ports cci400_ports = {
1288 .nb_ace = 2,
1289 .nb_ace_lite = 3
1290};
1291
1292static const struct of_device_id arm_cci_matches[] = {
1293 {.compatible = "arm,cci-400", .data = &cci400_ports },
1294 {},
1295};
1296
1297static const struct of_device_id arm_cci_ctrl_if_matches[] = { 1388static const struct of_device_id arm_cci_ctrl_if_matches[] = {
1298 {.compatible = "arm,cci-400-ctrl-if", }, 1389 {.compatible = "arm,cci-400-ctrl-if", },
1299 {}, 1390 {},
1300}; 1391};
1301 1392
1302static int cci_probe(void) 1393static int cci_probe_ports(struct device_node *np)
1303{ 1394{
1304 struct cci_nb_ports const *cci_config; 1395 struct cci_nb_ports const *cci_config;
1305 int ret, i, nb_ace = 0, nb_ace_lite = 0; 1396 int ret, i, nb_ace = 0, nb_ace_lite = 0;
1306 struct device_node *np, *cp; 1397 struct device_node *cp;
1307 struct resource res; 1398 struct resource res;
1308 const char *match_str; 1399 const char *match_str;
1309 bool is_ace; 1400 bool is_ace;
1310 1401
1311 np = of_find_matching_node(NULL, arm_cci_matches);
1312 if (!np)
1313 return -ENODEV;
1314
1315 if (!of_device_is_available(np))
1316 return -ENODEV;
1317 1402
1318 cci_config = of_match_node(arm_cci_matches, np)->data; 1403 cci_config = of_match_node(arm_cci_matches, np)->data;
1319 if (!cci_config) 1404 if (!cci_config)
@@ -1325,17 +1410,6 @@ static int cci_probe(void)
1325 if (!ports) 1410 if (!ports)
1326 return -ENOMEM; 1411 return -ENOMEM;
1327 1412
1328 ret = of_address_to_resource(np, 0, &res);
1329 if (!ret) {
1330 cci_ctrl_base = ioremap(res.start, resource_size(&res));
1331 cci_ctrl_phys = res.start;
1332 }
1333 if (ret || !cci_ctrl_base) {
1334 WARN(1, "unable to ioremap CCI ctrl\n");
1335 ret = -ENXIO;
1336 goto memalloc_err;
1337 }
1338
1339 for_each_child_of_node(np, cp) { 1413 for_each_child_of_node(np, cp) {
1340 if (!of_match_node(arm_cci_ctrl_if_matches, cp)) 1414 if (!of_match_node(arm_cci_ctrl_if_matches, cp))
1341 continue; 1415 continue;
@@ -1395,12 +1469,37 @@ static int cci_probe(void)
1395 sync_cache_w(&cpu_port); 1469 sync_cache_w(&cpu_port);
1396 __sync_cache_range_w(ports, sizeof(*ports) * nb_cci_ports); 1470 __sync_cache_range_w(ports, sizeof(*ports) * nb_cci_ports);
1397 pr_info("ARM CCI driver probed\n"); 1471 pr_info("ARM CCI driver probed\n");
1472
1398 return 0; 1473 return 0;
1474}
1475#else /* !CONFIG_ARM_CCI400_PORT_CTRL */
1476static inline int cci_probe_ports(struct device_node *np)
1477{
1478 return 0;
1479}
1480#endif /* CONFIG_ARM_CCI400_PORT_CTRL */
1399 1481
1400memalloc_err: 1482static int cci_probe(void)
1483{
1484 int ret;
1485 struct device_node *np;
1486 struct resource res;
1487
1488 np = of_find_matching_node(NULL, arm_cci_matches);
1489 if(!np || !of_device_is_available(np))
1490 return -ENODEV;
1401 1491
1402 kfree(ports); 1492 ret = of_address_to_resource(np, 0, &res);
1403 return ret; 1493 if (!ret) {
1494 cci_ctrl_base = ioremap(res.start, resource_size(&res));
1495 cci_ctrl_phys = res.start;
1496 }
1497 if (ret || !cci_ctrl_base) {
1498 WARN(1, "unable to ioremap CCI ctrl\n");
1499 return -ENXIO;
1500 }
1501
1502 return cci_probe_ports(np);
1404} 1503}
1405 1504
1406static int cci_init_status = -EAGAIN; 1505static int cci_init_status = -EAGAIN;
@@ -1418,42 +1517,6 @@ static int cci_init(void)
1418 return cci_init_status; 1517 return cci_init_status;
1419} 1518}
1420 1519
1421#ifdef CONFIG_HW_PERF_EVENTS
1422static struct platform_driver cci_pmu_driver = {
1423 .driver = {
1424 .name = DRIVER_NAME_PMU,
1425 .of_match_table = arm_cci_pmu_matches,
1426 },
1427 .probe = cci_pmu_probe,
1428};
1429
1430static struct platform_driver cci_platform_driver = {
1431 .driver = {
1432 .name = DRIVER_NAME,
1433 .of_match_table = arm_cci_matches,
1434 },
1435 .probe = cci_platform_probe,
1436};
1437
1438static int __init cci_platform_init(void)
1439{
1440 int ret;
1441
1442 ret = platform_driver_register(&cci_pmu_driver);
1443 if (ret)
1444 return ret;
1445
1446 return platform_driver_register(&cci_platform_driver);
1447}
1448
1449#else
1450
1451static int __init cci_platform_init(void)
1452{
1453 return 0;
1454}
1455
1456#endif
1457/* 1520/*
1458 * To sort out early init calls ordering a helper function is provided to 1521 * To sort out early init calls ordering a helper function is provided to
1459 * check if the CCI driver has beed initialized. Function check if the driver 1522 * check if the CCI driver has beed initialized. Function check if the driver
diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c
new file mode 100644
index 000000000000..c5eb46cbf388
--- /dev/null
+++ b/drivers/bus/simple-pm-bus.c
@@ -0,0 +1,58 @@
1/*
2 * Simple Power-Managed Bus Driver
3 *
4 * Copyright (C) 2014-2015 Glider bvba
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/module.h>
12#include <linux/of_platform.h>
13#include <linux/platform_device.h>
14#include <linux/pm_runtime.h>
15
16
17static int simple_pm_bus_probe(struct platform_device *pdev)
18{
19 struct device_node *np = pdev->dev.of_node;
20
21 dev_dbg(&pdev->dev, "%s\n", __func__);
22
23 pm_runtime_enable(&pdev->dev);
24
25 if (np)
26 of_platform_populate(np, NULL, NULL, &pdev->dev);
27
28 return 0;
29}
30
31static int simple_pm_bus_remove(struct platform_device *pdev)
32{
33 dev_dbg(&pdev->dev, "%s\n", __func__);
34
35 pm_runtime_disable(&pdev->dev);
36 return 0;
37}
38
39static const struct of_device_id simple_pm_bus_of_match[] = {
40 { .compatible = "simple-pm-bus", },
41 { /* sentinel */ }
42};
43MODULE_DEVICE_TABLE(of, simple_pm_bus_of_match);
44
45static struct platform_driver simple_pm_bus_driver = {
46 .probe = simple_pm_bus_probe,
47 .remove = simple_pm_bus_remove,
48 .driver = {
49 .name = "simple-pm-bus",
50 .of_match_table = simple_pm_bus_of_match,
51 },
52};
53
54module_platform_driver(simple_pm_bus_driver);
55
56MODULE_DESCRIPTION("Simple Power-Managed Bus Driver");
57MODULE_AUTHOR("Geert Uytterhoeven <geert+renesas@glider.be>");
58MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index b4ac7cfae441..51d7865fdddb 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -143,6 +143,11 @@ config ATMEL_PIT
143 select CLKSRC_OF if OF 143 select CLKSRC_OF if OF
144 def_bool SOC_AT91SAM9 || SOC_SAMA5 144 def_bool SOC_AT91SAM9 || SOC_SAMA5
145 145
146config ATMEL_ST
147 bool
148 select CLKSRC_OF
149 select MFD_SYSCON
150
146config CLKSRC_METAG_GENERIC 151config CLKSRC_METAG_GENERIC
147 def_bool y if METAG 152 def_bool y if METAG
148 help 153 help
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 752d5c70b0ef..5b85f6adb258 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -1,5 +1,6 @@
1obj-$(CONFIG_CLKSRC_OF) += clksrc-of.o 1obj-$(CONFIG_CLKSRC_OF) += clksrc-of.o
2obj-$(CONFIG_ATMEL_PIT) += timer-atmel-pit.o 2obj-$(CONFIG_ATMEL_PIT) += timer-atmel-pit.o
3obj-$(CONFIG_ATMEL_ST) += timer-atmel-st.o
3obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o 4obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o
4obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o 5obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
5obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o 6obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/drivers/clocksource/timer-atmel-st.c
index b00d09555f2b..1692e17e096b 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/drivers/clocksource/timer-atmel-st.c
@@ -24,19 +24,17 @@
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/clockchips.h> 25#include <linux/clockchips.h>
26#include <linux/export.h> 26#include <linux/export.h>
27#include <linux/of.h> 27#include <linux/mfd/syscon.h>
28#include <linux/of_address.h> 28#include <linux/mfd/syscon/atmel-st.h>
29#include <linux/of_irq.h> 29#include <linux/of_irq.h>
30 30#include <linux/regmap.h>
31#include <asm/mach/time.h>
32
33#include <mach/at91_st.h>
34#include <mach/hardware.h>
35 31
36static unsigned long last_crtr; 32static unsigned long last_crtr;
37static u32 irqmask; 33static u32 irqmask;
38static struct clock_event_device clkevt; 34static struct clock_event_device clkevt;
35static struct regmap *regmap_st;
39 36
37#define AT91_SLOW_CLOCK 32768
40#define RM9200_TIMER_LATCH ((AT91_SLOW_CLOCK + HZ/2) / HZ) 38#define RM9200_TIMER_LATCH ((AT91_SLOW_CLOCK + HZ/2) / HZ)
41 39
42/* 40/*
@@ -46,11 +44,11 @@ static struct clock_event_device clkevt;
46 */ 44 */
47static inline unsigned long read_CRTR(void) 45static inline unsigned long read_CRTR(void)
48{ 46{
49 unsigned long x1, x2; 47 unsigned int x1, x2;
50 48
51 x1 = at91_st_read(AT91_ST_CRTR); 49 regmap_read(regmap_st, AT91_ST_CRTR, &x1);
52 do { 50 do {
53 x2 = at91_st_read(AT91_ST_CRTR); 51 regmap_read(regmap_st, AT91_ST_CRTR, &x2);
54 if (x1 == x2) 52 if (x1 == x2)
55 break; 53 break;
56 x1 = x2; 54 x1 = x2;
@@ -63,7 +61,10 @@ static inline unsigned long read_CRTR(void)
63 */ 61 */
64static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) 62static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
65{ 63{
66 u32 sr = at91_st_read(AT91_ST_SR) & irqmask; 64 u32 sr;
65
66 regmap_read(regmap_st, AT91_ST_SR, &sr);
67 sr &= irqmask;
67 68
68 /* 69 /*
69 * irqs should be disabled here, but as the irq is shared they are only 70 * irqs should be disabled here, but as the irq is shared they are only
@@ -92,13 +93,6 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
92 return IRQ_NONE; 93 return IRQ_NONE;
93} 94}
94 95
95static struct irqaction at91rm9200_timer_irq = {
96 .name = "at91_tick",
97 .flags = IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL,
98 .handler = at91rm9200_timer_interrupt,
99 .irq = NR_IRQS_LEGACY + AT91_ID_SYS,
100};
101
102static cycle_t read_clk32k(struct clocksource *cs) 96static cycle_t read_clk32k(struct clocksource *cs)
103{ 97{
104 return read_CRTR(); 98 return read_CRTR();
@@ -115,23 +109,25 @@ static struct clocksource clk32k = {
115static void 109static void
116clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) 110clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
117{ 111{
112 unsigned int val;
113
118 /* Disable and flush pending timer interrupts */ 114 /* Disable and flush pending timer interrupts */
119 at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS); 115 regmap_write(regmap_st, AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
120 at91_st_read(AT91_ST_SR); 116 regmap_read(regmap_st, AT91_ST_SR, &val);
121 117
122 last_crtr = read_CRTR(); 118 last_crtr = read_CRTR();
123 switch (mode) { 119 switch (mode) {
124 case CLOCK_EVT_MODE_PERIODIC: 120 case CLOCK_EVT_MODE_PERIODIC:
125 /* PIT for periodic irqs; fixed rate of 1/HZ */ 121 /* PIT for periodic irqs; fixed rate of 1/HZ */
126 irqmask = AT91_ST_PITS; 122 irqmask = AT91_ST_PITS;
127 at91_st_write(AT91_ST_PIMR, RM9200_TIMER_LATCH); 123 regmap_write(regmap_st, AT91_ST_PIMR, RM9200_TIMER_LATCH);
128 break; 124 break;
129 case CLOCK_EVT_MODE_ONESHOT: 125 case CLOCK_EVT_MODE_ONESHOT:
130 /* ALM for oneshot irqs, set by next_event() 126 /* ALM for oneshot irqs, set by next_event()
131 * before 32 seconds have passed 127 * before 32 seconds have passed
132 */ 128 */
133 irqmask = AT91_ST_ALMS; 129 irqmask = AT91_ST_ALMS;
134 at91_st_write(AT91_ST_RTAR, last_crtr); 130 regmap_write(regmap_st, AT91_ST_RTAR, last_crtr);
135 break; 131 break;
136 case CLOCK_EVT_MODE_SHUTDOWN: 132 case CLOCK_EVT_MODE_SHUTDOWN:
137 case CLOCK_EVT_MODE_UNUSED: 133 case CLOCK_EVT_MODE_UNUSED:
@@ -139,7 +135,7 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
139 irqmask = 0; 135 irqmask = 0;
140 break; 136 break;
141 } 137 }
142 at91_st_write(AT91_ST_IER, irqmask); 138 regmap_write(regmap_st, AT91_ST_IER, irqmask);
143} 139}
144 140
145static int 141static int
@@ -147,6 +143,7 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
147{ 143{
148 u32 alm; 144 u32 alm;
149 int status = 0; 145 int status = 0;
146 unsigned int val;
150 147
151 BUG_ON(delta < 2); 148 BUG_ON(delta < 2);
152 149
@@ -162,12 +159,12 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
162 alm = read_CRTR(); 159 alm = read_CRTR();
163 160
164 /* Cancel any pending alarm; flush any pending IRQ */ 161 /* Cancel any pending alarm; flush any pending IRQ */
165 at91_st_write(AT91_ST_RTAR, alm); 162 regmap_write(regmap_st, AT91_ST_RTAR, alm);
166 at91_st_read(AT91_ST_SR); 163 regmap_read(regmap_st, AT91_ST_SR, &val);
167 164
168 /* Schedule alarm by writing RTAR. */ 165 /* Schedule alarm by writing RTAR. */
169 alm += delta; 166 alm += delta;
170 at91_st_write(AT91_ST_RTAR, alm); 167 regmap_write(regmap_st, AT91_ST_RTAR, alm);
171 168
172 return status; 169 return status;
173} 170}
@@ -180,66 +177,40 @@ static struct clock_event_device clkevt = {
180 .set_mode = clkevt32k_mode, 177 .set_mode = clkevt32k_mode,
181}; 178};
182 179
183void __iomem *at91_st_base;
184EXPORT_SYMBOL_GPL(at91_st_base);
185
186static const struct of_device_id at91rm9200_st_timer_ids[] = {
187 { .compatible = "atmel,at91rm9200-st" },
188 { /* sentinel */ }
189};
190
191static int __init of_at91rm9200_st_init(void)
192{
193 struct device_node *np;
194 int ret;
195
196 np = of_find_matching_node(NULL, at91rm9200_st_timer_ids);
197 if (!np)
198 goto err;
199
200 at91_st_base = of_iomap(np, 0);
201 if (!at91_st_base)
202 goto node_err;
203
204 /* Get the interrupts property */
205 ret = irq_of_parse_and_map(np, 0);
206 if (!ret)
207 goto ioremap_err;
208 at91rm9200_timer_irq.irq = ret;
209
210 of_node_put(np);
211
212 return 0;
213
214ioremap_err:
215 iounmap(at91_st_base);
216node_err:
217 of_node_put(np);
218err:
219 return -EINVAL;
220}
221
222/* 180/*
223 * ST (system timer) module supports both clockevents and clocksource. 181 * ST (system timer) module supports both clockevents and clocksource.
224 */ 182 */
225void __init at91rm9200_timer_init(void) 183static void __init atmel_st_timer_init(struct device_node *node)
226{ 184{
227 /* For device tree enabled device: initialize here */ 185 unsigned int val;
228 of_at91rm9200_st_init(); 186 int irq, ret;
187
188 regmap_st = syscon_node_to_regmap(node);
189 if (IS_ERR(regmap_st))
190 panic(pr_fmt("Unable to get regmap\n"));
229 191
230 /* Disable all timer interrupts, and clear any pending ones */ 192 /* Disable all timer interrupts, and clear any pending ones */
231 at91_st_write(AT91_ST_IDR, 193 regmap_write(regmap_st, AT91_ST_IDR,
232 AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); 194 AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
233 at91_st_read(AT91_ST_SR); 195 regmap_read(regmap_st, AT91_ST_SR, &val);
196
197 /* Get the interrupts property */
198 irq = irq_of_parse_and_map(node, 0);
199 if (!irq)
200 panic(pr_fmt("Unable to get IRQ from DT\n"));
234 201
235 /* Make IRQs happen for the system timer */ 202 /* Make IRQs happen for the system timer */
236 setup_irq(at91rm9200_timer_irq.irq, &at91rm9200_timer_irq); 203 ret = request_irq(irq, at91rm9200_timer_interrupt,
204 IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL,
205 "at91_tick", regmap_st);
206 if (ret)
207 panic(pr_fmt("Unable to setup IRQ\n"));
237 208
238 /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used 209 /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used
239 * directly for the clocksource and all clockevents, after adjusting 210 * directly for the clocksource and all clockevents, after adjusting
240 * its prescaler from the 1 Hz default. 211 * its prescaler from the 1 Hz default.
241 */ 212 */
242 at91_st_write(AT91_ST_RTMR, 1); 213 regmap_write(regmap_st, AT91_ST_RTMR, 1);
243 214
244 /* Setup timer clockevent, with minimum of two ticks (important!!) */ 215 /* Setup timer clockevent, with minimum of two ticks (important!!) */
245 clkevt.cpumask = cpumask_of(0); 216 clkevt.cpumask = cpumask_of(0);
@@ -249,3 +220,5 @@ void __init at91rm9200_timer_init(void)
249 /* register clocksource */ 220 /* register clocksource */
250 clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK); 221 clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
251} 222}
223CLOCKSOURCE_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st",
224 atmel_st_timer_init);
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 41983883cef4..6517132e5d8b 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -132,6 +132,10 @@ config ISCSI_IBFT
132 detect iSCSI boot parameters dynamically during system boot, say Y. 132 detect iSCSI boot parameters dynamically during system boot, say Y.
133 Otherwise, say N. 133 Otherwise, say N.
134 134
135config QCOM_SCM
136 bool
137 depends on ARM || ARM64
138
135source "drivers/firmware/google/Kconfig" 139source "drivers/firmware/google/Kconfig"
136source "drivers/firmware/efi/Kconfig" 140source "drivers/firmware/efi/Kconfig"
137 141
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 5373dc5b6011..3fdd3912709a 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -11,6 +11,8 @@ obj-$(CONFIG_DMIID) += dmi-id.o
11obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o 11obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
12obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o 12obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
13obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o 13obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
14obj-$(CONFIG_QCOM_SCM) += qcom_scm.o
15CFLAGS_qcom_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
14 16
15obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ 17obj-$(CONFIG_GOOGLE_FIRMWARE) += google/
16obj-$(CONFIG_EFI) += efi/ 18obj-$(CONFIG_EFI) += efi/
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
new file mode 100644
index 000000000000..994b50fd997c
--- /dev/null
+++ b/drivers/firmware/qcom_scm.c
@@ -0,0 +1,494 @@
1/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
2 * Copyright (C) 2015 Linaro Ltd.
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 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301, USA.
17 */
18
19#include <linux/slab.h>
20#include <linux/io.h>
21#include <linux/module.h>
22#include <linux/mutex.h>
23#include <linux/errno.h>
24#include <linux/err.h>
25#include <linux/qcom_scm.h>
26
27#include <asm/outercache.h>
28#include <asm/cacheflush.h>
29
30
31#define QCOM_SCM_ENOMEM -5
32#define QCOM_SCM_EOPNOTSUPP -4
33#define QCOM_SCM_EINVAL_ADDR -3
34#define QCOM_SCM_EINVAL_ARG -2
35#define QCOM_SCM_ERROR -1
36#define QCOM_SCM_INTERRUPTED 1
37
38#define QCOM_SCM_FLAG_COLDBOOT_CPU0 0x00
39#define QCOM_SCM_FLAG_COLDBOOT_CPU1 0x01
40#define QCOM_SCM_FLAG_COLDBOOT_CPU2 0x08
41#define QCOM_SCM_FLAG_COLDBOOT_CPU3 0x20
42
43#define QCOM_SCM_FLAG_WARMBOOT_CPU0 0x04
44#define QCOM_SCM_FLAG_WARMBOOT_CPU1 0x02
45#define QCOM_SCM_FLAG_WARMBOOT_CPU2 0x10
46#define QCOM_SCM_FLAG_WARMBOOT_CPU3 0x40
47
48struct qcom_scm_entry {
49 int flag;
50 void *entry;
51};
52
53static struct qcom_scm_entry qcom_scm_wb[] = {
54 { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU0 },
55 { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU1 },
56 { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU2 },
57 { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU3 },
58};
59
60static DEFINE_MUTEX(qcom_scm_lock);
61
62/**
63 * struct qcom_scm_command - one SCM command buffer
64 * @len: total available memory for command and response
65 * @buf_offset: start of command buffer
66 * @resp_hdr_offset: start of response buffer
67 * @id: command to be executed
68 * @buf: buffer returned from qcom_scm_get_command_buffer()
69 *
70 * An SCM command is laid out in memory as follows:
71 *
72 * ------------------- <--- struct qcom_scm_command
73 * | command header |
74 * ------------------- <--- qcom_scm_get_command_buffer()
75 * | command buffer |
76 * ------------------- <--- struct qcom_scm_response and
77 * | response header | qcom_scm_command_to_response()
78 * ------------------- <--- qcom_scm_get_response_buffer()
79 * | response buffer |
80 * -------------------
81 *
82 * There can be arbitrary padding between the headers and buffers so
83 * you should always use the appropriate qcom_scm_get_*_buffer() routines
84 * to access the buffers in a safe manner.
85 */
86struct qcom_scm_command {
87 __le32 len;
88 __le32 buf_offset;
89 __le32 resp_hdr_offset;
90 __le32 id;
91 __le32 buf[0];
92};
93
94/**
95 * struct qcom_scm_response - one SCM response buffer
96 * @len: total available memory for response
97 * @buf_offset: start of response data relative to start of qcom_scm_response
98 * @is_complete: indicates if the command has finished processing
99 */
100struct qcom_scm_response {
101 __le32 len;
102 __le32 buf_offset;
103 __le32 is_complete;
104};
105
106/**
107 * alloc_qcom_scm_command() - Allocate an SCM command
108 * @cmd_size: size of the command buffer
109 * @resp_size: size of the response buffer
110 *
111 * Allocate an SCM command, including enough room for the command
112 * and response headers as well as the command and response buffers.
113 *
114 * Returns a valid &qcom_scm_command on success or %NULL if the allocation fails.
115 */
116static struct qcom_scm_command *alloc_qcom_scm_command(size_t cmd_size, size_t resp_size)
117{
118 struct qcom_scm_command *cmd;
119 size_t len = sizeof(*cmd) + sizeof(struct qcom_scm_response) + cmd_size +
120 resp_size;
121 u32 offset;
122
123 cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
124 if (cmd) {
125 cmd->len = cpu_to_le32(len);
126 offset = offsetof(struct qcom_scm_command, buf);
127 cmd->buf_offset = cpu_to_le32(offset);
128 cmd->resp_hdr_offset = cpu_to_le32(offset + cmd_size);
129 }
130 return cmd;
131}
132
133/**
134 * free_qcom_scm_command() - Free an SCM command
135 * @cmd: command to free
136 *
137 * Free an SCM command.
138 */
139static inline void free_qcom_scm_command(struct qcom_scm_command *cmd)
140{
141 kfree(cmd);
142}
143
144/**
145 * qcom_scm_command_to_response() - Get a pointer to a qcom_scm_response
146 * @cmd: command
147 *
148 * Returns a pointer to a response for a command.
149 */
150static inline struct qcom_scm_response *qcom_scm_command_to_response(
151 const struct qcom_scm_command *cmd)
152{
153 return (void *)cmd + le32_to_cpu(cmd->resp_hdr_offset);
154}
155
156/**
157 * qcom_scm_get_command_buffer() - Get a pointer to a command buffer
158 * @cmd: command
159 *
160 * Returns a pointer to the command buffer of a command.
161 */
162static inline void *qcom_scm_get_command_buffer(const struct qcom_scm_command *cmd)
163{
164 return (void *)cmd->buf;
165}
166
167/**
168 * qcom_scm_get_response_buffer() - Get a pointer to a response buffer
169 * @rsp: response
170 *
171 * Returns a pointer to a response buffer of a response.
172 */
173static inline void *qcom_scm_get_response_buffer(const struct qcom_scm_response *rsp)
174{
175 return (void *)rsp + le32_to_cpu(rsp->buf_offset);
176}
177
178static int qcom_scm_remap_error(int err)
179{
180 pr_err("qcom_scm_call failed with error code %d\n", err);
181 switch (err) {
182 case QCOM_SCM_ERROR:
183 return -EIO;
184 case QCOM_SCM_EINVAL_ADDR:
185 case QCOM_SCM_EINVAL_ARG:
186 return -EINVAL;
187 case QCOM_SCM_EOPNOTSUPP:
188 return -EOPNOTSUPP;
189 case QCOM_SCM_ENOMEM:
190 return -ENOMEM;
191 }
192 return -EINVAL;
193}
194
195static u32 smc(u32 cmd_addr)
196{
197 int context_id;
198 register u32 r0 asm("r0") = 1;
199 register u32 r1 asm("r1") = (u32)&context_id;
200 register u32 r2 asm("r2") = cmd_addr;
201 do {
202 asm volatile(
203 __asmeq("%0", "r0")
204 __asmeq("%1", "r0")
205 __asmeq("%2", "r1")
206 __asmeq("%3", "r2")
207#ifdef REQUIRES_SEC
208 ".arch_extension sec\n"
209#endif
210 "smc #0 @ switch to secure world\n"
211 : "=r" (r0)
212 : "r" (r0), "r" (r1), "r" (r2)
213 : "r3");
214 } while (r0 == QCOM_SCM_INTERRUPTED);
215
216 return r0;
217}
218
219static int __qcom_scm_call(const struct qcom_scm_command *cmd)
220{
221 int ret;
222 u32 cmd_addr = virt_to_phys(cmd);
223
224 /*
225 * Flush the command buffer so that the secure world sees
226 * the correct data.
227 */
228 __cpuc_flush_dcache_area((void *)cmd, cmd->len);
229 outer_flush_range(cmd_addr, cmd_addr + cmd->len);
230
231 ret = smc(cmd_addr);
232 if (ret < 0)
233 ret = qcom_scm_remap_error(ret);
234
235 return ret;
236}
237
238static void qcom_scm_inv_range(unsigned long start, unsigned long end)
239{
240 u32 cacheline_size, ctr;
241
242 asm volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (ctr));
243 cacheline_size = 4 << ((ctr >> 16) & 0xf);
244
245 start = round_down(start, cacheline_size);
246 end = round_up(end, cacheline_size);
247 outer_inv_range(start, end);
248 while (start < end) {
249 asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
250 : "memory");
251 start += cacheline_size;
252 }
253 dsb();
254 isb();
255}
256
257/**
258 * qcom_scm_call() - Send an SCM command
259 * @svc_id: service identifier
260 * @cmd_id: command identifier
261 * @cmd_buf: command buffer
262 * @cmd_len: length of the command buffer
263 * @resp_buf: response buffer
264 * @resp_len: length of the response buffer
265 *
266 * Sends a command to the SCM and waits for the command to finish processing.
267 *
268 * A note on cache maintenance:
269 * Note that any buffers that are expected to be accessed by the secure world
270 * must be flushed before invoking qcom_scm_call and invalidated in the cache
271 * immediately after qcom_scm_call returns. Cache maintenance on the command
272 * and response buffers is taken care of by qcom_scm_call; however, callers are
273 * responsible for any other cached buffers passed over to the secure world.
274 */
275static int qcom_scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf,
276 size_t cmd_len, void *resp_buf, size_t resp_len)
277{
278 int ret;
279 struct qcom_scm_command *cmd;
280 struct qcom_scm_response *rsp;
281 unsigned long start, end;
282
283 cmd = alloc_qcom_scm_command(cmd_len, resp_len);
284 if (!cmd)
285 return -ENOMEM;
286
287 cmd->id = cpu_to_le32((svc_id << 10) | cmd_id);
288 if (cmd_buf)
289 memcpy(qcom_scm_get_command_buffer(cmd), cmd_buf, cmd_len);
290
291 mutex_lock(&qcom_scm_lock);
292 ret = __qcom_scm_call(cmd);
293 mutex_unlock(&qcom_scm_lock);
294 if (ret)
295 goto out;
296
297 rsp = qcom_scm_command_to_response(cmd);
298 start = (unsigned long)rsp;
299
300 do {
301 qcom_scm_inv_range(start, start + sizeof(*rsp));
302 } while (!rsp->is_complete);
303
304 end = (unsigned long)qcom_scm_get_response_buffer(rsp) + resp_len;
305 qcom_scm_inv_range(start, end);
306
307 if (resp_buf)
308 memcpy(resp_buf, qcom_scm_get_response_buffer(rsp), resp_len);
309out:
310 free_qcom_scm_command(cmd);
311 return ret;
312}
313
314#define SCM_CLASS_REGISTER (0x2 << 8)
315#define SCM_MASK_IRQS BIT(5)
316#define SCM_ATOMIC(svc, cmd, n) (((((svc) << 10)|((cmd) & 0x3ff)) << 12) | \
317 SCM_CLASS_REGISTER | \
318 SCM_MASK_IRQS | \
319 (n & 0xf))
320
321/**
322 * qcom_scm_call_atomic1() - Send an atomic SCM command with one argument
323 * @svc_id: service identifier
324 * @cmd_id: command identifier
325 * @arg1: first argument
326 *
327 * This shall only be used with commands that are guaranteed to be
328 * uninterruptable, atomic and SMP safe.
329 */
330static s32 qcom_scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
331{
332 int context_id;
333
334 register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 1);
335 register u32 r1 asm("r1") = (u32)&context_id;
336 register u32 r2 asm("r2") = arg1;
337
338 asm volatile(
339 __asmeq("%0", "r0")
340 __asmeq("%1", "r0")
341 __asmeq("%2", "r1")
342 __asmeq("%3", "r2")
343#ifdef REQUIRES_SEC
344 ".arch_extension sec\n"
345#endif
346 "smc #0 @ switch to secure world\n"
347 : "=r" (r0)
348 : "r" (r0), "r" (r1), "r" (r2)
349 : "r3");
350 return r0;
351}
352
353u32 qcom_scm_get_version(void)
354{
355 int context_id;
356 static u32 version = -1;
357 register u32 r0 asm("r0");
358 register u32 r1 asm("r1");
359
360 if (version != -1)
361 return version;
362
363 mutex_lock(&qcom_scm_lock);
364
365 r0 = 0x1 << 8;
366 r1 = (u32)&context_id;
367 do {
368 asm volatile(
369 __asmeq("%0", "r0")
370 __asmeq("%1", "r1")
371 __asmeq("%2", "r0")
372 __asmeq("%3", "r1")
373#ifdef REQUIRES_SEC
374 ".arch_extension sec\n"
375#endif
376 "smc #0 @ switch to secure world\n"
377 : "=r" (r0), "=r" (r1)
378 : "r" (r0), "r" (r1)
379 : "r2", "r3");
380 } while (r0 == QCOM_SCM_INTERRUPTED);
381
382 version = r1;
383 mutex_unlock(&qcom_scm_lock);
384
385 return version;
386}
387EXPORT_SYMBOL(qcom_scm_get_version);
388
389#define QCOM_SCM_SVC_BOOT 0x1
390#define QCOM_SCM_BOOT_ADDR 0x1
391/*
392 * Set the cold/warm boot address for one of the CPU cores.
393 */
394static int qcom_scm_set_boot_addr(u32 addr, int flags)
395{
396 struct {
397 __le32 flags;
398 __le32 addr;
399 } cmd;
400
401 cmd.addr = cpu_to_le32(addr);
402 cmd.flags = cpu_to_le32(flags);
403 return qcom_scm_call(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR,
404 &cmd, sizeof(cmd), NULL, 0);
405}
406
407/**
408 * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
409 * @entry: Entry point function for the cpus
410 * @cpus: The cpumask of cpus that will use the entry point
411 *
412 * Set the cold boot address of the cpus. Any cpu outside the supported
413 * range would be removed from the cpu present mask.
414 */
415int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
416{
417 int flags = 0;
418 int cpu;
419 int scm_cb_flags[] = {
420 QCOM_SCM_FLAG_COLDBOOT_CPU0,
421 QCOM_SCM_FLAG_COLDBOOT_CPU1,
422 QCOM_SCM_FLAG_COLDBOOT_CPU2,
423 QCOM_SCM_FLAG_COLDBOOT_CPU3,
424 };
425
426 if (!cpus || (cpus && cpumask_empty(cpus)))
427 return -EINVAL;
428
429 for_each_cpu(cpu, cpus) {
430 if (cpu < ARRAY_SIZE(scm_cb_flags))
431 flags |= scm_cb_flags[cpu];
432 else
433 set_cpu_present(cpu, false);
434 }
435
436 return qcom_scm_set_boot_addr(virt_to_phys(entry), flags);
437}
438EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);
439
440/**
441 * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
442 * @entry: Entry point function for the cpus
443 * @cpus: The cpumask of cpus that will use the entry point
444 *
445 * Set the Linux entry point for the SCM to transfer control to when coming
446 * out of a power down. CPU power down may be executed on cpuidle or hotplug.
447 */
448int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
449{
450 int ret;
451 int flags = 0;
452 int cpu;
453
454 /*
455 * Reassign only if we are switching from hotplug entry point
456 * to cpuidle entry point or vice versa.
457 */
458 for_each_cpu(cpu, cpus) {
459 if (entry == qcom_scm_wb[cpu].entry)
460 continue;
461 flags |= qcom_scm_wb[cpu].flag;
462 }
463
464 /* No change in entry function */
465 if (!flags)
466 return 0;
467
468 ret = qcom_scm_set_boot_addr(virt_to_phys(entry), flags);
469 if (!ret) {
470 for_each_cpu(cpu, cpus)
471 qcom_scm_wb[cpu].entry = entry;
472 }
473
474 return ret;
475}
476EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
477
478#define QCOM_SCM_CMD_TERMINATE_PC 0x2
479#define QCOM_SCM_FLUSH_FLAG_MASK 0x3
480
481/**
482 * qcom_scm_cpu_power_down() - Power down the cpu
483 * @flags - Flags to flush cache
484 *
485 * This is an end point to power down cpu. If there was a pending interrupt,
486 * the control would return from this function, otherwise, the cpu jumps to the
487 * warm boot entry point set for this cpu upon reset.
488 */
489void qcom_scm_cpu_power_down(u32 flags)
490{
491 qcom_scm_call_atomic1(QCOM_SCM_SVC_BOOT, QCOM_SCM_CMD_TERMINATE_PC,
492 flags & QCOM_SCM_FLUSH_FLAG_MASK);
493}
494EXPORT_SYMBOL(qcom_scm_cpu_power_down);
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 24696f59215b..c94ea0d68746 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -12,8 +12,6 @@
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation. 13 * published by the Free Software Foundation.
14 */ 14 */
15#undef DEBUG
16
17#include <linux/irq.h> 15#include <linux/irq.h>
18#include <linux/kernel.h> 16#include <linux/kernel.h>
19#include <linux/init.h> 17#include <linux/init.h>
@@ -29,6 +27,7 @@
29#include <linux/of_address.h> 27#include <linux/of_address.h>
30#include <linux/of_mtd.h> 28#include <linux/of_mtd.h>
31#include <linux/of_device.h> 29#include <linux/of_device.h>
30#include <linux/of_platform.h>
32#include <linux/omap-gpmc.h> 31#include <linux/omap-gpmc.h>
33#include <linux/mtd/nand.h> 32#include <linux/mtd/nand.h>
34#include <linux/pm_runtime.h> 33#include <linux/pm_runtime.h>
@@ -136,13 +135,21 @@
136#define GPMC_CONFIG1_WRITETYPE_ASYNC (0 << 27) 135#define GPMC_CONFIG1_WRITETYPE_ASYNC (0 << 27)
137#define GPMC_CONFIG1_WRITETYPE_SYNC (1 << 27) 136#define GPMC_CONFIG1_WRITETYPE_SYNC (1 << 27)
138#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25) 137#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25)
138/** CLKACTIVATIONTIME Max Ticks */
139#define GPMC_CONFIG1_CLKACTIVATIONTIME_MAX 2
139#define GPMC_CONFIG1_PAGE_LEN(val) ((val & 3) << 23) 140#define GPMC_CONFIG1_PAGE_LEN(val) ((val & 3) << 23)
141/** ATTACHEDDEVICEPAGELENGTH Max Value */
142#define GPMC_CONFIG1_ATTACHEDDEVICEPAGELENGTH_MAX 2
140#define GPMC_CONFIG1_WAIT_READ_MON (1 << 22) 143#define GPMC_CONFIG1_WAIT_READ_MON (1 << 22)
141#define GPMC_CONFIG1_WAIT_WRITE_MON (1 << 21) 144#define GPMC_CONFIG1_WAIT_WRITE_MON (1 << 21)
142#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18) 145#define GPMC_CONFIG1_WAIT_MON_TIME(val) ((val & 3) << 18)
146/** WAITMONITORINGTIME Max Ticks */
147#define GPMC_CONFIG1_WAITMONITORINGTIME_MAX 2
143#define GPMC_CONFIG1_WAIT_PIN_SEL(val) ((val & 3) << 16) 148#define GPMC_CONFIG1_WAIT_PIN_SEL(val) ((val & 3) << 16)
144#define GPMC_CONFIG1_DEVICESIZE(val) ((val & 3) << 12) 149#define GPMC_CONFIG1_DEVICESIZE(val) ((val & 3) << 12)
145#define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1) 150#define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1)
151/** DEVICESIZE Max Value */
152#define GPMC_CONFIG1_DEVICESIZE_MAX 1
146#define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10) 153#define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10)
147#define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) 154#define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0)
148#define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8) 155#define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8)
@@ -153,6 +160,15 @@
153#define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3)) 160#define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3))
154#define GPMC_CONFIG7_CSVALID (1 << 6) 161#define GPMC_CONFIG7_CSVALID (1 << 6)
155 162
163#define GPMC_CONFIG7_BASEADDRESS_MASK 0x3f
164#define GPMC_CONFIG7_CSVALID_MASK BIT(6)
165#define GPMC_CONFIG7_MASKADDRESS_OFFSET 8
166#define GPMC_CONFIG7_MASKADDRESS_MASK (0xf << GPMC_CONFIG7_MASKADDRESS_OFFSET)
167/* All CONFIG7 bits except reserved bits */
168#define GPMC_CONFIG7_MASK (GPMC_CONFIG7_BASEADDRESS_MASK | \
169 GPMC_CONFIG7_CSVALID_MASK | \
170 GPMC_CONFIG7_MASKADDRESS_MASK)
171
156#define GPMC_DEVICETYPE_NOR 0 172#define GPMC_DEVICETYPE_NOR 0
157#define GPMC_DEVICETYPE_NAND 2 173#define GPMC_DEVICETYPE_NAND 2
158#define GPMC_CONFIG_WRITEPROTECT 0x00000010 174#define GPMC_CONFIG_WRITEPROTECT 0x00000010
@@ -169,6 +185,11 @@
169 */ 185 */
170#define GPMC_NR_IRQ 2 186#define GPMC_NR_IRQ 2
171 187
188enum gpmc_clk_domain {
189 GPMC_CD_FCLK,
190 GPMC_CD_CLK
191};
192
172struct gpmc_cs_data { 193struct gpmc_cs_data {
173 const char *name; 194 const char *name;
174 195
@@ -267,16 +288,55 @@ static unsigned long gpmc_get_fclk_period(void)
267 return rate; 288 return rate;
268} 289}
269 290
270static unsigned int gpmc_ns_to_ticks(unsigned int time_ns) 291/**
292 * gpmc_get_clk_period - get period of selected clock domain in ps
293 * @cs Chip Select Region.
294 * @cd Clock Domain.
295 *
296 * GPMC_CS_CONFIG1 GPMCFCLKDIVIDER for cs has to be setup
297 * prior to calling this function with GPMC_CD_CLK.
298 */
299static unsigned long gpmc_get_clk_period(int cs, enum gpmc_clk_domain cd)
300{
301
302 unsigned long tick_ps = gpmc_get_fclk_period();
303 u32 l;
304 int div;
305
306 switch (cd) {
307 case GPMC_CD_CLK:
308 /* get current clk divider */
309 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
310 div = (l & 0x03) + 1;
311 /* get GPMC_CLK period */
312 tick_ps *= div;
313 break;
314 case GPMC_CD_FCLK:
315 /* FALL-THROUGH */
316 default:
317 break;
318 }
319
320 return tick_ps;
321
322}
323
324static unsigned int gpmc_ns_to_clk_ticks(unsigned int time_ns, int cs,
325 enum gpmc_clk_domain cd)
271{ 326{
272 unsigned long tick_ps; 327 unsigned long tick_ps;
273 328
274 /* Calculate in picosecs to yield more exact results */ 329 /* Calculate in picosecs to yield more exact results */
275 tick_ps = gpmc_get_fclk_period(); 330 tick_ps = gpmc_get_clk_period(cs, cd);
276 331
277 return (time_ns * 1000 + tick_ps - 1) / tick_ps; 332 return (time_ns * 1000 + tick_ps - 1) / tick_ps;
278} 333}
279 334
335static unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
336{
337 return gpmc_ns_to_clk_ticks(time_ns, /* any CS */ 0, GPMC_CD_FCLK);
338}
339
280static unsigned int gpmc_ps_to_ticks(unsigned int time_ps) 340static unsigned int gpmc_ps_to_ticks(unsigned int time_ps)
281{ 341{
282 unsigned long tick_ps; 342 unsigned long tick_ps;
@@ -287,9 +347,15 @@ static unsigned int gpmc_ps_to_ticks(unsigned int time_ps)
287 return (time_ps + tick_ps - 1) / tick_ps; 347 return (time_ps + tick_ps - 1) / tick_ps;
288} 348}
289 349
350unsigned int gpmc_clk_ticks_to_ns(unsigned ticks, int cs,
351 enum gpmc_clk_domain cd)
352{
353 return ticks * gpmc_get_clk_period(cs, cd) / 1000;
354}
355
290unsigned int gpmc_ticks_to_ns(unsigned int ticks) 356unsigned int gpmc_ticks_to_ns(unsigned int ticks)
291{ 357{
292 return ticks * gpmc_get_fclk_period() / 1000; 358 return gpmc_clk_ticks_to_ns(ticks, /* any CS */ 0, GPMC_CD_FCLK);
293} 359}
294 360
295static unsigned int gpmc_ticks_to_ps(unsigned int ticks) 361static unsigned int gpmc_ticks_to_ps(unsigned int ticks)
@@ -338,33 +404,66 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
338} 404}
339 405
340#ifdef DEBUG 406#ifdef DEBUG
341static int get_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, 407/**
342 bool raw, bool noval, int shift, 408 * get_gpmc_timing_reg - read a timing parameter and print DTS settings for it.
343 const char *name) 409 * @cs: Chip Select Region
410 * @reg: GPMC_CS_CONFIGn register offset.
411 * @st_bit: Start Bit
412 * @end_bit: End Bit. Must be >= @st_bit.
413 * @ma:x Maximum parameter value (before optional @shift).
414 * If 0, maximum is as high as @st_bit and @end_bit allow.
415 * @name: DTS node name, w/o "gpmc,"
416 * @cd: Clock Domain of timing parameter.
417 * @shift: Parameter value left shifts @shift, which is then printed instead of value.
418 * @raw: Raw Format Option.
419 * raw format: gpmc,name = <value>
420 * tick format: gpmc,name = <value> /&zwj;* x ns -- y ns; x ticks *&zwj;/
421 * Where x ns -- y ns result in the same tick value.
422 * When @max is exceeded, "invalid" is printed inside comment.
423 * @noval: Parameter values equal to 0 are not printed.
424 * @return: Specified timing parameter (after optional @shift).
425 *
426 */
427static int get_gpmc_timing_reg(
428 /* timing specifiers */
429 int cs, int reg, int st_bit, int end_bit, int max,
430 const char *name, const enum gpmc_clk_domain cd,
431 /* value transform */
432 int shift,
433 /* format specifiers */
434 bool raw, bool noval)
344{ 435{
345 u32 l; 436 u32 l;
346 int nr_bits, max_value, mask; 437 int nr_bits;
438 int mask;
439 bool invalid;
347 440
348 l = gpmc_cs_read_reg(cs, reg); 441 l = gpmc_cs_read_reg(cs, reg);
349 nr_bits = end_bit - st_bit + 1; 442 nr_bits = end_bit - st_bit + 1;
350 max_value = (1 << nr_bits) - 1; 443 mask = (1 << nr_bits) - 1;
351 mask = max_value << st_bit; 444 l = (l >> st_bit) & mask;
352 l = (l & mask) >> st_bit; 445 if (!max)
446 max = mask;
447 invalid = l > max;
353 if (shift) 448 if (shift)
354 l = (shift << l); 449 l = (shift << l);
355 if (noval && (l == 0)) 450 if (noval && (l == 0))
356 return 0; 451 return 0;
357 if (!raw) { 452 if (!raw) {
358 unsigned int time_ns_min, time_ns, time_ns_max; 453 /* DTS tick format for timings in ns */
359 454 unsigned int time_ns;
360 time_ns_min = gpmc_ticks_to_ns(l ? l - 1 : 0); 455 unsigned int time_ns_min = 0;
361 time_ns = gpmc_ticks_to_ns(l); 456
362 time_ns_max = gpmc_ticks_to_ns(l + 1 > max_value ? 457 if (l)
363 max_value : l + 1); 458 time_ns_min = gpmc_clk_ticks_to_ns(l - 1, cs, cd) + 1;
364 pr_info("gpmc,%s = <%u> (%u - %u ns, %i ticks)\n", 459 time_ns = gpmc_clk_ticks_to_ns(l, cs, cd);
365 name, time_ns, time_ns_min, time_ns_max, l); 460 pr_info("gpmc,%s = <%u> /* %u ns - %u ns; %i ticks%s*/\n",
461 name, time_ns, time_ns_min, time_ns, l,
462 invalid ? "; invalid " : " ");
366 } else { 463 } else {
367 pr_info("gpmc,%s = <%u>\n", name, l); 464 /* raw format */
465 pr_info("gpmc,%s = <%u>%s\n", name, l,
466 invalid ? " /* invalid */" : "");
368 } 467 }
369 468
370 return l; 469 return l;
@@ -374,13 +473,19 @@ static int get_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
374 pr_info("cs%i %s: 0x%08x\n", cs, #config, \ 473 pr_info("cs%i %s: 0x%08x\n", cs, #config, \
375 gpmc_cs_read_reg(cs, config)) 474 gpmc_cs_read_reg(cs, config))
376#define GPMC_GET_RAW(reg, st, end, field) \ 475#define GPMC_GET_RAW(reg, st, end, field) \
377 get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 0, 0, field) 476 get_gpmc_timing_reg(cs, (reg), (st), (end), 0, field, GPMC_CD_FCLK, 0, 1, 0)
477#define GPMC_GET_RAW_MAX(reg, st, end, max, field) \
478 get_gpmc_timing_reg(cs, (reg), (st), (end), (max), field, GPMC_CD_FCLK, 0, 1, 0)
378#define GPMC_GET_RAW_BOOL(reg, st, end, field) \ 479#define GPMC_GET_RAW_BOOL(reg, st, end, field) \
379 get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 1, 0, field) 480 get_gpmc_timing_reg(cs, (reg), (st), (end), 0, field, GPMC_CD_FCLK, 0, 1, 1)
380#define GPMC_GET_RAW_SHIFT(reg, st, end, shift, field) \ 481#define GPMC_GET_RAW_SHIFT_MAX(reg, st, end, shift, max, field) \
381 get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 1, (shift), field) 482 get_gpmc_timing_reg(cs, (reg), (st), (end), (max), field, GPMC_CD_FCLK, (shift), 1, 1)
382#define GPMC_GET_TICKS(reg, st, end, field) \ 483#define GPMC_GET_TICKS(reg, st, end, field) \
383 get_gpmc_timing_reg(cs, (reg), (st), (end), 0, 0, 0, field) 484 get_gpmc_timing_reg(cs, (reg), (st), (end), 0, field, GPMC_CD_FCLK, 0, 0, 0)
485#define GPMC_GET_TICKS_CD(reg, st, end, field, cd) \
486 get_gpmc_timing_reg(cs, (reg), (st), (end), 0, field, (cd), 0, 0, 0)
487#define GPMC_GET_TICKS_CD_MAX(reg, st, end, max, field, cd) \
488 get_gpmc_timing_reg(cs, (reg), (st), (end), (max), field, (cd), 0, 0, 0)
384 489
385static void gpmc_show_regs(int cs, const char *desc) 490static void gpmc_show_regs(int cs, const char *desc)
386{ 491{
@@ -404,11 +509,14 @@ static void gpmc_cs_show_timings(int cs, const char *desc)
404 pr_info("gpmc cs%i access configuration:\n", cs); 509 pr_info("gpmc cs%i access configuration:\n", cs);
405 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 4, 4, "time-para-granularity"); 510 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 4, 4, "time-para-granularity");
406 GPMC_GET_RAW(GPMC_CS_CONFIG1, 8, 9, "mux-add-data"); 511 GPMC_GET_RAW(GPMC_CS_CONFIG1, 8, 9, "mux-add-data");
407 GPMC_GET_RAW(GPMC_CS_CONFIG1, 12, 13, "device-width"); 512 GPMC_GET_RAW_MAX(GPMC_CS_CONFIG1, 12, 13,
513 GPMC_CONFIG1_DEVICESIZE_MAX, "device-width");
408 GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin"); 514 GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin");
409 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write"); 515 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write");
410 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read"); 516 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read");
411 GPMC_GET_RAW_SHIFT(GPMC_CS_CONFIG1, 23, 24, 4, "burst-length"); 517 GPMC_GET_RAW_SHIFT_MAX(GPMC_CS_CONFIG1, 23, 24, 4,
518 GPMC_CONFIG1_ATTACHEDDEVICEPAGELENGTH_MAX,
519 "burst-length");
412 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 27, 27, "sync-write"); 520 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 27, 27, "sync-write");
413 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 28, 28, "burst-write"); 521 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 28, 28, "burst-write");
414 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 29, 29, "gpmc,sync-read"); 522 GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 29, 29, "gpmc,sync-read");
@@ -448,8 +556,12 @@ static void gpmc_cs_show_timings(int cs, const char *desc)
448 GPMC_GET_TICKS(GPMC_CS_CONFIG6, 0, 3, "bus-turnaround-ns"); 556 GPMC_GET_TICKS(GPMC_CS_CONFIG6, 0, 3, "bus-turnaround-ns");
449 GPMC_GET_TICKS(GPMC_CS_CONFIG6, 8, 11, "cycle2cycle-delay-ns"); 557 GPMC_GET_TICKS(GPMC_CS_CONFIG6, 8, 11, "cycle2cycle-delay-ns");
450 558
451 GPMC_GET_TICKS(GPMC_CS_CONFIG1, 18, 19, "wait-monitoring-ns"); 559 GPMC_GET_TICKS_CD_MAX(GPMC_CS_CONFIG1, 18, 19,
452 GPMC_GET_TICKS(GPMC_CS_CONFIG1, 25, 26, "clk-activation-ns"); 560 GPMC_CONFIG1_WAITMONITORINGTIME_MAX,
561 "wait-monitoring-ns", GPMC_CD_CLK);
562 GPMC_GET_TICKS_CD_MAX(GPMC_CS_CONFIG1, 25, 26,
563 GPMC_CONFIG1_CLKACTIVATIONTIME_MAX,
564 "clk-activation-ns", GPMC_CD_FCLK);
453 565
454 GPMC_GET_TICKS(GPMC_CS_CONFIG6, 16, 19, "wr-data-mux-bus-ns"); 566 GPMC_GET_TICKS(GPMC_CS_CONFIG6, 16, 19, "wr-data-mux-bus-ns");
455 GPMC_GET_TICKS(GPMC_CS_CONFIG6, 24, 28, "wr-access-ns"); 567 GPMC_GET_TICKS(GPMC_CS_CONFIG6, 24, 28, "wr-access-ns");
@@ -460,8 +572,24 @@ static inline void gpmc_cs_show_timings(int cs, const char *desc)
460} 572}
461#endif 573#endif
462 574
463static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, 575/**
464 int time, const char *name) 576 * set_gpmc_timing_reg - set a single timing parameter for Chip Select Region.
577 * Caller is expected to have initialized CONFIG1 GPMCFCLKDIVIDER
578 * prior to calling this function with @cd equal to GPMC_CD_CLK.
579 *
580 * @cs: Chip Select Region.
581 * @reg: GPMC_CS_CONFIGn register offset.
582 * @st_bit: Start Bit
583 * @end_bit: End Bit. Must be >= @st_bit.
584 * @max: Maximum parameter value.
585 * If 0, maximum is as high as @st_bit and @end_bit allow.
586 * @time: Timing parameter in ns.
587 * @cd: Timing parameter clock domain.
588 * @name: Timing parameter name.
589 * @return: 0 on success, -1 on error.
590 */
591static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, int max,
592 int time, enum gpmc_clk_domain cd, const char *name)
465{ 593{
466 u32 l; 594 u32 l;
467 int ticks, mask, nr_bits; 595 int ticks, mask, nr_bits;
@@ -469,22 +597,25 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
469 if (time == 0) 597 if (time == 0)
470 ticks = 0; 598 ticks = 0;
471 else 599 else
472 ticks = gpmc_ns_to_ticks(time); 600 ticks = gpmc_ns_to_clk_ticks(time, cs, cd);
473 nr_bits = end_bit - st_bit + 1; 601 nr_bits = end_bit - st_bit + 1;
474 mask = (1 << nr_bits) - 1; 602 mask = (1 << nr_bits) - 1;
475 603
476 if (ticks > mask) { 604 if (!max)
477 pr_err("%s: GPMC error! CS%d: %s: %d ns, %d ticks > %d\n", 605 max = mask;
478 __func__, cs, name, time, ticks, mask); 606
607 if (ticks > max) {
608 pr_err("%s: GPMC CS%d: %s %d ns, %d ticks > %d ticks\n",
609 __func__, cs, name, time, ticks, max);
479 610
480 return -1; 611 return -1;
481 } 612 }
482 613
483 l = gpmc_cs_read_reg(cs, reg); 614 l = gpmc_cs_read_reg(cs, reg);
484#ifdef DEBUG 615#ifdef DEBUG
485 printk(KERN_INFO 616 pr_info(
486 "GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", 617 "GPMC CS%d: %-17s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
487 cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000, 618 cs, name, ticks, gpmc_get_clk_period(cs, cd) * ticks / 1000,
488 (l >> st_bit) & mask, time); 619 (l >> st_bit) & mask, time);
489#endif 620#endif
490 l &= ~(mask << st_bit); 621 l &= ~(mask << st_bit);
@@ -494,18 +625,56 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
494 return 0; 625 return 0;
495} 626}
496 627
497#define GPMC_SET_ONE(reg, st, end, field) \ 628#define GPMC_SET_ONE_CD_MAX(reg, st, end, max, field, cd) \
498 if (set_gpmc_timing_reg(cs, (reg), (st), (end), \ 629 if (set_gpmc_timing_reg(cs, (reg), (st), (end), (max), \
499 t->field, #field) < 0) \ 630 t->field, (cd), #field) < 0) \
500 return -1 631 return -1
501 632
633#define GPMC_SET_ONE(reg, st, end, field) \
634 GPMC_SET_ONE_CD_MAX(reg, st, end, 0, field, GPMC_CD_FCLK)
635
636/**
637 * gpmc_calc_waitmonitoring_divider - calculate proper GPMCFCLKDIVIDER based on WAITMONITORINGTIME
638 * WAITMONITORINGTIME will be _at least_ as long as desired, i.e.
639 * read --> don't sample bus too early
640 * write --> data is longer on bus
641 *
642 * Formula:
643 * gpmc_clk_div + 1 = ceil(ceil(waitmonitoringtime_ns / gpmc_fclk_ns)
644 * / waitmonitoring_ticks)
645 * WAITMONITORINGTIME resulting in 0 or 1 tick with div = 1 are caught by
646 * div <= 0 check.
647 *
648 * @wait_monitoring: WAITMONITORINGTIME in ns.
649 * @return: -1 on failure to scale, else proper divider > 0.
650 */
651static int gpmc_calc_waitmonitoring_divider(unsigned int wait_monitoring)
652{
653
654 int div = gpmc_ns_to_ticks(wait_monitoring);
655
656 div += GPMC_CONFIG1_WAITMONITORINGTIME_MAX - 1;
657 div /= GPMC_CONFIG1_WAITMONITORINGTIME_MAX;
658
659 if (div > 4)
660 return -1;
661 if (div <= 0)
662 div = 1;
663
664 return div;
665
666}
667
668/**
669 * gpmc_calc_divider - calculate GPMC_FCLK divider for sync_clk GPMC_CLK period.
670 * @sync_clk: GPMC_CLK period in ps.
671 * @return: Returns at least 1 if GPMC_FCLK can be divided to GPMC_CLK.
672 * Else, returns -1.
673 */
502int gpmc_calc_divider(unsigned int sync_clk) 674int gpmc_calc_divider(unsigned int sync_clk)
503{ 675{
504 int div; 676 int div = gpmc_ps_to_ticks(sync_clk);
505 u32 l;
506 677
507 l = sync_clk + (gpmc_get_fclk_period() - 1);
508 div = l / gpmc_get_fclk_period();
509 if (div > 4) 678 if (div > 4)
510 return -1; 679 return -1;
511 if (div <= 0) 680 if (div <= 0)
@@ -514,7 +683,15 @@ int gpmc_calc_divider(unsigned int sync_clk)
514 return div; 683 return div;
515} 684}
516 685
517int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) 686/**
687 * gpmc_cs_set_timings - program timing parameters for Chip Select Region.
688 * @cs: Chip Select Region.
689 * @t: GPMC timing parameters.
690 * @s: GPMC timing settings.
691 * @return: 0 on success, -1 on error.
692 */
693int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t,
694 const struct gpmc_settings *s)
518{ 695{
519 int div; 696 int div;
520 u32 l; 697 u32 l;
@@ -524,6 +701,33 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
524 if (div < 0) 701 if (div < 0)
525 return div; 702 return div;
526 703
704 /*
705 * See if we need to change the divider for waitmonitoringtime.
706 *
707 * Calculate GPMCFCLKDIVIDER independent of gpmc,sync-clk-ps in DT for
708 * pure asynchronous accesses, i.e. both read and write asynchronous.
709 * However, only do so if WAITMONITORINGTIME is actually used, i.e.
710 * either WAITREADMONITORING or WAITWRITEMONITORING is set.
711 *
712 * This statement must not change div to scale async WAITMONITORINGTIME
713 * to protect mixed synchronous and asynchronous accesses.
714 *
715 * We raise an error later if WAITMONITORINGTIME does not fit.
716 */
717 if (!s->sync_read && !s->sync_write &&
718 (s->wait_on_read || s->wait_on_write)
719 ) {
720
721 div = gpmc_calc_waitmonitoring_divider(t->wait_monitoring);
722 if (div < 0) {
723 pr_err("%s: waitmonitoringtime %3d ns too large for greatest gpmcfclkdivider.\n",
724 __func__,
725 t->wait_monitoring
726 );
727 return -1;
728 }
729 }
730
527 GPMC_SET_ONE(GPMC_CS_CONFIG2, 0, 3, cs_on); 731 GPMC_SET_ONE(GPMC_CS_CONFIG2, 0, 3, cs_on);
528 GPMC_SET_ONE(GPMC_CS_CONFIG2, 8, 12, cs_rd_off); 732 GPMC_SET_ONE(GPMC_CS_CONFIG2, 8, 12, cs_rd_off);
529 GPMC_SET_ONE(GPMC_CS_CONFIG2, 16, 20, cs_wr_off); 733 GPMC_SET_ONE(GPMC_CS_CONFIG2, 16, 20, cs_wr_off);
@@ -546,27 +750,27 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
546 GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround); 750 GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround);
547 GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay); 751 GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay);
548 752
549 GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
550 GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
551
552 if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) 753 if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
553 GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus); 754 GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
554 if (gpmc_capability & GPMC_HAS_WR_ACCESS) 755 if (gpmc_capability & GPMC_HAS_WR_ACCESS)
555 GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access); 756 GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
556 757
557 /* caller is expected to have initialized CONFIG1 to cover
558 * at least sync vs async
559 */
560 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); 758 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
561 if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) { 759 l &= ~0x03;
760 l |= (div - 1);
761 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
762
763 GPMC_SET_ONE_CD_MAX(GPMC_CS_CONFIG1, 18, 19,
764 GPMC_CONFIG1_WAITMONITORINGTIME_MAX,
765 wait_monitoring, GPMC_CD_CLK);
766 GPMC_SET_ONE_CD_MAX(GPMC_CS_CONFIG1, 25, 26,
767 GPMC_CONFIG1_CLKACTIVATIONTIME_MAX,
768 clk_activation, GPMC_CD_FCLK);
769
562#ifdef DEBUG 770#ifdef DEBUG
563 printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n", 771 pr_info("GPMC CS%d CLK period is %lu ns (div %d)\n",
564 cs, (div * gpmc_get_fclk_period()) / 1000, div); 772 cs, (div * gpmc_get_fclk_period()) / 1000, div);
565#endif 773#endif
566 l &= ~0x03;
567 l |= (div - 1);
568 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
569 }
570 774
571 gpmc_cs_bool_timings(cs, &t->bool_timings); 775 gpmc_cs_bool_timings(cs, &t->bool_timings);
572 gpmc_cs_show_timings(cs, "after gpmc_cs_set_timings"); 776 gpmc_cs_show_timings(cs, "after gpmc_cs_set_timings");
@@ -586,12 +790,15 @@ static int gpmc_cs_set_memconf(int cs, u32 base, u32 size)
586 if (base & (size - 1)) 790 if (base & (size - 1))
587 return -EINVAL; 791 return -EINVAL;
588 792
793 base >>= GPMC_CHUNK_SHIFT;
589 mask = (1 << GPMC_SECTION_SHIFT) - size; 794 mask = (1 << GPMC_SECTION_SHIFT) - size;
795 mask >>= GPMC_CHUNK_SHIFT;
796 mask <<= GPMC_CONFIG7_MASKADDRESS_OFFSET;
797
590 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); 798 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
591 l &= ~0x3f; 799 l &= ~GPMC_CONFIG7_MASK;
592 l = (base >> GPMC_CHUNK_SHIFT) & 0x3f; 800 l |= base & GPMC_CONFIG7_BASEADDRESS_MASK;
593 l &= ~(0x0f << 8); 801 l |= mask & GPMC_CONFIG7_MASKADDRESS_MASK;
594 l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8;
595 l |= GPMC_CONFIG7_CSVALID; 802 l |= GPMC_CONFIG7_CSVALID;
596 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); 803 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
597 804
@@ -656,7 +863,7 @@ static void gpmc_cs_set_name(int cs, const char *name)
656 gpmc->name = name; 863 gpmc->name = name;
657} 864}
658 865
659const char *gpmc_cs_get_name(int cs) 866static const char *gpmc_cs_get_name(int cs)
660{ 867{
661 struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; 868 struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
662 869
@@ -1786,7 +1993,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
1786 if (ret < 0) 1993 if (ret < 0)
1787 goto err; 1994 goto err;
1788 1995
1789 ret = gpmc_cs_set_timings(cs, &gpmc_t); 1996 ret = gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s);
1790 if (ret) { 1997 if (ret) {
1791 dev_err(&pdev->dev, "failed to set gpmc timings for: %s\n", 1998 dev_err(&pdev->dev, "failed to set gpmc timings for: %s\n",
1792 child->name); 1999 child->name);
@@ -1802,8 +2009,21 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
1802 gpmc_cs_enable_mem(cs); 2009 gpmc_cs_enable_mem(cs);
1803 2010
1804no_timings: 2011no_timings:
1805 if (of_platform_device_create(child, NULL, &pdev->dev)) 2012
1806 return 0; 2013 /* create platform device, NULL on error or when disabled */
2014 if (!of_platform_device_create(child, NULL, &pdev->dev))
2015 goto err_child_fail;
2016
2017 /* is child a common bus? */
2018 if (of_match_node(of_default_bus_match_table, child))
2019 /* create children and other common bus children */
2020 if (of_platform_populate(child, of_default_bus_match_table,
2021 NULL, &pdev->dev))
2022 goto err_child_fail;
2023
2024 return 0;
2025
2026err_child_fail:
1807 2027
1808 dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name); 2028 dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name);
1809 ret = -ENODEV; 2029 ret = -ENODEV;
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 76d6bd4da138..d8bde82f0370 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -1,5 +1,6 @@
1menu "SOC (System On Chip) specific Drivers" 1menu "SOC (System On Chip) specific Drivers"
2 2
3source "drivers/soc/mediatek/Kconfig"
3source "drivers/soc/qcom/Kconfig" 4source "drivers/soc/qcom/Kconfig"
4source "drivers/soc/ti/Kconfig" 5source "drivers/soc/ti/Kconfig"
5source "drivers/soc/versatile/Kconfig" 6source "drivers/soc/versatile/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 063113d0bd38..70042b259744 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -2,6 +2,7 @@
2# Makefile for the Linux Kernel SOC specific device drivers. 2# Makefile for the Linux Kernel SOC specific device drivers.
3# 3#
4 4
5obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
5obj-$(CONFIG_ARCH_QCOM) += qcom/ 6obj-$(CONFIG_ARCH_QCOM) += qcom/
6obj-$(CONFIG_ARCH_TEGRA) += tegra/ 7obj-$(CONFIG_ARCH_TEGRA) += tegra/
7obj-$(CONFIG_SOC_TI) += ti/ 8obj-$(CONFIG_SOC_TI) += ti/
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
new file mode 100644
index 000000000000..bcdb22d5e215
--- /dev/null
+++ b/drivers/soc/mediatek/Kconfig
@@ -0,0 +1,11 @@
1#
2# MediaTek SoC drivers
3#
4config MTK_PMIC_WRAP
5 tristate "MediaTek PMIC Wrapper Support"
6 depends on ARCH_MEDIATEK
7 select REGMAP
8 help
9 Say yes here to add support for MediaTek PMIC Wrapper found
10 on different MediaTek SoCs. The PMIC wrapper is a proprietary
11 hardware to connect the PMIC.
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
new file mode 100644
index 000000000000..ecaf4defd7f6
--- /dev/null
+++ b/drivers/soc/mediatek/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
new file mode 100644
index 000000000000..db5be1eec54c
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
@@ -0,0 +1,975 @@
1/*
2 * Copyright (c) 2014 MediaTek Inc.
3 * Author: Flora Fu, MediaTek
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#include <linux/clk.h>
15#include <linux/interrupt.h>
16#include <linux/io.h>
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/of_device.h>
20#include <linux/platform_device.h>
21#include <linux/regmap.h>
22#include <linux/reset.h>
23
24#define PWRAP_MT8135_BRIDGE_IORD_ARB_EN 0x4
25#define PWRAP_MT8135_BRIDGE_WACS3_EN 0x10
26#define PWRAP_MT8135_BRIDGE_INIT_DONE3 0x14
27#define PWRAP_MT8135_BRIDGE_WACS4_EN 0x24
28#define PWRAP_MT8135_BRIDGE_INIT_DONE4 0x28
29#define PWRAP_MT8135_BRIDGE_INT_EN 0x38
30#define PWRAP_MT8135_BRIDGE_TIMER_EN 0x48
31#define PWRAP_MT8135_BRIDGE_WDT_UNIT 0x50
32#define PWRAP_MT8135_BRIDGE_WDT_SRC_EN 0x54
33
34/* macro for wrapper status */
35#define PWRAP_GET_WACS_RDATA(x) (((x) >> 0) & 0x0000ffff)
36#define PWRAP_GET_WACS_FSM(x) (((x) >> 16) & 0x00000007)
37#define PWRAP_GET_WACS_REQ(x) (((x) >> 19) & 0x00000001)
38#define PWRAP_STATE_SYNC_IDLE0 (1 << 20)
39#define PWRAP_STATE_INIT_DONE0 (1 << 21)
40
41/* macro for WACS FSM */
42#define PWRAP_WACS_FSM_IDLE 0x00
43#define PWRAP_WACS_FSM_REQ 0x02
44#define PWRAP_WACS_FSM_WFDLE 0x04
45#define PWRAP_WACS_FSM_WFVLDCLR 0x06
46#define PWRAP_WACS_INIT_DONE 0x01
47#define PWRAP_WACS_WACS_SYNC_IDLE 0x01
48#define PWRAP_WACS_SYNC_BUSY 0x00
49
50/* macro for device wrapper default value */
51#define PWRAP_DEW_READ_TEST_VAL 0x5aa5
52#define PWRAP_DEW_WRITE_TEST_VAL 0xa55a
53
54/* macro for manual command */
55#define PWRAP_MAN_CMD_SPI_WRITE (1 << 13)
56#define PWRAP_MAN_CMD_OP_CSH (0x0 << 8)
57#define PWRAP_MAN_CMD_OP_CSL (0x1 << 8)
58#define PWRAP_MAN_CMD_OP_CK (0x2 << 8)
59#define PWRAP_MAN_CMD_OP_OUTS (0x8 << 8)
60#define PWRAP_MAN_CMD_OP_OUTD (0x9 << 8)
61#define PWRAP_MAN_CMD_OP_OUTQ (0xa << 8)
62
63/* macro for slave device wrapper registers */
64#define PWRAP_DEW_BASE 0xbc00
65#define PWRAP_DEW_EVENT_OUT_EN (PWRAP_DEW_BASE + 0x0)
66#define PWRAP_DEW_DIO_EN (PWRAP_DEW_BASE + 0x2)
67#define PWRAP_DEW_EVENT_SRC_EN (PWRAP_DEW_BASE + 0x4)
68#define PWRAP_DEW_EVENT_SRC (PWRAP_DEW_BASE + 0x6)
69#define PWRAP_DEW_EVENT_FLAG (PWRAP_DEW_BASE + 0x8)
70#define PWRAP_DEW_READ_TEST (PWRAP_DEW_BASE + 0xa)
71#define PWRAP_DEW_WRITE_TEST (PWRAP_DEW_BASE + 0xc)
72#define PWRAP_DEW_CRC_EN (PWRAP_DEW_BASE + 0xe)
73#define PWRAP_DEW_CRC_VAL (PWRAP_DEW_BASE + 0x10)
74#define PWRAP_DEW_MON_GRP_SEL (PWRAP_DEW_BASE + 0x12)
75#define PWRAP_DEW_MON_FLAG_SEL (PWRAP_DEW_BASE + 0x14)
76#define PWRAP_DEW_EVENT_TEST (PWRAP_DEW_BASE + 0x16)
77#define PWRAP_DEW_CIPHER_KEY_SEL (PWRAP_DEW_BASE + 0x18)
78#define PWRAP_DEW_CIPHER_IV_SEL (PWRAP_DEW_BASE + 0x1a)
79#define PWRAP_DEW_CIPHER_LOAD (PWRAP_DEW_BASE + 0x1c)
80#define PWRAP_DEW_CIPHER_START (PWRAP_DEW_BASE + 0x1e)
81#define PWRAP_DEW_CIPHER_RDY (PWRAP_DEW_BASE + 0x20)
82#define PWRAP_DEW_CIPHER_MODE (PWRAP_DEW_BASE + 0x22)
83#define PWRAP_DEW_CIPHER_SWRST (PWRAP_DEW_BASE + 0x24)
84#define PWRAP_MT8173_DEW_CIPHER_IV0 (PWRAP_DEW_BASE + 0x26)
85#define PWRAP_MT8173_DEW_CIPHER_IV1 (PWRAP_DEW_BASE + 0x28)
86#define PWRAP_MT8173_DEW_CIPHER_IV2 (PWRAP_DEW_BASE + 0x2a)
87#define PWRAP_MT8173_DEW_CIPHER_IV3 (PWRAP_DEW_BASE + 0x2c)
88#define PWRAP_MT8173_DEW_CIPHER_IV4 (PWRAP_DEW_BASE + 0x2e)
89#define PWRAP_MT8173_DEW_CIPHER_IV5 (PWRAP_DEW_BASE + 0x30)
90
91enum pwrap_regs {
92 PWRAP_MUX_SEL,
93 PWRAP_WRAP_EN,
94 PWRAP_DIO_EN,
95 PWRAP_SIDLY,
96 PWRAP_CSHEXT_WRITE,
97 PWRAP_CSHEXT_READ,
98 PWRAP_CSLEXT_START,
99 PWRAP_CSLEXT_END,
100 PWRAP_STAUPD_PRD,
101 PWRAP_STAUPD_GRPEN,
102 PWRAP_STAUPD_MAN_TRIG,
103 PWRAP_STAUPD_STA,
104 PWRAP_WRAP_STA,
105 PWRAP_HARB_INIT,
106 PWRAP_HARB_HPRIO,
107 PWRAP_HIPRIO_ARB_EN,
108 PWRAP_HARB_STA0,
109 PWRAP_HARB_STA1,
110 PWRAP_MAN_EN,
111 PWRAP_MAN_CMD,
112 PWRAP_MAN_RDATA,
113 PWRAP_MAN_VLDCLR,
114 PWRAP_WACS0_EN,
115 PWRAP_INIT_DONE0,
116 PWRAP_WACS0_CMD,
117 PWRAP_WACS0_RDATA,
118 PWRAP_WACS0_VLDCLR,
119 PWRAP_WACS1_EN,
120 PWRAP_INIT_DONE1,
121 PWRAP_WACS1_CMD,
122 PWRAP_WACS1_RDATA,
123 PWRAP_WACS1_VLDCLR,
124 PWRAP_WACS2_EN,
125 PWRAP_INIT_DONE2,
126 PWRAP_WACS2_CMD,
127 PWRAP_WACS2_RDATA,
128 PWRAP_WACS2_VLDCLR,
129 PWRAP_INT_EN,
130 PWRAP_INT_FLG_RAW,
131 PWRAP_INT_FLG,
132 PWRAP_INT_CLR,
133 PWRAP_SIG_ADR,
134 PWRAP_SIG_MODE,
135 PWRAP_SIG_VALUE,
136 PWRAP_SIG_ERRVAL,
137 PWRAP_CRC_EN,
138 PWRAP_TIMER_EN,
139 PWRAP_TIMER_STA,
140 PWRAP_WDT_UNIT,
141 PWRAP_WDT_SRC_EN,
142 PWRAP_WDT_FLG,
143 PWRAP_DEBUG_INT_SEL,
144 PWRAP_CIPHER_KEY_SEL,
145 PWRAP_CIPHER_IV_SEL,
146 PWRAP_CIPHER_RDY,
147 PWRAP_CIPHER_MODE,
148 PWRAP_CIPHER_SWRST,
149 PWRAP_DCM_EN,
150 PWRAP_DCM_DBC_PRD,
151
152 /* MT8135 only regs */
153 PWRAP_CSHEXT,
154 PWRAP_EVENT_IN_EN,
155 PWRAP_EVENT_DST_EN,
156 PWRAP_RRARB_INIT,
157 PWRAP_RRARB_EN,
158 PWRAP_RRARB_STA0,
159 PWRAP_RRARB_STA1,
160 PWRAP_EVENT_STA,
161 PWRAP_EVENT_STACLR,
162 PWRAP_CIPHER_LOAD,
163 PWRAP_CIPHER_START,
164
165 /* MT8173 only regs */
166 PWRAP_RDDMY,
167 PWRAP_SI_CK_CON,
168 PWRAP_DVFS_ADR0,
169 PWRAP_DVFS_WDATA0,
170 PWRAP_DVFS_ADR1,
171 PWRAP_DVFS_WDATA1,
172 PWRAP_DVFS_ADR2,
173 PWRAP_DVFS_WDATA2,
174 PWRAP_DVFS_ADR3,
175 PWRAP_DVFS_WDATA3,
176 PWRAP_DVFS_ADR4,
177 PWRAP_DVFS_WDATA4,
178 PWRAP_DVFS_ADR5,
179 PWRAP_DVFS_WDATA5,
180 PWRAP_DVFS_ADR6,
181 PWRAP_DVFS_WDATA6,
182 PWRAP_DVFS_ADR7,
183 PWRAP_DVFS_WDATA7,
184 PWRAP_SPMINF_STA,
185 PWRAP_CIPHER_EN,
186};
187
188static int mt8173_regs[] = {
189 [PWRAP_MUX_SEL] = 0x0,
190 [PWRAP_WRAP_EN] = 0x4,
191 [PWRAP_DIO_EN] = 0x8,
192 [PWRAP_SIDLY] = 0xc,
193 [PWRAP_RDDMY] = 0x10,
194 [PWRAP_SI_CK_CON] = 0x14,
195 [PWRAP_CSHEXT_WRITE] = 0x18,
196 [PWRAP_CSHEXT_READ] = 0x1c,
197 [PWRAP_CSLEXT_START] = 0x20,
198 [PWRAP_CSLEXT_END] = 0x24,
199 [PWRAP_STAUPD_PRD] = 0x28,
200 [PWRAP_STAUPD_GRPEN] = 0x2c,
201 [PWRAP_STAUPD_MAN_TRIG] = 0x40,
202 [PWRAP_STAUPD_STA] = 0x44,
203 [PWRAP_WRAP_STA] = 0x48,
204 [PWRAP_HARB_INIT] = 0x4c,
205 [PWRAP_HARB_HPRIO] = 0x50,
206 [PWRAP_HIPRIO_ARB_EN] = 0x54,
207 [PWRAP_HARB_STA0] = 0x58,
208 [PWRAP_HARB_STA1] = 0x5c,
209 [PWRAP_MAN_EN] = 0x60,
210 [PWRAP_MAN_CMD] = 0x64,
211 [PWRAP_MAN_RDATA] = 0x68,
212 [PWRAP_MAN_VLDCLR] = 0x6c,
213 [PWRAP_WACS0_EN] = 0x70,
214 [PWRAP_INIT_DONE0] = 0x74,
215 [PWRAP_WACS0_CMD] = 0x78,
216 [PWRAP_WACS0_RDATA] = 0x7c,
217 [PWRAP_WACS0_VLDCLR] = 0x80,
218 [PWRAP_WACS1_EN] = 0x84,
219 [PWRAP_INIT_DONE1] = 0x88,
220 [PWRAP_WACS1_CMD] = 0x8c,
221 [PWRAP_WACS1_RDATA] = 0x90,
222 [PWRAP_WACS1_VLDCLR] = 0x94,
223 [PWRAP_WACS2_EN] = 0x98,
224 [PWRAP_INIT_DONE2] = 0x9c,
225 [PWRAP_WACS2_CMD] = 0xa0,
226 [PWRAP_WACS2_RDATA] = 0xa4,
227 [PWRAP_WACS2_VLDCLR] = 0xa8,
228 [PWRAP_INT_EN] = 0xac,
229 [PWRAP_INT_FLG_RAW] = 0xb0,
230 [PWRAP_INT_FLG] = 0xb4,
231 [PWRAP_INT_CLR] = 0xb8,
232 [PWRAP_SIG_ADR] = 0xbc,
233 [PWRAP_SIG_MODE] = 0xc0,
234 [PWRAP_SIG_VALUE] = 0xc4,
235 [PWRAP_SIG_ERRVAL] = 0xc8,
236 [PWRAP_CRC_EN] = 0xcc,
237 [PWRAP_TIMER_EN] = 0xd0,
238 [PWRAP_TIMER_STA] = 0xd4,
239 [PWRAP_WDT_UNIT] = 0xd8,
240 [PWRAP_WDT_SRC_EN] = 0xdc,
241 [PWRAP_WDT_FLG] = 0xe0,
242 [PWRAP_DEBUG_INT_SEL] = 0xe4,
243 [PWRAP_DVFS_ADR0] = 0xe8,
244 [PWRAP_DVFS_WDATA0] = 0xec,
245 [PWRAP_DVFS_ADR1] = 0xf0,
246 [PWRAP_DVFS_WDATA1] = 0xf4,
247 [PWRAP_DVFS_ADR2] = 0xf8,
248 [PWRAP_DVFS_WDATA2] = 0xfc,
249 [PWRAP_DVFS_ADR3] = 0x100,
250 [PWRAP_DVFS_WDATA3] = 0x104,
251 [PWRAP_DVFS_ADR4] = 0x108,
252 [PWRAP_DVFS_WDATA4] = 0x10c,
253 [PWRAP_DVFS_ADR5] = 0x110,
254 [PWRAP_DVFS_WDATA5] = 0x114,
255 [PWRAP_DVFS_ADR6] = 0x118,
256 [PWRAP_DVFS_WDATA6] = 0x11c,
257 [PWRAP_DVFS_ADR7] = 0x120,
258 [PWRAP_DVFS_WDATA7] = 0x124,
259 [PWRAP_SPMINF_STA] = 0x128,
260 [PWRAP_CIPHER_KEY_SEL] = 0x12c,
261 [PWRAP_CIPHER_IV_SEL] = 0x130,
262 [PWRAP_CIPHER_EN] = 0x134,
263 [PWRAP_CIPHER_RDY] = 0x138,
264 [PWRAP_CIPHER_MODE] = 0x13c,
265 [PWRAP_CIPHER_SWRST] = 0x140,
266 [PWRAP_DCM_EN] = 0x144,
267 [PWRAP_DCM_DBC_PRD] = 0x148,
268};
269
270static int mt8135_regs[] = {
271 [PWRAP_MUX_SEL] = 0x0,
272 [PWRAP_WRAP_EN] = 0x4,
273 [PWRAP_DIO_EN] = 0x8,
274 [PWRAP_SIDLY] = 0xc,
275 [PWRAP_CSHEXT] = 0x10,
276 [PWRAP_CSHEXT_WRITE] = 0x14,
277 [PWRAP_CSHEXT_READ] = 0x18,
278 [PWRAP_CSLEXT_START] = 0x1c,
279 [PWRAP_CSLEXT_END] = 0x20,
280 [PWRAP_STAUPD_PRD] = 0x24,
281 [PWRAP_STAUPD_GRPEN] = 0x28,
282 [PWRAP_STAUPD_MAN_TRIG] = 0x2c,
283 [PWRAP_STAUPD_STA] = 0x30,
284 [PWRAP_EVENT_IN_EN] = 0x34,
285 [PWRAP_EVENT_DST_EN] = 0x38,
286 [PWRAP_WRAP_STA] = 0x3c,
287 [PWRAP_RRARB_INIT] = 0x40,
288 [PWRAP_RRARB_EN] = 0x44,
289 [PWRAP_RRARB_STA0] = 0x48,
290 [PWRAP_RRARB_STA1] = 0x4c,
291 [PWRAP_HARB_INIT] = 0x50,
292 [PWRAP_HARB_HPRIO] = 0x54,
293 [PWRAP_HIPRIO_ARB_EN] = 0x58,
294 [PWRAP_HARB_STA0] = 0x5c,
295 [PWRAP_HARB_STA1] = 0x60,
296 [PWRAP_MAN_EN] = 0x64,
297 [PWRAP_MAN_CMD] = 0x68,
298 [PWRAP_MAN_RDATA] = 0x6c,
299 [PWRAP_MAN_VLDCLR] = 0x70,
300 [PWRAP_WACS0_EN] = 0x74,
301 [PWRAP_INIT_DONE0] = 0x78,
302 [PWRAP_WACS0_CMD] = 0x7c,
303 [PWRAP_WACS0_RDATA] = 0x80,
304 [PWRAP_WACS0_VLDCLR] = 0x84,
305 [PWRAP_WACS1_EN] = 0x88,
306 [PWRAP_INIT_DONE1] = 0x8c,
307 [PWRAP_WACS1_CMD] = 0x90,
308 [PWRAP_WACS1_RDATA] = 0x94,
309 [PWRAP_WACS1_VLDCLR] = 0x98,
310 [PWRAP_WACS2_EN] = 0x9c,
311 [PWRAP_INIT_DONE2] = 0xa0,
312 [PWRAP_WACS2_CMD] = 0xa4,
313 [PWRAP_WACS2_RDATA] = 0xa8,
314 [PWRAP_WACS2_VLDCLR] = 0xac,
315 [PWRAP_INT_EN] = 0xb0,
316 [PWRAP_INT_FLG_RAW] = 0xb4,
317 [PWRAP_INT_FLG] = 0xb8,
318 [PWRAP_INT_CLR] = 0xbc,
319 [PWRAP_SIG_ADR] = 0xc0,
320 [PWRAP_SIG_MODE] = 0xc4,
321 [PWRAP_SIG_VALUE] = 0xc8,
322 [PWRAP_SIG_ERRVAL] = 0xcc,
323 [PWRAP_CRC_EN] = 0xd0,
324 [PWRAP_EVENT_STA] = 0xd4,
325 [PWRAP_EVENT_STACLR] = 0xd8,
326 [PWRAP_TIMER_EN] = 0xdc,
327 [PWRAP_TIMER_STA] = 0xe0,
328 [PWRAP_WDT_UNIT] = 0xe4,
329 [PWRAP_WDT_SRC_EN] = 0xe8,
330 [PWRAP_WDT_FLG] = 0xec,
331 [PWRAP_DEBUG_INT_SEL] = 0xf0,
332 [PWRAP_CIPHER_KEY_SEL] = 0x134,
333 [PWRAP_CIPHER_IV_SEL] = 0x138,
334 [PWRAP_CIPHER_LOAD] = 0x13c,
335 [PWRAP_CIPHER_START] = 0x140,
336 [PWRAP_CIPHER_RDY] = 0x144,
337 [PWRAP_CIPHER_MODE] = 0x148,
338 [PWRAP_CIPHER_SWRST] = 0x14c,
339 [PWRAP_DCM_EN] = 0x15c,
340 [PWRAP_DCM_DBC_PRD] = 0x160,
341};
342
343enum pwrap_type {
344 PWRAP_MT8135,
345 PWRAP_MT8173,
346};
347
348struct pmic_wrapper_type {
349 int *regs;
350 enum pwrap_type type;
351 u32 arb_en_all;
352};
353
354static struct pmic_wrapper_type pwrap_mt8135 = {
355 .regs = mt8135_regs,
356 .type = PWRAP_MT8135,
357 .arb_en_all = 0x1ff,
358};
359
360static struct pmic_wrapper_type pwrap_mt8173 = {
361 .regs = mt8173_regs,
362 .type = PWRAP_MT8173,
363 .arb_en_all = 0x3f,
364};
365
366struct pmic_wrapper {
367 struct device *dev;
368 void __iomem *base;
369 struct regmap *regmap;
370 int *regs;
371 enum pwrap_type type;
372 u32 arb_en_all;
373 struct clk *clk_spi;
374 struct clk *clk_wrap;
375 struct reset_control *rstc;
376
377 struct reset_control *rstc_bridge;
378 void __iomem *bridge_base;
379};
380
381static inline int pwrap_is_mt8135(struct pmic_wrapper *wrp)
382{
383 return wrp->type == PWRAP_MT8135;
384}
385
386static inline int pwrap_is_mt8173(struct pmic_wrapper *wrp)
387{
388 return wrp->type == PWRAP_MT8173;
389}
390
391static u32 pwrap_readl(struct pmic_wrapper *wrp, enum pwrap_regs reg)
392{
393 return readl(wrp->base + wrp->regs[reg]);
394}
395
396static void pwrap_writel(struct pmic_wrapper *wrp, u32 val, enum pwrap_regs reg)
397{
398 writel(val, wrp->base + wrp->regs[reg]);
399}
400
401static bool pwrap_is_fsm_idle(struct pmic_wrapper *wrp)
402{
403 u32 val = pwrap_readl(wrp, PWRAP_WACS2_RDATA);
404
405 return PWRAP_GET_WACS_FSM(val) == PWRAP_WACS_FSM_IDLE;
406}
407
408static bool pwrap_is_fsm_vldclr(struct pmic_wrapper *wrp)
409{
410 u32 val = pwrap_readl(wrp, PWRAP_WACS2_RDATA);
411
412 return PWRAP_GET_WACS_FSM(val) == PWRAP_WACS_FSM_WFVLDCLR;
413}
414
415static bool pwrap_is_sync_idle(struct pmic_wrapper *wrp)
416{
417 return pwrap_readl(wrp, PWRAP_WACS2_RDATA) & PWRAP_STATE_SYNC_IDLE0;
418}
419
420static bool pwrap_is_fsm_idle_and_sync_idle(struct pmic_wrapper *wrp)
421{
422 u32 val = pwrap_readl(wrp, PWRAP_WACS2_RDATA);
423
424 return (PWRAP_GET_WACS_FSM(val) == PWRAP_WACS_FSM_IDLE) &&
425 (val & PWRAP_STATE_SYNC_IDLE0);
426}
427
428static int pwrap_wait_for_state(struct pmic_wrapper *wrp,
429 bool (*fp)(struct pmic_wrapper *))
430{
431 unsigned long timeout;
432
433 timeout = jiffies + usecs_to_jiffies(255);
434
435 do {
436 if (time_after(jiffies, timeout))
437 return fp(wrp) ? 0 : -ETIMEDOUT;
438 if (fp(wrp))
439 return 0;
440 } while (1);
441}
442
443static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata)
444{
445 int ret;
446 u32 val;
447
448 val = pwrap_readl(wrp, PWRAP_WACS2_RDATA);
449 if (PWRAP_GET_WACS_FSM(val) == PWRAP_WACS_FSM_WFVLDCLR)
450 pwrap_writel(wrp, 1, PWRAP_WACS2_VLDCLR);
451
452 ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle);
453 if (ret)
454 return ret;
455
456 pwrap_writel(wrp, (1 << 31) | ((adr >> 1) << 16) | wdata,
457 PWRAP_WACS2_CMD);
458
459 return 0;
460}
461
462static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
463{
464 int ret;
465 u32 val;
466
467 val = pwrap_readl(wrp, PWRAP_WACS2_RDATA);
468 if (PWRAP_GET_WACS_FSM(val) == PWRAP_WACS_FSM_WFVLDCLR)
469 pwrap_writel(wrp, 1, PWRAP_WACS2_VLDCLR);
470
471 ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle);
472 if (ret)
473 return ret;
474
475 pwrap_writel(wrp, (adr >> 1) << 16, PWRAP_WACS2_CMD);
476
477 ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_vldclr);
478 if (ret)
479 return ret;
480
481 *rdata = PWRAP_GET_WACS_RDATA(pwrap_readl(wrp, PWRAP_WACS2_RDATA));
482
483 return 0;
484}
485
486static int pwrap_regmap_read(void *context, u32 adr, u32 *rdata)
487{
488 return pwrap_read(context, adr, rdata);
489}
490
491static int pwrap_regmap_write(void *context, u32 adr, u32 wdata)
492{
493 return pwrap_write(context, adr, wdata);
494}
495
496static int pwrap_reset_spislave(struct pmic_wrapper *wrp)
497{
498 int ret, i;
499
500 pwrap_writel(wrp, 0, PWRAP_HIPRIO_ARB_EN);
501 pwrap_writel(wrp, 0, PWRAP_WRAP_EN);
502 pwrap_writel(wrp, 1, PWRAP_MUX_SEL);
503 pwrap_writel(wrp, 1, PWRAP_MAN_EN);
504 pwrap_writel(wrp, 0, PWRAP_DIO_EN);
505
506 pwrap_writel(wrp, PWRAP_MAN_CMD_SPI_WRITE | PWRAP_MAN_CMD_OP_CSL,
507 PWRAP_MAN_CMD);
508 pwrap_writel(wrp, PWRAP_MAN_CMD_SPI_WRITE | PWRAP_MAN_CMD_OP_OUTS,
509 PWRAP_MAN_CMD);
510 pwrap_writel(wrp, PWRAP_MAN_CMD_SPI_WRITE | PWRAP_MAN_CMD_OP_CSH,
511 PWRAP_MAN_CMD);
512
513 for (i = 0; i < 4; i++)
514 pwrap_writel(wrp, PWRAP_MAN_CMD_SPI_WRITE | PWRAP_MAN_CMD_OP_OUTS,
515 PWRAP_MAN_CMD);
516
517 ret = pwrap_wait_for_state(wrp, pwrap_is_sync_idle);
518 if (ret) {
519 dev_err(wrp->dev, "%s fail, ret=%d\n", __func__, ret);
520 return ret;
521 }
522
523 pwrap_writel(wrp, 0, PWRAP_MAN_EN);
524 pwrap_writel(wrp, 0, PWRAP_MUX_SEL);
525
526 return 0;
527}
528
529/*
530 * pwrap_init_sidly - configure serial input delay
531 *
532 * This configures the serial input delay. We can configure 0, 2, 4 or 6ns
533 * delay. Do a read test with all possible values and chose the best delay.
534 */
535static int pwrap_init_sidly(struct pmic_wrapper *wrp)
536{
537 u32 rdata;
538 u32 i;
539 u32 pass = 0;
540 signed char dly[16] = {
541 -1, 0, 1, 0, 2, -1, 1, 1, 3, -1, -1, -1, 3, -1, 2, 1
542 };
543
544 for (i = 0; i < 4; i++) {
545 pwrap_writel(wrp, i, PWRAP_SIDLY);
546 pwrap_read(wrp, PWRAP_DEW_READ_TEST, &rdata);
547 if (rdata == PWRAP_DEW_READ_TEST_VAL) {
548 dev_dbg(wrp->dev, "[Read Test] pass, SIDLY=%x\n", i);
549 pass |= 1 << i;
550 }
551 }
552
553 if (dly[pass] < 0) {
554 dev_err(wrp->dev, "sidly pass range 0x%x not continuous\n",
555 pass);
556 return -EIO;
557 }
558
559 pwrap_writel(wrp, dly[pass], PWRAP_SIDLY);
560
561 return 0;
562}
563
564static int pwrap_init_reg_clock(struct pmic_wrapper *wrp)
565{
566 unsigned long rate_spi;
567 int ck_mhz;
568
569 rate_spi = clk_get_rate(wrp->clk_spi);
570
571 if (rate_spi > 26000000)
572 ck_mhz = 26;
573 else if (rate_spi > 18000000)
574 ck_mhz = 18;
575 else
576 ck_mhz = 0;
577
578 switch (ck_mhz) {
579 case 18:
580 if (pwrap_is_mt8135(wrp))
581 pwrap_writel(wrp, 0xc, PWRAP_CSHEXT);
582 pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_WRITE);
583 pwrap_writel(wrp, 0xc, PWRAP_CSHEXT_READ);
584 pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_START);
585 pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_END);
586 break;
587 case 26:
588 if (pwrap_is_mt8135(wrp))
589 pwrap_writel(wrp, 0x4, PWRAP_CSHEXT);
590 pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
591 pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
592 pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_START);
593 pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_END);
594 break;
595 case 0:
596 if (pwrap_is_mt8135(wrp))
597 pwrap_writel(wrp, 0xf, PWRAP_CSHEXT);
598 pwrap_writel(wrp, 0xf, PWRAP_CSHEXT_WRITE);
599 pwrap_writel(wrp, 0xf, PWRAP_CSHEXT_READ);
600 pwrap_writel(wrp, 0xf, PWRAP_CSLEXT_START);
601 pwrap_writel(wrp, 0xf, PWRAP_CSLEXT_END);
602 break;
603 default:
604 return -EINVAL;
605 }
606
607 return 0;
608}
609
610static bool pwrap_is_cipher_ready(struct pmic_wrapper *wrp)
611{
612 return pwrap_readl(wrp, PWRAP_CIPHER_RDY) & 1;
613}
614
615static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp)
616{
617 u32 rdata;
618 int ret;
619
620 ret = pwrap_read(wrp, PWRAP_DEW_CIPHER_RDY, &rdata);
621 if (ret)
622 return 0;
623
624 return rdata == 1;
625}
626
627static int pwrap_init_cipher(struct pmic_wrapper *wrp)
628{
629 int ret;
630 u32 rdata;
631
632 pwrap_writel(wrp, 0x1, PWRAP_CIPHER_SWRST);
633 pwrap_writel(wrp, 0x0, PWRAP_CIPHER_SWRST);
634 pwrap_writel(wrp, 0x1, PWRAP_CIPHER_KEY_SEL);
635 pwrap_writel(wrp, 0x2, PWRAP_CIPHER_IV_SEL);
636
637 if (pwrap_is_mt8135(wrp)) {
638 pwrap_writel(wrp, 1, PWRAP_CIPHER_LOAD);
639 pwrap_writel(wrp, 1, PWRAP_CIPHER_START);
640 } else {
641 pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
642 }
643
644 /* Config cipher mode @PMIC */
645 pwrap_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x1);
646 pwrap_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x0);
647 pwrap_write(wrp, PWRAP_DEW_CIPHER_KEY_SEL, 0x1);
648 pwrap_write(wrp, PWRAP_DEW_CIPHER_IV_SEL, 0x2);
649 pwrap_write(wrp, PWRAP_DEW_CIPHER_LOAD, 0x1);
650 pwrap_write(wrp, PWRAP_DEW_CIPHER_START, 0x1);
651
652 /* wait for cipher data ready@AP */
653 ret = pwrap_wait_for_state(wrp, pwrap_is_cipher_ready);
654 if (ret) {
655 dev_err(wrp->dev, "cipher data ready@AP fail, ret=%d\n", ret);
656 return ret;
657 }
658
659 /* wait for cipher data ready@PMIC */
660 ret = pwrap_wait_for_state(wrp, pwrap_is_pmic_cipher_ready);
661 if (ret) {
662 dev_err(wrp->dev, "timeout waiting for cipher data ready@PMIC\n");
663 return ret;
664 }
665
666 /* wait for cipher mode idle */
667 pwrap_write(wrp, PWRAP_DEW_CIPHER_MODE, 0x1);
668 ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
669 if (ret) {
670 dev_err(wrp->dev, "cipher mode idle fail, ret=%d\n", ret);
671 return ret;
672 }
673
674 pwrap_writel(wrp, 1, PWRAP_CIPHER_MODE);
675
676 /* Write Test */
677 if (pwrap_write(wrp, PWRAP_DEW_WRITE_TEST, PWRAP_DEW_WRITE_TEST_VAL) ||
678 pwrap_read(wrp, PWRAP_DEW_WRITE_TEST, &rdata) ||
679 (rdata != PWRAP_DEW_WRITE_TEST_VAL)) {
680 dev_err(wrp->dev, "rdata=0x%04X\n", rdata);
681 return -EFAULT;
682 }
683
684 return 0;
685}
686
687static int pwrap_init(struct pmic_wrapper *wrp)
688{
689 int ret;
690 u32 rdata;
691
692 reset_control_reset(wrp->rstc);
693 if (wrp->rstc_bridge)
694 reset_control_reset(wrp->rstc_bridge);
695
696 if (pwrap_is_mt8173(wrp)) {
697 /* Enable DCM */
698 pwrap_writel(wrp, 3, PWRAP_DCM_EN);
699 pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD);
700 }
701
702 /* Reset SPI slave */
703 ret = pwrap_reset_spislave(wrp);
704 if (ret)
705 return ret;
706
707 pwrap_writel(wrp, 1, PWRAP_WRAP_EN);
708
709 pwrap_writel(wrp, wrp->arb_en_all, PWRAP_HIPRIO_ARB_EN);
710
711 pwrap_writel(wrp, 1, PWRAP_WACS2_EN);
712
713 ret = pwrap_init_reg_clock(wrp);
714 if (ret)
715 return ret;
716
717 /* Setup serial input delay */
718 ret = pwrap_init_sidly(wrp);
719 if (ret)
720 return ret;
721
722 /* Enable dual IO mode */
723 pwrap_write(wrp, PWRAP_DEW_DIO_EN, 1);
724
725 /* Check IDLE & INIT_DONE in advance */
726 ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
727 if (ret) {
728 dev_err(wrp->dev, "%s fail, ret=%d\n", __func__, ret);
729 return ret;
730 }
731
732 pwrap_writel(wrp, 1, PWRAP_DIO_EN);
733
734 /* Read Test */
735 pwrap_read(wrp, PWRAP_DEW_READ_TEST, &rdata);
736 if (rdata != PWRAP_DEW_READ_TEST_VAL) {
737 dev_err(wrp->dev, "Read test failed after switch to DIO mode: 0x%04x != 0x%04x\n",
738 PWRAP_DEW_READ_TEST_VAL, rdata);
739 return -EFAULT;
740 }
741
742 /* Enable encryption */
743 ret = pwrap_init_cipher(wrp);
744 if (ret)
745 return ret;
746
747 /* Signature checking - using CRC */
748 if (pwrap_write(wrp, PWRAP_DEW_CRC_EN, 0x1))
749 return -EFAULT;
750
751 pwrap_writel(wrp, 0x1, PWRAP_CRC_EN);
752 pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE);
753 pwrap_writel(wrp, PWRAP_DEW_CRC_VAL, PWRAP_SIG_ADR);
754 pwrap_writel(wrp, wrp->arb_en_all, PWRAP_HIPRIO_ARB_EN);
755
756 if (pwrap_is_mt8135(wrp))
757 pwrap_writel(wrp, 0x7, PWRAP_RRARB_EN);
758
759 pwrap_writel(wrp, 0x1, PWRAP_WACS0_EN);
760 pwrap_writel(wrp, 0x1, PWRAP_WACS1_EN);
761 pwrap_writel(wrp, 0x1, PWRAP_WACS2_EN);
762 pwrap_writel(wrp, 0x5, PWRAP_STAUPD_PRD);
763 pwrap_writel(wrp, 0xff, PWRAP_STAUPD_GRPEN);
764 pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT);
765 pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN);
766 pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
767 pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
768
769 if (pwrap_is_mt8135(wrp)) {
770 /* enable pwrap events and pwrap bridge in AP side */
771 pwrap_writel(wrp, 0x1, PWRAP_EVENT_IN_EN);
772 pwrap_writel(wrp, 0xffff, PWRAP_EVENT_DST_EN);
773 writel(0x7f, wrp->bridge_base + PWRAP_MT8135_BRIDGE_IORD_ARB_EN);
774 writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WACS3_EN);
775 writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WACS4_EN);
776 writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WDT_UNIT);
777 writel(0xffff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WDT_SRC_EN);
778 writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_TIMER_EN);
779 writel(0x7ff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INT_EN);
780
781 /* enable PMIC event out and sources */
782 if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
783 pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
784 dev_err(wrp->dev, "enable dewrap fail\n");
785 return -EFAULT;
786 }
787 } else {
788 /* PMIC_DEWRAP enables */
789 if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
790 pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
791 dev_err(wrp->dev, "enable dewrap fail\n");
792 return -EFAULT;
793 }
794 }
795
796 /* Setup the init done registers */
797 pwrap_writel(wrp, 1, PWRAP_INIT_DONE2);
798 pwrap_writel(wrp, 1, PWRAP_INIT_DONE0);
799 pwrap_writel(wrp, 1, PWRAP_INIT_DONE1);
800
801 if (pwrap_is_mt8135(wrp)) {
802 writel(1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INIT_DONE3);
803 writel(1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INIT_DONE4);
804 }
805
806 return 0;
807}
808
809static irqreturn_t pwrap_interrupt(int irqno, void *dev_id)
810{
811 u32 rdata;
812 struct pmic_wrapper *wrp = dev_id;
813
814 rdata = pwrap_readl(wrp, PWRAP_INT_FLG);
815
816 dev_err(wrp->dev, "unexpected interrupt int=0x%x\n", rdata);
817
818 pwrap_writel(wrp, 0xffffffff, PWRAP_INT_CLR);
819
820 return IRQ_HANDLED;
821}
822
823static const struct regmap_config pwrap_regmap_config = {
824 .reg_bits = 16,
825 .val_bits = 16,
826 .reg_stride = 2,
827 .reg_read = pwrap_regmap_read,
828 .reg_write = pwrap_regmap_write,
829 .max_register = 0xffff,
830};
831
832static struct of_device_id of_pwrap_match_tbl[] = {
833 {
834 .compatible = "mediatek,mt8135-pwrap",
835 .data = &pwrap_mt8135,
836 }, {
837 .compatible = "mediatek,mt8173-pwrap",
838 .data = &pwrap_mt8173,
839 }, {
840 /* sentinel */
841 }
842};
843MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl);
844
845static int pwrap_probe(struct platform_device *pdev)
846{
847 int ret, irq;
848 struct pmic_wrapper *wrp;
849 struct device_node *np = pdev->dev.of_node;
850 const struct of_device_id *of_id =
851 of_match_device(of_pwrap_match_tbl, &pdev->dev);
852 const struct pmic_wrapper_type *type;
853 struct resource *res;
854
855 wrp = devm_kzalloc(&pdev->dev, sizeof(*wrp), GFP_KERNEL);
856 if (!wrp)
857 return -ENOMEM;
858
859 platform_set_drvdata(pdev, wrp);
860
861 type = of_id->data;
862 wrp->regs = type->regs;
863 wrp->type = type->type;
864 wrp->arb_en_all = type->arb_en_all;
865 wrp->dev = &pdev->dev;
866
867 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwrap");
868 wrp->base = devm_ioremap_resource(wrp->dev, res);
869 if (IS_ERR(wrp->base))
870 return PTR_ERR(wrp->base);
871
872 wrp->rstc = devm_reset_control_get(wrp->dev, "pwrap");
873 if (IS_ERR(wrp->rstc)) {
874 ret = PTR_ERR(wrp->rstc);
875 dev_dbg(wrp->dev, "cannot get pwrap reset: %d\n", ret);
876 return ret;
877 }
878
879 if (pwrap_is_mt8135(wrp)) {
880 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
881 "pwrap-bridge");
882 wrp->bridge_base = devm_ioremap_resource(wrp->dev, res);
883 if (IS_ERR(wrp->bridge_base))
884 return PTR_ERR(wrp->bridge_base);
885
886 wrp->rstc_bridge = devm_reset_control_get(wrp->dev, "pwrap-bridge");
887 if (IS_ERR(wrp->rstc_bridge)) {
888 ret = PTR_ERR(wrp->rstc_bridge);
889 dev_dbg(wrp->dev, "cannot get pwrap-bridge reset: %d\n", ret);
890 return ret;
891 }
892 }
893
894 wrp->clk_spi = devm_clk_get(wrp->dev, "spi");
895 if (IS_ERR(wrp->clk_spi)) {
896 dev_dbg(wrp->dev, "failed to get clock: %ld\n", PTR_ERR(wrp->clk_spi));
897 return PTR_ERR(wrp->clk_spi);
898 }
899
900 wrp->clk_wrap = devm_clk_get(wrp->dev, "wrap");
901 if (IS_ERR(wrp->clk_wrap)) {
902 dev_dbg(wrp->dev, "failed to get clock: %ld\n", PTR_ERR(wrp->clk_wrap));
903 return PTR_ERR(wrp->clk_wrap);
904 }
905
906 ret = clk_prepare_enable(wrp->clk_spi);
907 if (ret)
908 return ret;
909
910 ret = clk_prepare_enable(wrp->clk_wrap);
911 if (ret)
912 goto err_out1;
913
914 /* Enable internal dynamic clock */
915 pwrap_writel(wrp, 1, PWRAP_DCM_EN);
916 pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD);
917
918 /*
919 * The PMIC could already be initialized by the bootloader.
920 * Skip initialization here in this case.
921 */
922 if (!pwrap_readl(wrp, PWRAP_INIT_DONE2)) {
923 ret = pwrap_init(wrp);
924 if (ret) {
925 dev_dbg(wrp->dev, "init failed with %d\n", ret);
926 goto err_out2;
927 }
928 }
929
930 if (!(pwrap_readl(wrp, PWRAP_WACS2_RDATA) & PWRAP_STATE_INIT_DONE0)) {
931 dev_dbg(wrp->dev, "initialization isn't finished\n");
932 return -ENODEV;
933 }
934
935 irq = platform_get_irq(pdev, 0);
936 ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt, IRQF_TRIGGER_HIGH,
937 "mt-pmic-pwrap", wrp);
938 if (ret)
939 goto err_out2;
940
941 wrp->regmap = devm_regmap_init(wrp->dev, NULL, wrp, &pwrap_regmap_config);
942 if (IS_ERR(wrp->regmap))
943 return PTR_ERR(wrp->regmap);
944
945 ret = of_platform_populate(np, NULL, NULL, wrp->dev);
946 if (ret) {
947 dev_dbg(wrp->dev, "failed to create child devices at %s\n",
948 np->full_name);
949 goto err_out2;
950 }
951
952 return 0;
953
954err_out2:
955 clk_disable_unprepare(wrp->clk_wrap);
956err_out1:
957 clk_disable_unprepare(wrp->clk_spi);
958
959 return ret;
960}
961
962static struct platform_driver pwrap_drv = {
963 .driver = {
964 .name = "mt-pmic-pwrap",
965 .owner = THIS_MODULE,
966 .of_match_table = of_match_ptr(of_pwrap_match_tbl),
967 },
968 .probe = pwrap_probe,
969};
970
971module_platform_driver(pwrap_drv);
972
973MODULE_AUTHOR("Flora Fu, MediaTek");
974MODULE_DESCRIPTION("MediaTek MT8135 PMIC Wrapper Driver");
975MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 7bd2c94f54a4..460b2dba109c 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -4,6 +4,7 @@
4config QCOM_GSBI 4config QCOM_GSBI
5 tristate "QCOM General Serial Bus Interface" 5 tristate "QCOM General Serial Bus Interface"
6 depends on ARCH_QCOM 6 depends on ARCH_QCOM
7 select MFD_SYSCON
7 help 8 help
8 Say y here to enable GSBI support. The GSBI provides control 9 Say y here to enable GSBI support. The GSBI provides control
9 functions for connecting the underlying serial UART, SPI, and I2C 10 functions for connecting the underlying serial UART, SPI, and I2C
diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c
index 729425ddfd3e..09c669e70d63 100644
--- a/drivers/soc/qcom/qcom_gsbi.c
+++ b/drivers/soc/qcom/qcom_gsbi.c
@@ -18,22 +18,129 @@
18#include <linux/of.h> 18#include <linux/of.h>
19#include <linux/of_platform.h> 19#include <linux/of_platform.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/regmap.h>
22#include <linux/mfd/syscon.h>
23#include <dt-bindings/soc/qcom,gsbi.h>
21 24
22#define GSBI_CTRL_REG 0x0000 25#define GSBI_CTRL_REG 0x0000
23#define GSBI_PROTOCOL_SHIFT 4 26#define GSBI_PROTOCOL_SHIFT 4
27#define MAX_GSBI 12
28
29#define TCSR_ADM_CRCI_BASE 0x70
30
31struct crci_config {
32 u32 num_rows;
33 const u32 (*array)[MAX_GSBI];
34};
35
36static const u32 crci_ipq8064[][MAX_GSBI] = {
37 {
38 0x000003, 0x00000c, 0x000030, 0x0000c0,
39 0x000300, 0x000c00, 0x003000, 0x00c000,
40 0x030000, 0x0c0000, 0x300000, 0xc00000
41 },
42 {
43 0x000003, 0x00000c, 0x000030, 0x0000c0,
44 0x000300, 0x000c00, 0x003000, 0x00c000,
45 0x030000, 0x0c0000, 0x300000, 0xc00000
46 },
47};
48
49static const struct crci_config config_ipq8064 = {
50 .num_rows = ARRAY_SIZE(crci_ipq8064),
51 .array = crci_ipq8064,
52};
53
54static const unsigned int crci_apq8064[][MAX_GSBI] = {
55 {
56 0x001800, 0x006000, 0x000030, 0x0000c0,
57 0x000300, 0x000400, 0x000000, 0x000000,
58 0x000000, 0x000000, 0x000000, 0x000000
59 },
60 {
61 0x000000, 0x000000, 0x000000, 0x000000,
62 0x000000, 0x000020, 0x0000c0, 0x000000,
63 0x000000, 0x000000, 0x000000, 0x000000
64 },
65};
66
67static const struct crci_config config_apq8064 = {
68 .num_rows = ARRAY_SIZE(crci_apq8064),
69 .array = crci_apq8064,
70};
71
72static const unsigned int crci_msm8960[][MAX_GSBI] = {
73 {
74 0x000003, 0x00000c, 0x000030, 0x0000c0,
75 0x000300, 0x000400, 0x000000, 0x000000,
76 0x000000, 0x000000, 0x000000, 0x000000
77 },
78 {
79 0x000000, 0x000000, 0x000000, 0x000000,
80 0x000000, 0x000020, 0x0000c0, 0x000300,
81 0x001800, 0x006000, 0x000000, 0x000000
82 },
83};
84
85static const struct crci_config config_msm8960 = {
86 .num_rows = ARRAY_SIZE(crci_msm8960),
87 .array = crci_msm8960,
88};
89
90static const unsigned int crci_msm8660[][MAX_GSBI] = {
91 { /* ADM 0 - B */
92 0x000003, 0x00000c, 0x000030, 0x0000c0,
93 0x000300, 0x000c00, 0x003000, 0x00c000,
94 0x030000, 0x0c0000, 0x300000, 0xc00000
95 },
96 { /* ADM 0 - B */
97 0x000003, 0x00000c, 0x000030, 0x0000c0,
98 0x000300, 0x000c00, 0x003000, 0x00c000,
99 0x030000, 0x0c0000, 0x300000, 0xc00000
100 },
101 { /* ADM 1 - A */
102 0x000003, 0x00000c, 0x000030, 0x0000c0,
103 0x000300, 0x000c00, 0x003000, 0x00c000,
104 0x030000, 0x0c0000, 0x300000, 0xc00000
105 },
106 { /* ADM 1 - B */
107 0x000003, 0x00000c, 0x000030, 0x0000c0,
108 0x000300, 0x000c00, 0x003000, 0x00c000,
109 0x030000, 0x0c0000, 0x300000, 0xc00000
110 },
111};
112
113static const struct crci_config config_msm8660 = {
114 .num_rows = ARRAY_SIZE(crci_msm8660),
115 .array = crci_msm8660,
116};
24 117
25struct gsbi_info { 118struct gsbi_info {
26 struct clk *hclk; 119 struct clk *hclk;
27 u32 mode; 120 u32 mode;
28 u32 crci; 121 u32 crci;
122 struct regmap *tcsr;
123};
124
125static const struct of_device_id tcsr_dt_match[] = {
126 { .compatible = "qcom,tcsr-ipq8064", .data = &config_ipq8064},
127 { .compatible = "qcom,tcsr-apq8064", .data = &config_apq8064},
128 { .compatible = "qcom,tcsr-msm8960", .data = &config_msm8960},
129 { .compatible = "qcom,tcsr-msm8660", .data = &config_msm8660},
130 { },
29}; 131};
30 132
31static int gsbi_probe(struct platform_device *pdev) 133static int gsbi_probe(struct platform_device *pdev)
32{ 134{
33 struct device_node *node = pdev->dev.of_node; 135 struct device_node *node = pdev->dev.of_node;
136 struct device_node *tcsr_node;
137 const struct of_device_id *match;
34 struct resource *res; 138 struct resource *res;
35 void __iomem *base; 139 void __iomem *base;
36 struct gsbi_info *gsbi; 140 struct gsbi_info *gsbi;
141 int i;
142 u32 mask, gsbi_num;
143 const struct crci_config *config = NULL;
37 144
38 gsbi = devm_kzalloc(&pdev->dev, sizeof(*gsbi), GFP_KERNEL); 145 gsbi = devm_kzalloc(&pdev->dev, sizeof(*gsbi), GFP_KERNEL);
39 146
@@ -45,6 +152,32 @@ static int gsbi_probe(struct platform_device *pdev)
45 if (IS_ERR(base)) 152 if (IS_ERR(base))
46 return PTR_ERR(base); 153 return PTR_ERR(base);
47 154
155 /* get the tcsr node and setup the config and regmap */
156 gsbi->tcsr = syscon_regmap_lookup_by_phandle(node, "syscon-tcsr");
157
158 if (!IS_ERR(gsbi->tcsr)) {
159 tcsr_node = of_parse_phandle(node, "syscon-tcsr", 0);
160 if (tcsr_node) {
161 match = of_match_node(tcsr_dt_match, tcsr_node);
162 if (match)
163 config = match->data;
164 else
165 dev_warn(&pdev->dev, "no matching TCSR\n");
166
167 of_node_put(tcsr_node);
168 }
169 }
170
171 if (of_property_read_u32(node, "cell-index", &gsbi_num)) {
172 dev_err(&pdev->dev, "missing cell-index\n");
173 return -EINVAL;
174 }
175
176 if (gsbi_num < 1 || gsbi_num > MAX_GSBI) {
177 dev_err(&pdev->dev, "invalid cell-index\n");
178 return -EINVAL;
179 }
180
48 if (of_property_read_u32(node, "qcom,mode", &gsbi->mode)) { 181 if (of_property_read_u32(node, "qcom,mode", &gsbi->mode)) {
49 dev_err(&pdev->dev, "missing mode configuration\n"); 182 dev_err(&pdev->dev, "missing mode configuration\n");
50 return -EINVAL; 183 return -EINVAL;
@@ -64,6 +197,25 @@ static int gsbi_probe(struct platform_device *pdev)
64 writel_relaxed((gsbi->mode << GSBI_PROTOCOL_SHIFT) | gsbi->crci, 197 writel_relaxed((gsbi->mode << GSBI_PROTOCOL_SHIFT) | gsbi->crci,
65 base + GSBI_CTRL_REG); 198 base + GSBI_CTRL_REG);
66 199
200 /*
201 * modify tcsr to reflect mode and ADM CRCI mux
202 * Each gsbi contains a pair of bits, one for RX and one for TX
203 * SPI mode requires both bits cleared, otherwise they are set
204 */
205 if (config) {
206 for (i = 0; i < config->num_rows; i++) {
207 mask = config->array[i][gsbi_num - 1];
208
209 if (gsbi->mode == GSBI_PROT_SPI)
210 regmap_update_bits(gsbi->tcsr,
211 TCSR_ADM_CRCI_BASE + 4 * i, mask, 0);
212 else
213 regmap_update_bits(gsbi->tcsr,
214 TCSR_ADM_CRCI_BASE + 4 * i, mask, mask);
215
216 }
217 }
218
67 /* make sure the gsbi control write is not reordered */ 219 /* make sure the gsbi control write is not reordered */
68 wmb(); 220 wmb();
69 221
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 16f202350997..ce4f3a7f95fd 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -154,7 +154,7 @@ config ARM_SP805_WATCHDOG
154 154
155config AT91RM9200_WATCHDOG 155config AT91RM9200_WATCHDOG
156 tristate "AT91RM9200 watchdog" 156 tristate "AT91RM9200 watchdog"
157 depends on SOC_AT91RM9200 157 depends on SOC_AT91RM9200 && MFD_SYSCON
158 help 158 help
159 Watchdog timer embedded into AT91RM9200 chips. This will reboot your 159 Watchdog timer embedded into AT91RM9200 chips. This will reboot your
160 system when the timeout is reached. 160 system when the timeout is reached.
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index d244112d5b6f..41cecb55766c 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -12,27 +12,32 @@
12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 13
14#include <linux/bitops.h> 14#include <linux/bitops.h>
15#include <linux/delay.h>
15#include <linux/errno.h> 16#include <linux/errno.h>
16#include <linux/fs.h> 17#include <linux/fs.h>
17#include <linux/init.h> 18#include <linux/init.h>
18#include <linux/io.h> 19#include <linux/io.h>
19#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/mfd/syscon.h>
22#include <linux/mfd/syscon/atmel-st.h>
20#include <linux/miscdevice.h> 23#include <linux/miscdevice.h>
21#include <linux/module.h> 24#include <linux/module.h>
22#include <linux/moduleparam.h> 25#include <linux/moduleparam.h>
23#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/reboot.h>
28#include <linux/regmap.h>
24#include <linux/types.h> 29#include <linux/types.h>
25#include <linux/watchdog.h> 30#include <linux/watchdog.h>
26#include <linux/uaccess.h> 31#include <linux/uaccess.h>
27#include <linux/of.h> 32#include <linux/of.h>
28#include <linux/of_device.h> 33#include <linux/of_device.h>
29#include <mach/at91_st.h>
30 34
31#define WDT_DEFAULT_TIME 5 /* seconds */ 35#define WDT_DEFAULT_TIME 5 /* seconds */
32#define WDT_MAX_TIME 256 /* seconds */ 36#define WDT_MAX_TIME 256 /* seconds */
33 37
34static int wdt_time = WDT_DEFAULT_TIME; 38static int wdt_time = WDT_DEFAULT_TIME;
35static bool nowayout = WATCHDOG_NOWAYOUT; 39static bool nowayout = WATCHDOG_NOWAYOUT;
40static struct regmap *regmap_st;
36 41
37module_param(wdt_time, int, 0); 42module_param(wdt_time, int, 0);
38MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default=" 43MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
@@ -50,12 +55,33 @@ static unsigned long at91wdt_busy;
50 55
51/* ......................................................................... */ 56/* ......................................................................... */
52 57
58static int at91rm9200_restart(struct notifier_block *this,
59 unsigned long mode, void *cmd)
60{
61 /*
62 * Perform a hardware reset with the use of the Watchdog timer.
63 */
64 regmap_write(regmap_st, AT91_ST_WDMR,
65 AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
66 regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);
67
68 mdelay(2000);
69
70 pr_emerg("Unable to restart system\n");
71 return NOTIFY_DONE;
72}
73
74static struct notifier_block at91rm9200_restart_nb = {
75 .notifier_call = at91rm9200_restart,
76 .priority = 192,
77};
78
53/* 79/*
54 * Disable the watchdog. 80 * Disable the watchdog.
55 */ 81 */
56static inline void at91_wdt_stop(void) 82static inline void at91_wdt_stop(void)
57{ 83{
58 at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN); 84 regmap_write(regmap_st, AT91_ST_WDMR, AT91_ST_EXTEN);
59} 85}
60 86
61/* 87/*
@@ -63,9 +89,9 @@ static inline void at91_wdt_stop(void)
63 */ 89 */
64static inline void at91_wdt_start(void) 90static inline void at91_wdt_start(void)
65{ 91{
66 at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | 92 regmap_write(regmap_st, AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
67 (((65536 * wdt_time) >> 8) & AT91_ST_WDV)); 93 (((65536 * wdt_time) >> 8) & AT91_ST_WDV));
68 at91_st_write(AT91_ST_CR, AT91_ST_WDRST); 94 regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);
69} 95}
70 96
71/* 97/*
@@ -73,7 +99,7 @@ static inline void at91_wdt_start(void)
73 */ 99 */
74static inline void at91_wdt_reload(void) 100static inline void at91_wdt_reload(void)
75{ 101{
76 at91_st_write(AT91_ST_CR, AT91_ST_WDRST); 102 regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);
77} 103}
78 104
79/* ......................................................................... */ 105/* ......................................................................... */
@@ -203,16 +229,32 @@ static struct miscdevice at91wdt_miscdev = {
203 229
204static int at91wdt_probe(struct platform_device *pdev) 230static int at91wdt_probe(struct platform_device *pdev)
205{ 231{
232 struct device *dev = &pdev->dev;
233 struct device *parent;
206 int res; 234 int res;
207 235
208 if (at91wdt_miscdev.parent) 236 if (at91wdt_miscdev.parent)
209 return -EBUSY; 237 return -EBUSY;
210 at91wdt_miscdev.parent = &pdev->dev; 238 at91wdt_miscdev.parent = &pdev->dev;
211 239
240 parent = dev->parent;
241 if (!parent) {
242 dev_err(dev, "no parent\n");
243 return -ENODEV;
244 }
245
246 regmap_st = syscon_node_to_regmap(parent->of_node);
247 if (!regmap_st)
248 return -ENODEV;
249
212 res = misc_register(&at91wdt_miscdev); 250 res = misc_register(&at91wdt_miscdev);
213 if (res) 251 if (res)
214 return res; 252 return res;
215 253
254 res = register_restart_handler(&at91rm9200_restart_nb);
255 if (res)
256 dev_warn(dev, "failed to register restart handler\n");
257
216 pr_info("AT91 Watchdog Timer enabled (%d seconds%s)\n", 258 pr_info("AT91 Watchdog Timer enabled (%d seconds%s)\n",
217 wdt_time, nowayout ? ", nowayout" : ""); 259 wdt_time, nowayout ? ", nowayout" : "");
218 return 0; 260 return 0;
@@ -220,8 +262,13 @@ static int at91wdt_probe(struct platform_device *pdev)
220 262
221static int at91wdt_remove(struct platform_device *pdev) 263static int at91wdt_remove(struct platform_device *pdev)
222{ 264{
265 struct device *dev = &pdev->dev;
223 int res; 266 int res;
224 267
268 res = unregister_restart_handler(&at91rm9200_restart_nb);
269 if (res)
270 dev_warn(dev, "failed to unregister restart handler\n");
271
225 res = misc_deregister(&at91wdt_miscdev); 272 res = misc_deregister(&at91wdt_miscdev);
226 if (!res) 273 if (!res)
227 at91wdt_miscdev.parent = NULL; 274 at91wdt_miscdev.parent = NULL;
@@ -267,7 +314,7 @@ static struct platform_driver at91wdt_driver = {
267 .suspend = at91wdt_suspend, 314 .suspend = at91wdt_suspend,
268 .resume = at91wdt_resume, 315 .resume = at91wdt_resume,
269 .driver = { 316 .driver = {
270 .name = "at91_wdt", 317 .name = "atmel_st_watchdog",
271 .of_match_table = at91_wdt_dt_ids, 318 .of_match_table = at91_wdt_dt_ids,
272 }, 319 },
273}; 320};
@@ -296,4 +343,4 @@ module_exit(at91_wdt_exit);
296MODULE_AUTHOR("Andrew Victor"); 343MODULE_AUTHOR("Andrew Victor");
297MODULE_DESCRIPTION("Watchdog driver for Atmel AT91RM9200"); 344MODULE_DESCRIPTION("Watchdog driver for Atmel AT91RM9200");
298MODULE_LICENSE("GPL"); 345MODULE_LICENSE("GPL");
299MODULE_ALIAS("platform:at91_wdt"); 346MODULE_ALIAS("platform:atmel_st_watchdog");
diff --git a/include/linux/arm-cci.h b/include/linux/arm-cci.h
index 79d6edf446d5..521ec1f2e6bc 100644
--- a/include/linux/arm-cci.h
+++ b/include/linux/arm-cci.h
@@ -24,16 +24,22 @@
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/types.h> 25#include <linux/types.h>
26 26
27#include <asm/arm-cci.h>
28
27struct device_node; 29struct device_node;
28 30
29#ifdef CONFIG_ARM_CCI 31#ifdef CONFIG_ARM_CCI
30extern bool cci_probed(void); 32extern bool cci_probed(void);
33#else
34static inline bool cci_probed(void) { return false; }
35#endif
36
37#ifdef CONFIG_ARM_CCI400_PORT_CTRL
31extern int cci_ace_get_port(struct device_node *dn); 38extern int cci_ace_get_port(struct device_node *dn);
32extern int cci_disable_port_by_cpu(u64 mpidr); 39extern int cci_disable_port_by_cpu(u64 mpidr);
33extern int __cci_control_port_by_device(struct device_node *dn, bool enable); 40extern int __cci_control_port_by_device(struct device_node *dn, bool enable);
34extern int __cci_control_port_by_index(u32 port, bool enable); 41extern int __cci_control_port_by_index(u32 port, bool enable);
35#else 42#else
36static inline bool cci_probed(void) { return false; }
37static inline int cci_ace_get_port(struct device_node *dn) 43static inline int cci_ace_get_port(struct device_node *dn)
38{ 44{
39 return -ENODEV; 45 return -ENODEV;
@@ -49,6 +55,7 @@ static inline int __cci_control_port_by_index(u32 port, bool enable)
49 return -ENODEV; 55 return -ENODEV;
50} 56}
51#endif 57#endif
58
52#define cci_disable_port_by_device(dev) \ 59#define cci_disable_port_by_device(dev) \
53 __cci_control_port_by_device(dev, false) 60 __cci_control_port_by_device(dev, false)
54#define cci_enable_port_by_device(dev) \ 61#define cci_enable_port_by_device(dev) \
diff --git a/include/linux/mfd/syscon/atmel-st.h b/include/linux/mfd/syscon/atmel-st.h
new file mode 100644
index 000000000000..8acf1ec1fa32
--- /dev/null
+++ b/include/linux/mfd/syscon/atmel-st.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2005 Ivan Kokshaysky
3 * Copyright (C) SAN People
4 *
5 * System Timer (ST) - System peripherals registers.
6 * Based on AT91RM9200 datasheet revision E.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#ifndef _LINUX_MFD_SYSCON_ATMEL_ST_H
15#define _LINUX_MFD_SYSCON_ATMEL_ST_H
16
17#include <linux/bitops.h>
18
19#define AT91_ST_CR 0x00 /* Control Register */
20#define AT91_ST_WDRST BIT(0) /* Watchdog Timer Restart */
21
22#define AT91_ST_PIMR 0x04 /* Period Interval Mode Register */
23#define AT91_ST_PIV 0xffff /* Period Interval Value */
24
25#define AT91_ST_WDMR 0x08 /* Watchdog Mode Register */
26#define AT91_ST_WDV 0xffff /* Watchdog Counter Value */
27#define AT91_ST_RSTEN BIT(16) /* Reset Enable */
28#define AT91_ST_EXTEN BIT(17) /* External Signal Assertion Enable */
29
30#define AT91_ST_RTMR 0x0c /* Real-time Mode Register */
31#define AT91_ST_RTPRES 0xffff /* Real-time Prescalar Value */
32
33#define AT91_ST_SR 0x10 /* Status Register */
34#define AT91_ST_PITS BIT(0) /* Period Interval Timer Status */
35#define AT91_ST_WDOVF BIT(1) /* Watchdog Overflow */
36#define AT91_ST_RTTINC BIT(2) /* Real-time Timer Increment */
37#define AT91_ST_ALMS BIT(3) /* Alarm Status */
38
39#define AT91_ST_IER 0x14 /* Interrupt Enable Register */
40#define AT91_ST_IDR 0x18 /* Interrupt Disable Register */
41#define AT91_ST_IMR 0x1c /* Interrupt Mask Register */
42
43#define AT91_ST_RTAR 0x20 /* Real-time Alarm Register */
44#define AT91_ST_ALMV 0xfffff /* Alarm Value */
45
46#define AT91_ST_CRTR 0x24 /* Current Real-time Register */
47#define AT91_ST_CRTV 0xfffff /* Current Real-Time Value */
48
49#endif /* _LINUX_MFD_SYSCON_ATMEL_ST_H */
diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h
index c2080eebbb47..7dee00143afd 100644
--- a/include/linux/omap-gpmc.h
+++ b/include/linux/omap-gpmc.h
@@ -163,7 +163,8 @@ extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
163 163
164extern void gpmc_cs_write_reg(int cs, int idx, u32 val); 164extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
165extern int gpmc_calc_divider(unsigned int sync_clk); 165extern int gpmc_calc_divider(unsigned int sync_clk);
166extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t); 166extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t,
167 const struct gpmc_settings *s);
167extern int gpmc_cs_program_settings(int cs, struct gpmc_settings *p); 168extern int gpmc_cs_program_settings(int cs, struct gpmc_settings *p);
168extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base); 169extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
169extern void gpmc_cs_free(int cs); 170extern void gpmc_cs_free(int cs);
diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h
new file mode 100644
index 000000000000..d7a974d5f57c
--- /dev/null
+++ b/include/linux/qcom_scm.h
@@ -0,0 +1,28 @@
1/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
2 * Copyright (C) 2015 Linaro Ltd.
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 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13#ifndef __QCOM_SCM_H
14#define __QCOM_SCM_H
15
16extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus);
17extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus);
18
19#define QCOM_SCM_CPU_PWR_DOWN_L2_ON 0x0
20#define QCOM_SCM_CPU_PWR_DOWN_L2_OFF 0x1
21
22extern void qcom_scm_cpu_power_down(u32 flags);
23
24#define QCOM_SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
25
26extern u32 qcom_scm_get_version(void);
27
28#endif