提交 6cd94d5e 编写于 作者: L Linus Torvalds

Merge tag 'soc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM SoC platform changes from Arnd Bergmann:
 "New and updated SoC support, notable changes include:

   - bcm:
        brcmstb SMP support
        initial iproc/cygnus support
   - exynos:
        Exynos4415 SoC support
        PMU and suspend support for Exynos5420
        PMU support for Exynos3250
        pm related maintenance
   - imx:
        new LS1021A SoC support
        vybrid 610 global timer support
   - integrator:
        convert to using multiplatform configuration
   - mediatek:
        earlyprintk support for mt8127/mt8135
   - meson:
        meson8 soc and l2 cache controller support
   - mvebu:
        Armada 38x CPU hotplug support
        drop support for prerelease Armada 375 Z1 stepping
        extended suspend support, now works on Armada 370/XP
   - omap:
        hwmod related maintenance
        prcm cleanup
   - pxa:
        initial pxa27x DT handling
   - rockchip:
        SMP support for rk3288
        add cpu frequency scaling support
   - shmobile:
        r8a7740 power domain support
        various small restart, timer, pci apmu changes
   - sunxi:
        Allwinner A80 (sun9i) earlyprintk support
   - ux500:
        power domain support

  Overall, a significant chunk of changes, coming mostly from the usual
  suspects: omap, shmobile, samsung and mvebu, all of which already
  contain a lot of platform specific code in arch/arm"

* tag 'soc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (187 commits)
  ARM: mvebu: use the cpufreq-dt platform_data for independent clocks
  soc: integrator: Add terminating entry for integrator_cm_match
  ARM: mvebu: add SDRAM controller description for Armada XP
  ARM: mvebu: adjust mbus controller description on Armada 370/XP
  ARM: mvebu: add suspend/resume DT information for Armada XP GP
  ARM: mvebu: synchronize secondary CPU clocks on resume
  ARM: mvebu: make sure MMU is disabled in armada_370_xp_cpu_resume
  ARM: mvebu: Armada XP GP specific suspend/resume code
  ARM: mvebu: reserve the first 10 KB of each memory bank for suspend/resume
  ARM: mvebu: implement suspend/resume support for Armada XP
  clk: mvebu: add suspend/resume for gatable clocks
  bus: mvebu-mbus: provide a mechanism to save SDRAM window configuration
  bus: mvebu-mbus: suspend/resume support
  clocksource: time-armada-370-xp: add suspend/resume support
  irqchip: armada-370-xp: Add suspend/resume support
  ARM: add lolevel debug support for asm9260
  ARM: add mach-asm9260
  ARM: EXYNOS: use u8 for val[] in struct exynos_pmu_conf
  power: reset: imx-snvs-poweroff: add power off driver for i.mx6
  ARM: imx: temporarily remove CONFIG_SOC_FSL from LS1021A
  ...
...@@ -7,32 +7,14 @@ world, which changes the way some things have to be initialized. This makes ...@@ -7,32 +7,14 @@ world, which changes the way some things have to be initialized. This makes
a need to provide an interface for such platforms to specify available firmware a need to provide an interface for such platforms to specify available firmware
operations and call them when needed. operations and call them when needed.
Firmware operations can be specified using struct firmware_ops Firmware operations can be specified by filling in a struct firmware_ops
with appropriate callbacks and then registering it with register_firmware_ops()
struct firmware_ops { function.
/*
* Enters CPU idle mode
*/
int (*do_idle)(void);
/*
* Sets boot address of specified physical CPU
*/
int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr);
/*
* Boots specified physical CPU
*/
int (*cpu_boot)(int cpu);
/*
* Initializes L2 cache
*/
int (*l2x0_init)(void);
};
and then registered with register_firmware_ops function
void register_firmware_ops(const struct firmware_ops *ops) void register_firmware_ops(const struct firmware_ops *ops)
the ops pointer must be non-NULL. The ops pointer must be non-NULL. More information about struct firmware_ops
and its members can be found in arch/arm/include/asm/firmware.h header.
There is a default, empty set of operations provided, so there is no need to There is a default, empty set of operations provided, so there is no need to
set anything if platform does not require firmware operations. set anything if platform does not require firmware operations.
......
...@@ -37,16 +37,26 @@ SunXi family ...@@ -37,16 +37,26 @@ SunXi family
http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf
- Allwinner A23 - Allwinner A23
+ Not Supported + Datasheet
http://dl.linux-sunxi.org/A23/A23%20Datasheet%20V1.0%2020130830.pdf
+ User Manual
http://dl.linux-sunxi.org/A23/A23%20User%20Manual%20V1.0%2020130830.pdf
* Quad ARM Cortex-A7 based SoCs * Quad ARM Cortex-A7 based SoCs
- Allwinner A31 (sun6i) - Allwinner A31 (sun6i)
+ Datasheet + Datasheet
http://dl.linux-sunxi.org/A31/A31%20Datasheet%20-%20v1.00%20(2012-12-24).pdf http://dl.linux-sunxi.org/A31/A3x_release_document/A31/IC/A31%20datasheet%20V1.3%2020131106.pdf
+ User Manual
http://dl.linux-sunxi.org/A31/A3x_release_document/A31/IC/A31%20user%20manual%20V1.1%2020130630.pdf
- Allwinner A31s (sun6i) - Allwinner A31s (sun6i)
+ Not Supported + Not Supported
+ Datasheet
http://dl.linux-sunxi.org/A31/A3x_release_document/A31s/IC/A31s%20datasheet%20V1.3%2020131106.pdf
+ User Manual
http://dl.linux-sunxi.org/A31/A3x_release_document/A31s/IC/A31s%20User%20Manual%20%20V1.0%2020130322.pdf
* Quad ARM Cortex-A15, Quad ARM Cortex-A7 based SoCs * Quad ARM Cortex-A15, Quad ARM Cortex-A7 based SoCs
- Allwinner A80 - Allwinner A80
+ Not Supported + Datasheet
\ No newline at end of file http://dl.linux-sunxi.org/A80/A80_Datasheet_Revision_1.0_0404.pdf
...@@ -2,7 +2,9 @@ Amlogic MesonX device tree bindings ...@@ -2,7 +2,9 @@ Amlogic MesonX device tree bindings
------------------------------------------- -------------------------------------------
Boards with the Amlogic Meson6 SoC shall have the following properties: Boards with the Amlogic Meson6 SoC shall have the following properties:
Required root node property:
compatible: "amlogic,meson6"
Required root node property: Boards with the Amlogic Meson8 SoC shall have the following properties:
Required root node property:
compatible = "amlogic,meson6"; compatible: "amlogic,meson8";
...@@ -227,6 +227,15 @@ nodes to be present and contain the properties described below. ...@@ -227,6 +227,15 @@ nodes to be present and contain the properties described below.
# List of phandles to idle state nodes supported # List of phandles to idle state nodes supported
by this cpu [3]. by this cpu [3].
- rockchip,pmu
Usage: optional for systems that have an "enable-method"
property value of "rockchip,rk3066-smp"
While optional, it is the preferred way to get access to
the cpu-core power-domains.
Value type: <phandle>
Definition: Specifies the syscon node controlling the cpu core
power domains.
Example 1 (dual-cluster big.LITTLE system 32-bit): Example 1 (dual-cluster big.LITTLE system 32-bit):
cpus { cpus {
......
Allwinner sunXi Platforms Device Tree Bindings
Each device tree must specify which Allwinner SoC it uses,
using one of the following compatible strings:
allwinner,sun4i-a10
allwinner,sun5i-a10s
allwinner,sun5i-a13
allwinner,sun6i-a31
allwinner,sun7i-a20
allwinner,sun8i-a23
allwinner,sun9i-a80
* ST-Ericsson UX500 PM Domains
UX500 supports multiple PM domains which are used to gate power to one or
more peripherals on the SOC.
The implementation of PM domains for UX500 are based upon the generic PM domain
and use the corresponding DT bindings.
==PM domain providers==
Required properties:
- compatible: Must be "stericsson,ux500-pm-domains".
- #power-domain-cells : Number of cells in a power domain specifier, must be 1.
Example:
pm_domains: pm_domains0 {
compatible = "stericsson,ux500-pm-domains";
#power-domain-cells = <1>;
};
==PM domain consumers==
Required properties:
- power-domains: A phandle and PM domain specifier. Below are the list of
valid specifiers:
Index Specifier
----- ---------
0 DOMAIN_VAPE
Example:
sdi0_per1@80126000 {
compatible = "arm,pl18x", "arm,primecell";
power-domains = <&pm_domains DOMAIN_VAPE>
};
...@@ -48,9 +48,12 @@ Required properties: ...@@ -48,9 +48,12 @@ Required properties:
- compatible: Should be set to "marvell,mbus-controller". - compatible: Should be set to "marvell,mbus-controller".
- reg: Device's register space. - reg: Device's register space.
Two entries are expected (see the examples below): Two or three entries are expected (see the examples below):
the first one controls the devices decoding window and the first one controls the devices decoding window,
the second one controls the SDRAM decoding window. the second one controls the SDRAM decoding window and
the third controls the MBus bridge (only with the
marvell,armada370-mbus and marvell,armadaxp-mbus
compatible strings)
Example: Example:
...@@ -67,7 +70,7 @@ Example: ...@@ -67,7 +70,7 @@ Example:
mbusc: mbus-controller@20000 { mbusc: mbus-controller@20000 {
compatible = "marvell,mbus-controller"; compatible = "marvell,mbus-controller";
reg = <0x20000 0x100>, <0x20180 0x20>; reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>;
}; };
/* more children ...*/ /* more children ...*/
...@@ -126,7 +129,7 @@ are skipped. ...@@ -126,7 +129,7 @@ are skipped.
mbusc: mbus-controller@20000 { mbusc: mbus-controller@20000 {
compatible = "marvell,mbus-controller"; compatible = "marvell,mbus-controller";
reg = <0x20000 0x100>, <0x20180 0x20>; reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>;
}; };
/* more children ...*/ /* more children ...*/
...@@ -170,7 +173,7 @@ Using this macro, the above example would be: ...@@ -170,7 +173,7 @@ Using this macro, the above example would be:
mbusc: mbus-controller@20000 { mbusc: mbus-controller@20000 {
compatible = "marvell,mbus-controller"; compatible = "marvell,mbus-controller";
reg = <0x20000 0x100>, <0x20180 0x20>; reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>;
}; };
/* other children */ /* other children */
...@@ -266,7 +269,7 @@ See the example below, where a more complete device tree is shown: ...@@ -266,7 +269,7 @@ See the example below, where a more complete device tree is shown:
ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>; ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
mbusc: mbus-controller@20000 { mbusc: mbus-controller@20000 {
reg = <0x20000 0x100>, <0x20180 0x20>; reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>;
}; };
interrupt-controller@20000 { interrupt-controller@20000 {
......
Device Tree bindings for MVEBU SDRAM controllers
The Marvell EBU SoCs all have a SDRAM controller. The SDRAM controller
differs from one SoC variant to another, but they also share a number
of commonalities.
For now, this Device Tree binding documentation only documents the
Armada XP SDRAM controller.
Required properties:
- compatible: for Armada XP, "marvell,armada-xp-sdram-controller"
- reg: a resource specifier for the register space, which should
include all SDRAM controller registers as per the datasheet.
Example:
sdramc@1400 {
compatible = "marvell,armada-xp-sdram-controller";
reg = <0x1400 0x500>;
};
i.mx6 Poweroff Driver
SNVS_LPCR in SNVS module can power off the whole system by pull
PMIC_ON_REQ low if PMIC_ON_REQ is connected with external PMIC.
If you don't want to use PMIC_ON_REQ as power on/off control,
please set status='disabled' to disable this driver.
Required Properties:
-compatible: "fsl,sec-v4.0-poweroff"
-reg: Specifies the physical address of the SNVS_LPCR register
Example:
snvs@020cc000 {
compatible = "fsl,sec-v4.0-mon", "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x020cc000 0x4000>;
.....
snvs_poweroff: snvs-poweroff@38 {
compatible = "fsl,sec-v4.0-poweroff";
reg = <0x38 0x4>;
};
}
...@@ -91,6 +91,7 @@ lltc Linear Technology Corporation ...@@ -91,6 +91,7 @@ lltc Linear Technology Corporation
marvell Marvell Technology Group Ltd. marvell Marvell Technology Group Ltd.
maxim Maxim Integrated Products maxim Maxim Integrated Products
mediatek MediaTek Inc. mediatek MediaTek Inc.
merrii Merrii Technology Co., Ltd.
micrel Micrel Inc. micrel Micrel Inc.
microchip Microchip Technology Inc. microchip Microchip Technology Inc.
micron Micron Technology Inc. micron Micron Technology Inc.
......
...@@ -1379,6 +1379,7 @@ F: arch/arm/configs/lager_defconfig ...@@ -1379,6 +1379,7 @@ F: arch/arm/configs/lager_defconfig
F: arch/arm/configs/mackerel_defconfig F: arch/arm/configs/mackerel_defconfig
F: arch/arm/configs/marzen_defconfig F: arch/arm/configs/marzen_defconfig
F: arch/arm/configs/shmobile_defconfig F: arch/arm/configs/shmobile_defconfig
F: arch/arm/include/debug/renesas-scif.S
F: arch/arm/mach-shmobile/ F: arch/arm/mach-shmobile/
F: drivers/sh/ F: drivers/sh/
......
...@@ -320,24 +320,6 @@ config ARCH_MULTIPLATFORM ...@@ -320,24 +320,6 @@ config ARCH_MULTIPLATFORM
select SPARSE_IRQ select SPARSE_IRQ
select USE_OF select USE_OF
config ARCH_INTEGRATOR
bool "ARM Ltd. Integrator family"
select ARM_AMBA
select ARM_PATCH_PHYS_VIRT if MMU
select AUTO_ZRELADDR
select COMMON_CLK
select COMMON_CLK_VERSATILE
select GENERIC_CLOCKEVENTS
select HAVE_TCM
select ICST
select MULTI_IRQ_HANDLER
select PLAT_VERSATILE
select SPARSE_IRQ
select USE_OF
select VERSATILE_FPGA_IRQ
help
Support for ARM's Integrator platform.
config ARCH_REALVIEW config ARCH_REALVIEW
bool "ARM Ltd. RealView family" bool "ARM Ltd. RealView family"
select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_OPTIONAL_GPIOLIB
...@@ -857,6 +839,8 @@ config ARCH_VIRT ...@@ -857,6 +839,8 @@ config ARCH_VIRT
# #
source "arch/arm/mach-mvebu/Kconfig" source "arch/arm/mach-mvebu/Kconfig"
source "arch/arm/mach-asm9260/Kconfig"
source "arch/arm/mach-at91/Kconfig" source "arch/arm/mach-at91/Kconfig"
source "arch/arm/mach-axxia/Kconfig" source "arch/arm/mach-axxia/Kconfig"
......
...@@ -93,6 +93,27 @@ choice ...@@ -93,6 +93,27 @@ choice
prompt "Kernel low-level debugging port" prompt "Kernel low-level debugging port"
depends on DEBUG_LL depends on DEBUG_LL
config DEBUG_ASM9260_UART
bool "Kernel low-level debugging via asm9260 UART"
depends on MACH_ASM9260
help
Say Y here if you want the debug print routines to direct
their output to an UART or USART port on asm9260 based
machines.
DEBUG_UART_PHYS | DEBUG_UART_VIRT
0x80000000 | 0xf0000000 | UART0
0x80004000 | 0xf0004000 | UART1
0x80008000 | 0xf0008000 | UART2
0x8000c000 | 0xf000c000 | UART3
0x80010000 | 0xf0010000 | UART4
0x80014000 | 0xf0014000 | UART5
0x80018000 | 0xf0018000 | UART6
0x8001c000 | 0xf001c000 | UART7
0x80020000 | 0xf0020000 | UART8
0x80024000 | 0xf0024000 | UART9
config AT91_DEBUG_LL_DBGU0 config AT91_DEBUG_LL_DBGU0
bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl" bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl"
depends on HAVE_AT91_DBGU0 depends on HAVE_AT91_DBGU0
...@@ -113,7 +134,7 @@ choice ...@@ -113,7 +134,7 @@ choice
config DEBUG_BCM_5301X config DEBUG_BCM_5301X
bool "Kernel low-level debugging on BCM5301X UART1" bool "Kernel low-level debugging on BCM5301X UART1"
depends on ARCH_BCM_5301X depends on ARCH_BCM_5301X
select DEBUG_UART_PL01X select DEBUG_UART_8250
config DEBUG_BCM_KONA_UART config DEBUG_BCM_KONA_UART
bool "Kernel low-level debugging messages via BCM KONA UART" bool "Kernel low-level debugging messages via BCM KONA UART"
...@@ -139,6 +160,17 @@ choice ...@@ -139,6 +160,17 @@ choice
Say Y here if you want kernel low-level debugging support Say Y here if you want kernel low-level debugging support
on Marvell Berlin SoC based platforms. on Marvell Berlin SoC based platforms.
config DEBUG_BRCMSTB_UART
bool "Use BRCMSTB UART for low-level debug"
depends on ARCH_BRCMSTB
select DEBUG_UART_8250
help
Say Y here if you want the debug print routines to direct
their output to the first serial port on these devices.
If you have a Broadcom STB chip and would like early print
messages to appear over the UART, select this option.
config DEBUG_CLPS711X_UART1 config DEBUG_CLPS711X_UART1
bool "Kernel low-level debugging messages via UART1" bool "Kernel low-level debugging messages via UART1"
depends on ARCH_CLPS711X depends on ARCH_CLPS711X
...@@ -653,6 +685,64 @@ choice ...@@ -653,6 +685,64 @@ choice
Say Y here if you want kernel low-level debugging support Say Y here if you want kernel low-level debugging support
on Rockchip RK32xx based platforms. on Rockchip RK32xx based platforms.
config DEBUG_R7S72100_SCIF2
bool "Kernel low-level debugging messages via SCIF2 on R7S72100"
depends on ARCH_R7S72100
help
Say Y here if you want kernel low-level debugging support
via SCIF2 on Renesas RZ/A1H (R7S72100).
config DEBUG_RCAR_GEN1_SCIF0
bool "Kernel low-level debugging messages via SCIF0 on R8A7778"
depends on ARCH_R8A7778
help
Say Y here if you want kernel low-level debugging support
via SCIF0 on Renesas R-Car M1A (R8A7778).
config DEBUG_RCAR_GEN1_SCIF2
bool "Kernel low-level debugging messages via SCIF2 on R8A7779"
depends on ARCH_R8A7779
help
Say Y here if you want kernel low-level debugging support
via SCIF2 on Renesas R-Car H1 (R8A7779).
config DEBUG_RCAR_GEN2_SCIF0
bool "Kernel low-level debugging messages via SCIF0 on R8A7790/R8A7791/R8A7793)"
depends on ARCH_R8A7790 || ARCH_R8A7791 || ARCH_R8A7793
help
Say Y here if you want kernel low-level debugging support
via SCIF0 on Renesas R-Car H2 (R8A7790), M2-W (R8A7791), or
M2-N (R8A7793).
config DEBUG_RCAR_GEN2_SCIF2
bool "Kernel low-level debugging messages via SCIF2 on R8A7794"
depends on ARCH_R8A7794
help
Say Y here if you want kernel low-level debugging support
via SCIF2 on Renesas R-Car E2 (R8A7794).
config DEBUG_RMOBILE_SCIFA0
bool "Kernel low-level debugging messages via SCIFA0 on R8A73A4/SH7372"
depends on ARCH_R8A73A4 || ARCH_SH7372
help
Say Y here if you want kernel low-level debugging support
via SCIFA0 on Renesas R-Mobile APE6 (R8A73A4) or SH-Mobile
AP4 (SH7372).
config DEBUG_RMOBILE_SCIFA1
bool "Kernel low-level debugging messages via SCIFA1 on R8A7740"
depends on ARCH_R8A7740
help
Say Y here if you want kernel low-level debugging support
via SCIFA1 on Renesas R-Mobile A1 (R8A7740).
config DEBUG_RMOBILE_SCIFA4
bool "Kernel low-level debugging messages via SCIFA4 on SH73A0"
depends on ARCH_SH73A0
help
Say Y here if you want kernel low-level debugging support
via SCIFA4 on Renesas SH-Mobile AG5 (SH73A0).
config DEBUG_S3C_UART0 config DEBUG_S3C_UART0
depends on PLAT_SAMSUNG depends on PLAT_SAMSUNG
select DEBUG_EXYNOS_UART if ARCH_EXYNOS select DEBUG_EXYNOS_UART if ARCH_EXYNOS
...@@ -723,6 +813,14 @@ choice ...@@ -723,6 +813,14 @@ choice
their output to UART 2. The port must have been initialised their output to UART 2. The port must have been initialised
by the boot-loader before use. by the boot-loader before use.
config DEBUG_SA1100
depends on ARCH_SA1100
bool "Use SA1100 UARTs for low-level debug"
help
Say Y here if you want kernel low-level debugging support
on SA-11x0 UART ports. The kernel will check for the first
enabled UART in a sequence 3-1-2.
config DEBUG_SOCFPGA_UART config DEBUG_SOCFPGA_UART
depends on ARCH_SOCFPGA depends on ARCH_SOCFPGA
bool "Use SOCFPGA UART for low-level debug" bool "Use SOCFPGA UART for low-level debug"
...@@ -731,6 +829,14 @@ choice ...@@ -731,6 +829,14 @@ choice
Say Y here if you want kernel low-level debugging support Say Y here if you want kernel low-level debugging support
on SOCFPGA based platforms. on SOCFPGA based platforms.
config DEBUG_SUN9I_UART0
bool "Kernel low-level debugging messages via sun9i UART0"
depends on MACH_SUN9I
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
on Allwinner A80 based platforms on the UART0.
config DEBUG_SUNXI_UART0 config DEBUG_SUNXI_UART0
bool "Kernel low-level debugging messages via sunXi UART0" bool "Kernel low-level debugging messages via sunXi UART0"
depends on ARCH_SUNXI depends on ARCH_SUNXI
...@@ -866,6 +972,22 @@ choice ...@@ -866,6 +972,22 @@ choice
Say Y here if you want kernel low-level debugging support Say Y here if you want kernel low-level debugging support
for Mediatek mt6589 based platforms on UART0. for Mediatek mt6589 based platforms on UART0.
config DEBUG_MT8127_UART0
bool "Mediatek mt8127 UART0"
depends on ARCH_MEDIATEK
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
for Mediatek mt8127 based platforms on UART0.
config DEBUG_MT8135_UART3
bool "Mediatek mt8135 UART3"
depends on ARCH_MEDIATEK
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
for Mediatek mt8135 based platforms on UART3.
config DEBUG_VEXPRESS_UART0_DETECT config DEBUG_VEXPRESS_UART0_DETECT
bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" bool "Autodetect UART0 on Versatile Express Cortex-A core tiles"
depends on ARCH_VEXPRESS && CPU_CP15_MMU depends on ARCH_VEXPRESS && CPU_CP15_MMU
...@@ -1041,7 +1163,9 @@ config DEBUG_STI_UART ...@@ -1041,7 +1163,9 @@ config DEBUG_STI_UART
config DEBUG_LL_INCLUDE config DEBUG_LL_INCLUDE
string string
default "debug/sa1100.S" if DEBUG_SA1100
default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250 default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250
default "debug/asm9260.S" if DEBUG_ASM9260_UART
default "debug/clps711x.S" if DEBUG_CLPS711X_UART1 || DEBUG_CLPS711X_UART2 default "debug/clps711x.S" if DEBUG_CLPS711X_UART1 || DEBUG_CLPS711X_UART2
default "debug/meson.S" if DEBUG_MESON_UARTAO default "debug/meson.S" if DEBUG_MESON_UARTAO
default "debug/pl01x.S" if DEBUG_LL_UART_PL01X || DEBUG_UART_PL01X default "debug/pl01x.S" if DEBUG_LL_UART_PL01X || DEBUG_UART_PL01X
...@@ -1061,6 +1185,14 @@ config DEBUG_LL_INCLUDE ...@@ -1061,6 +1185,14 @@ config DEBUG_LL_INCLUDE
DEBUG_IMX6SX_UART DEBUG_IMX6SX_UART
default "debug/msm.S" if DEBUG_MSM_UART || DEBUG_QCOM_UARTDM default "debug/msm.S" if DEBUG_MSM_UART || DEBUG_QCOM_UARTDM
default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
default "debug/renesas-scif.S" if DEBUG_R7S72100_SCIF2
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF0
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF2
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF0
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF2
default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA0
default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA1
default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA4
default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART
default "debug/s5pv210.S" if DEBUG_S5PV210_UART default "debug/s5pv210.S" if DEBUG_S5PV210_UART
default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1 default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1
...@@ -1106,6 +1238,7 @@ config DEBUG_UART_PHYS ...@@ -1106,6 +1238,7 @@ config DEBUG_UART_PHYS
default 0x02530c00 if DEBUG_KEYSTONE_UART0 default 0x02530c00 if DEBUG_KEYSTONE_UART0
default 0x02531000 if DEBUG_KEYSTONE_UART1 default 0x02531000 if DEBUG_KEYSTONE_UART1
default 0x03010fe0 if ARCH_RPC default 0x03010fe0 if ARCH_RPC
default 0x07000000 if DEBUG_SUN9I_UART0
default 0x10009000 if DEBUG_REALVIEW_STD_PORT || \ default 0x10009000 if DEBUG_REALVIEW_STD_PORT || \
DEBUG_VEXPRESS_UART0_CA9 DEBUG_VEXPRESS_UART0_CA9
default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT
...@@ -1113,7 +1246,9 @@ config DEBUG_UART_PHYS ...@@ -1113,7 +1246,9 @@ config DEBUG_UART_PHYS
default 0x10126000 if DEBUG_RK3X_UART1 default 0x10126000 if DEBUG_RK3X_UART1
default 0x101f1000 if ARCH_VERSATILE default 0x101f1000 if ARCH_VERSATILE
default 0x101fb000 if DEBUG_NOMADIK_UART default 0x101fb000 if DEBUG_NOMADIK_UART
default 0x11002000 if DEBUG_MT8127_UART0
default 0x11006000 if DEBUG_MT6589_UART0 default 0x11006000 if DEBUG_MT6589_UART0
default 0x11009000 if DEBUG_MT8135_UART3
default 0x16000000 if ARCH_INTEGRATOR default 0x16000000 if ARCH_INTEGRATOR
default 0x18000300 if DEBUG_BCM_5301X default 0x18000300 if DEBUG_BCM_5301X
default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1 default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1
...@@ -1135,6 +1270,7 @@ config DEBUG_UART_PHYS ...@@ -1135,6 +1270,7 @@ config DEBUG_UART_PHYS
default 0x78000000 if DEBUG_CNS3XXX default 0x78000000 if DEBUG_CNS3XXX
default 0x7c0003f8 if FOOTBRIDGE default 0x7c0003f8 if FOOTBRIDGE
default 0x78000000 if DEBUG_CNS3XXX default 0x78000000 if DEBUG_CNS3XXX
default 0x80010000 if DEBUG_ASM9260_UART
default 0x80070000 if DEBUG_IMX23_UART default 0x80070000 if DEBUG_IMX23_UART
default 0x80074000 if DEBUG_IMX28_UART default 0x80074000 if DEBUG_IMX28_UART
default 0x80230000 if DEBUG_PICOXCELL_UART default 0x80230000 if DEBUG_PICOXCELL_UART
...@@ -1152,7 +1288,14 @@ config DEBUG_UART_PHYS ...@@ -1152,7 +1288,14 @@ config DEBUG_UART_PHYS
default 0xd4018000 if DEBUG_MMP_UART3 default 0xd4018000 if DEBUG_MMP_UART3
default 0xe0000000 if ARCH_SPEAR13XX default 0xe0000000 if ARCH_SPEAR13XX
default 0xe4007000 if DEBUG_HIP04_UART default 0xe4007000 if DEBUG_HIP04_UART
default 0xe6c40000 if DEBUG_RMOBILE_SCIFA0
default 0xe6c50000 if DEBUG_RMOBILE_SCIFA1
default 0xe6c80000 if DEBUG_RMOBILE_SCIFA4
default 0xe6e58000 if DEBUG_RCAR_GEN2_SCIF2
default 0xe6e60000 if DEBUG_RCAR_GEN2_SCIF0
default 0xe8008000 if DEBUG_R7S72100_SCIF2
default 0xf0000be0 if ARCH_EBSA110 default 0xf0000be0 if ARCH_EBSA110
default 0xf040ab00 if DEBUG_BRCMSTB_UART
default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE
default 0xf1012000 if ARCH_DOVE || ARCH_MV78XX0 || \ default 0xf1012000 if ARCH_DOVE || ARCH_MV78XX0 || \
ARCH_ORION5X ARCH_ORION5X
...@@ -1164,24 +1307,33 @@ config DEBUG_UART_PHYS ...@@ -1164,24 +1307,33 @@ config DEBUG_UART_PHYS
default 0xff690000 if DEBUG_RK32_UART2 default 0xff690000 if DEBUG_RK32_UART2
default 0xffc02000 if DEBUG_SOCFPGA_UART default 0xffc02000 if DEBUG_SOCFPGA_UART
default 0xffd82340 if ARCH_IOP13XX default 0xffd82340 if ARCH_IOP13XX
default 0xffe40000 if DEBUG_RCAR_GEN1_SCIF0
default 0xffe42000 if DEBUG_RCAR_GEN1_SCIF2
default 0xfff36000 if DEBUG_HIGHBANK_UART default 0xfff36000 if DEBUG_HIGHBANK_UART
default 0xfffe8600 if DEBUG_UART_BCM63XX default 0xfffe8600 if DEBUG_UART_BCM63XX
default 0xfffff700 if ARCH_IOP33X default 0xfffff700 if ARCH_IOP33X
depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
DEBUG_LL_UART_EFM32 || \ DEBUG_LL_UART_EFM32 || \
DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \ DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \ DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \
DEBUG_UART_BCM63XX DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \
DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \
DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \
DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART
config DEBUG_UART_VIRT config DEBUG_UART_VIRT
hex "Virtual base address of debug UART" hex "Virtual base address of debug UART"
default 0xe0010fe0 if ARCH_RPC default 0xe0010fe0 if ARCH_RPC
default 0xe1000000 if DEBUG_MSM_UART default 0xe1000000 if DEBUG_MSM_UART
default 0xf0000be0 if ARCH_EBSA110 default 0xf0000be0 if ARCH_EBSA110
default 0xf0010000 if DEBUG_ASM9260_UART
default 0xf01fb000 if DEBUG_NOMADIK_UART default 0xf01fb000 if DEBUG_NOMADIK_UART
default 0xf0201000 if DEBUG_BCM2835 default 0xf0201000 if DEBUG_BCM2835
default 0xf1000300 if DEBUG_BCM_5301X default 0xf1000300 if DEBUG_BCM_5301X
default 0xf1002000 if DEBUG_MT8127_UART0
default 0xf1006000 if DEBUG_MT6589_UART0 default 0xf1006000 if DEBUG_MT6589_UART0
default 0xf1009000 if DEBUG_MT8135_UART3
default 0xf11f1000 if ARCH_VERSATILE default 0xf11f1000 if ARCH_VERSATILE
default 0xf1600000 if ARCH_INTEGRATOR default 0xf1600000 if ARCH_INTEGRATOR
default 0xf1c28000 if DEBUG_SUNXI_UART0 default 0xf1c28000 if DEBUG_SUNXI_UART0
...@@ -1190,6 +1342,7 @@ config DEBUG_UART_VIRT ...@@ -1190,6 +1342,7 @@ config DEBUG_UART_VIRT
default 0xf6200000 if DEBUG_PXA_UART1 default 0xf6200000 if DEBUG_PXA_UART1
default 0xf4090000 if ARCH_LPC32XX default 0xf4090000 if ARCH_LPC32XX
default 0xf4200000 if ARCH_GEMINI default 0xf4200000 if ARCH_GEMINI
default 0xf7000000 if DEBUG_SUN9I_UART0
default 0xf7000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \ default 0xf7000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \
DEBUG_S3C2410_UART0) DEBUG_S3C2410_UART0)
default 0xf7004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \ default 0xf7004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \
...@@ -1204,6 +1357,7 @@ config DEBUG_UART_VIRT ...@@ -1204,6 +1357,7 @@ config DEBUG_UART_VIRT
default 0xfb002000 if DEBUG_CNS3XXX default 0xfb002000 if DEBUG_CNS3XXX
default 0xfb009000 if DEBUG_REALVIEW_STD_PORT default 0xfb009000 if DEBUG_REALVIEW_STD_PORT
default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT
default 0xfc40ab00 if DEBUG_BRCMSTB_UART
default 0xfcfe8600 if DEBUG_UART_BCM63XX default 0xfcfe8600 if DEBUG_UART_BCM63XX
default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
default 0xfd000000 if ARCH_SPEAR13XX default 0xfd000000 if ARCH_SPEAR13XX
...@@ -1244,12 +1398,12 @@ config DEBUG_UART_VIRT ...@@ -1244,12 +1398,12 @@ config DEBUG_UART_VIRT
depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \ DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \ DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \
DEBUG_UART_BCM63XX DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART
config DEBUG_UART_8250_SHIFT config DEBUG_UART_8250_SHIFT
int "Register offset shift for the 8250 debug UART" int "Register offset shift for the 8250 debug UART"
depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
default 0 if FOOTBRIDGE || ARCH_IOP32X default 0 if FOOTBRIDGE || ARCH_IOP32X || DEBUG_BCM_5301X
default 2 default 2
config DEBUG_UART_8250_WORD config DEBUG_UART_8250_WORD
...@@ -1260,7 +1414,8 @@ config DEBUG_UART_8250_WORD ...@@ -1260,7 +1414,8 @@ config DEBUG_UART_8250_WORD
ARCH_KEYSTONE || \ ARCH_KEYSTONE || \
DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \ DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
DEBUG_DAVINCI_DA8XX_UART2 || \ DEBUG_DAVINCI_DA8XX_UART2 || \
DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 || \
DEBUG_BRCMSTB_UART
config DEBUG_UART_8250_FLOW_CONTROL config DEBUG_UART_8250_FLOW_CONTROL
bool "Enable flow control for 8250 UART" bool "Enable flow control for 8250 UART"
......
...@@ -180,7 +180,8 @@ ...@@ -180,7 +180,8 @@
mbusc: mbus-controller@20000 { mbusc: mbus-controller@20000 {
compatible = "marvell,mbus-controller"; compatible = "marvell,mbus-controller";
reg = <0x20000 0x100>, <0x20180 0x20>; reg = <0x20000 0x100>, <0x20180 0x20>,
<0x20250 0x8>;
}; };
mpic: interrupt-controller@20000 { mpic: interrupt-controller@20000 {
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
*/ */
/dts-v1/; /dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include "armada-xp-mv78460.dtsi" #include "armada-xp-mv78460.dtsi"
/ { / {
...@@ -48,6 +49,14 @@ ...@@ -48,6 +49,14 @@
<0x00000001 0x00000000 0x00000001 0x00000000>; <0x00000001 0x00000000 0x00000001 0x00000000>;
}; };
cpus {
pm_pic {
ctrl-gpios = <&gpio0 16 GPIO_ACTIVE_LOW>,
<&gpio0 17 GPIO_ACTIVE_LOW>,
<&gpio0 18 GPIO_ACTIVE_LOW>;
};
};
soc { soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000 ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000 MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
...@@ -115,7 +124,15 @@ ...@@ -115,7 +124,15 @@
serial@12300 { serial@12300 {
status = "okay"; status = "okay";
}; };
pinctrl {
pinctrl-0 = <&pic_pins>;
pinctrl-names = "default";
pic_pins: pic-pins-0 {
marvell,pins = "mpp16", "mpp17",
"mpp18";
marvell,function = "gpio";
};
};
sata@a0000 { sata@a0000 {
nr-ports = <2>; nr-ports = <2>;
status = "okay"; status = "okay";
......
...@@ -35,6 +35,11 @@ ...@@ -35,6 +35,11 @@
}; };
internal-regs { internal-regs {
sdramc@1400 {
compatible = "marvell,armada-xp-sdram-controller";
reg = <0x1400 0x500>;
};
L2: l2-cache { L2: l2-cache {
compatible = "marvell,aurora-system-cache"; compatible = "marvell,aurora-system-cache";
reg = <0x08000 0x1000>; reg = <0x08000 0x1000>;
......
...@@ -6,8 +6,18 @@ ...@@ -6,8 +6,18 @@
/ { / {
core-module@10000000 { core-module@10000000 {
compatible = "arm,core-module-integrator"; compatible = "arm,core-module-integrator", "syscon";
reg = <0x10000000 0x200>; reg = <0x10000000 0x200>;
/* Use core module LED to indicate CPU load */
led@0c.0 {
compatible = "register-bit-led";
offset = <0x0c>;
mask = <0x01>;
label = "integrator:core_module";
linux,default-trigger = "cpu0";
default-state = "on";
};
}; };
ebi@12000000 { ebi@12000000 {
...@@ -82,5 +92,41 @@ ...@@ -82,5 +92,41 @@
reg = <0x19000000 0x1000>; reg = <0x19000000 0x1000>;
interrupts = <4>; interrupts = <4>;
}; };
syscon {
/* Debug registers mapped as syscon */
compatible = "syscon";
reg = <0x1a000000 0x10>;
led@04.0 {
compatible = "register-bit-led";
offset = <0x04>;
mask = <0x01>;
label = "integrator:green0";
linux,default-trigger = "heartbeat";
default-state = "on";
};
led@04.1 {
compatible = "register-bit-led";
offset = <0x04>;
mask = <0x02>;
label = "integrator:yellow";
default-state = "off";
};
led@04.2 {
compatible = "register-bit-led";
offset = <0x04>;
mask = <0x04>;
label = "integrator:red";
default-state = "off";
};
led@04.3 {
compatible = "register-bit-led";
offset = <0x04>;
mask = <0x08>;
label = "integrator:green1";
default-state = "off";
};
};
}; };
}; };
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#include "twl4030.dtsi" #include "twl4030.dtsi"
#include "twl4030_omap3.dtsi" #include "twl4030_omap3.dtsi"
#include <dt-bindings/input/input.h>
&mmc1 { &mmc1 {
vmmc-supply = <&vmmc1>; vmmc-supply = <&vmmc1>;
...@@ -75,6 +76,22 @@ ...@@ -75,6 +76,22 @@
ti,pullups = <0x000001>; ti,pullups = <0x000001>;
}; };
&twl_keypad {
linux,keymap = <
MATRIX_KEY(0x00, 0x01, KEY_A)
MATRIX_KEY(0x00, 0x02, KEY_B)
MATRIX_KEY(0x00, 0x03, KEY_LEFT)
MATRIX_KEY(0x01, 0x01, KEY_UP)
MATRIX_KEY(0x01, 0x02, KEY_ENTER)
MATRIX_KEY(0x01, 0x03, KEY_DOWN)
MATRIX_KEY(0x02, 0x01, KEY_RIGHT)
MATRIX_KEY(0x02, 0x02, KEY_C)
MATRIX_KEY(0x02, 0x03, KEY_D)
>;
};
&hsusb1_phy { &hsusb1_phy {
reset-gpios = <&twl_gpio 6 GPIO_ACTIVE_LOW>; reset-gpios = <&twl_gpio 6 GPIO_ACTIVE_LOW>;
}; };
......
...@@ -895,7 +895,7 @@ ...@@ -895,7 +895,7 @@
reg = <0x58002000 0x1000>; reg = <0x58002000 0x1000>;
status = "disabled"; status = "disabled";
ti,hwmods = "dss_rfbi"; ti,hwmods = "dss_rfbi";
clocks = <&dss_dss_clk>, <&dss_fck>; clocks = <&dss_dss_clk>, <&l3_div_ck>;
clock-names = "fck", "ick"; clock-names = "fck", "ick";
}; };
......
...@@ -1018,14 +1018,6 @@ ...@@ -1018,14 +1018,6 @@
reg = <0x1120>; reg = <0x1120>;
}; };
dss_fck: dss_fck {
#clock-cells = <0>;
compatible = "ti,gate-clock";
clocks = <&l3_div_ck>;
ti,bit-shift = <1>;
reg = <0x1120>;
};
fdif_fck: fdif_fck { fdif_fck: fdif_fck {
#clock-cells = <0>; #clock-cells = <0>;
compatible = "ti,divider-clock"; compatible = "ti,divider-clock";
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/mfd/dbx500-prcmu.h> #include <dt-bindings/mfd/dbx500-prcmu.h>
#include <dt-bindings/arm/ux500_pm_domains.h>
#include "skeleton.dtsi" #include "skeleton.dtsi"
/ { / {
...@@ -43,6 +44,10 @@ ...@@ -43,6 +44,10 @@
interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
}; };
pm_domains: pm_domains0 {
compatible = "stericsson,ux500-pm-domains";
#power-domain-cells = <1>;
};
clocks { clocks {
compatible = "stericsson,u8500-clks"; compatible = "stericsson,u8500-clks";
...@@ -636,6 +641,7 @@ ...@@ -636,6 +641,7 @@
clock-frequency = <400000>; clock-frequency = <400000>;
clocks = <&prcc_kclk 3 3>, <&prcc_pclk 3 3>; clocks = <&prcc_kclk 3 3>, <&prcc_pclk 3 3>;
clock-names = "i2cclk", "apb_pclk"; clock-names = "i2cclk", "apb_pclk";
power-domains = <&pm_domains DOMAIN_VAPE>;
}; };
i2c@80122000 { i2c@80122000 {
...@@ -651,6 +657,7 @@ ...@@ -651,6 +657,7 @@
clocks = <&prcc_kclk 1 2>, <&prcc_pclk 1 2>; clocks = <&prcc_kclk 1 2>, <&prcc_pclk 1 2>;
clock-names = "i2cclk", "apb_pclk"; clock-names = "i2cclk", "apb_pclk";
power-domains = <&pm_domains DOMAIN_VAPE>;
}; };
i2c@80128000 { i2c@80128000 {
...@@ -666,6 +673,7 @@ ...@@ -666,6 +673,7 @@
clocks = <&prcc_kclk 1 6>, <&prcc_pclk 1 6>; clocks = <&prcc_kclk 1 6>, <&prcc_pclk 1 6>;
clock-names = "i2cclk", "apb_pclk"; clock-names = "i2cclk", "apb_pclk";
power-domains = <&pm_domains DOMAIN_VAPE>;
}; };
i2c@80110000 { i2c@80110000 {
...@@ -681,6 +689,7 @@ ...@@ -681,6 +689,7 @@
clocks = <&prcc_kclk 2 0>, <&prcc_pclk 2 0>; clocks = <&prcc_kclk 2 0>, <&prcc_pclk 2 0>;
clock-names = "i2cclk", "apb_pclk"; clock-names = "i2cclk", "apb_pclk";
power-domains = <&pm_domains DOMAIN_VAPE>;
}; };
i2c@8012a000 { i2c@8012a000 {
...@@ -696,6 +705,7 @@ ...@@ -696,6 +705,7 @@
clocks = <&prcc_kclk 1 9>, <&prcc_pclk 1 10>; clocks = <&prcc_kclk 1 9>, <&prcc_pclk 1 10>;
clock-names = "i2cclk", "apb_pclk"; clock-names = "i2cclk", "apb_pclk";
power-domains = <&pm_domains DOMAIN_VAPE>;
}; };
ssp@80002000 { ssp@80002000 {
...@@ -709,6 +719,7 @@ ...@@ -709,6 +719,7 @@
dmas = <&dma 8 0 0x2>, /* Logical - DevToMem */ dmas = <&dma 8 0 0x2>, /* Logical - DevToMem */
<&dma 8 0 0x0>; /* Logical - MemToDev */ <&dma 8 0 0x0>; /* Logical - MemToDev */
dma-names = "rx", "tx"; dma-names = "rx", "tx";
power-domains = <&pm_domains DOMAIN_VAPE>;
}; };
ssp@80003000 { ssp@80003000 {
...@@ -722,6 +733,7 @@ ...@@ -722,6 +733,7 @@
dmas = <&dma 9 0 0x2>, /* Logical - DevToMem */ dmas = <&dma 9 0 0x2>, /* Logical - DevToMem */
<&dma 9 0 0x0>; /* Logical - MemToDev */ <&dma 9 0 0x0>; /* Logical - MemToDev */
dma-names = "rx", "tx"; dma-names = "rx", "tx";
power-domains = <&pm_domains DOMAIN_VAPE>;
}; };
spi@8011a000 { spi@8011a000 {
...@@ -736,6 +748,7 @@ ...@@ -736,6 +748,7 @@
dmas = <&dma 0 0 0x2>, /* Logical - DevToMem */ dmas = <&dma 0 0 0x2>, /* Logical - DevToMem */
<&dma 0 0 0x0>; /* Logical - MemToDev */ <&dma 0 0 0x0>; /* Logical - MemToDev */
dma-names = "rx", "tx"; dma-names = "rx", "tx";
power-domains = <&pm_domains DOMAIN_VAPE>;
}; };
spi@80112000 { spi@80112000 {
...@@ -750,6 +763,7 @@ ...@@ -750,6 +763,7 @@
dmas = <&dma 35 0 0x2>, /* Logical - DevToMem */ dmas = <&dma 35 0 0x2>, /* Logical - DevToMem */
<&dma 35 0 0x0>; /* Logical - MemToDev */ <&dma 35 0 0x0>; /* Logical - MemToDev */
dma-names = "rx", "tx"; dma-names = "rx", "tx";
power-domains = <&pm_domains DOMAIN_VAPE>;
}; };
spi@80111000 { spi@80111000 {
...@@ -764,6 +778,7 @@ ...@@ -764,6 +778,7 @@
dmas = <&dma 33 0 0x2>, /* Logical - DevToMem */ dmas = <&dma 33 0 0x2>, /* Logical - DevToMem */
<&dma 33 0 0x0>; /* Logical - MemToDev */ <&dma 33 0 0x0>; /* Logical - MemToDev */
dma-names = "rx", "tx"; dma-names = "rx", "tx";
power-domains = <&pm_domains DOMAIN_VAPE>;
}; };
spi@80129000 { spi@80129000 {
...@@ -778,6 +793,7 @@ ...@@ -778,6 +793,7 @@
dmas = <&dma 40 0 0x2>, /* Logical - DevToMem */ dmas = <&dma 40 0 0x2>, /* Logical - DevToMem */
<&dma 40 0 0x0>; /* Logical - MemToDev */ <&dma 40 0 0x0>; /* Logical - MemToDev */
dma-names = "rx", "tx"; dma-names = "rx", "tx";
power-domains = <&pm_domains DOMAIN_VAPE>;
}; };
uart@80120000 { uart@80120000 {
...@@ -836,6 +852,7 @@ ...@@ -836,6 +852,7 @@
clocks = <&prcc_kclk 1 5>, <&prcc_pclk 1 5>; clocks = <&prcc_kclk 1 5>, <&prcc_pclk 1 5>;
clock-names = "sdi", "apb_pclk"; clock-names = "sdi", "apb_pclk";
power-domains = <&pm_domains DOMAIN_VAPE>;
status = "disabled"; status = "disabled";
}; };
...@@ -851,6 +868,7 @@ ...@@ -851,6 +868,7 @@
clocks = <&prcc_kclk 2 4>, <&prcc_pclk 2 6>; clocks = <&prcc_kclk 2 4>, <&prcc_pclk 2 6>;
clock-names = "sdi", "apb_pclk"; clock-names = "sdi", "apb_pclk";
power-domains = <&pm_domains DOMAIN_VAPE>;
status = "disabled"; status = "disabled";
}; };
...@@ -866,6 +884,7 @@ ...@@ -866,6 +884,7 @@
clocks = <&prcc_kclk 3 4>, <&prcc_pclk 3 4>; clocks = <&prcc_kclk 3 4>, <&prcc_pclk 3 4>;
clock-names = "sdi", "apb_pclk"; clock-names = "sdi", "apb_pclk";
power-domains = <&pm_domains DOMAIN_VAPE>;
status = "disabled"; status = "disabled";
}; };
...@@ -881,6 +900,7 @@ ...@@ -881,6 +900,7 @@
clocks = <&prcc_kclk 2 5>, <&prcc_pclk 2 7>; clocks = <&prcc_kclk 2 5>, <&prcc_pclk 2 7>;
clock-names = "sdi", "apb_pclk"; clock-names = "sdi", "apb_pclk";
power-domains = <&pm_domains DOMAIN_VAPE>;
status = "disabled"; status = "disabled";
}; };
...@@ -896,6 +916,7 @@ ...@@ -896,6 +916,7 @@
clocks = <&prcc_kclk 2 2>, <&prcc_pclk 2 4>; clocks = <&prcc_kclk 2 2>, <&prcc_pclk 2 4>;
clock-names = "sdi", "apb_pclk"; clock-names = "sdi", "apb_pclk";
power-domains = <&pm_domains DOMAIN_VAPE>;
status = "disabled"; status = "disabled";
}; };
...@@ -911,6 +932,7 @@ ...@@ -911,6 +932,7 @@
clocks = <&prcc_kclk 3 7>, <&prcc_pclk 3 7>; clocks = <&prcc_kclk 3 7>, <&prcc_pclk 3 7>;
clock-names = "sdi", "apb_pclk"; clock-names = "sdi", "apb_pclk";
power-domains = <&pm_domains DOMAIN_VAPE>;
status = "disabled"; status = "disabled";
}; };
......
...@@ -25,7 +25,8 @@ CONFIG_MODULE_UNLOAD=y ...@@ -25,7 +25,8 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_BCM=y CONFIG_ARCH_BCM=y
CONFIG_ARCH_BCM_MOBILE=y CONFIG_ARCH_BCM_21664=y
CONFIG_ARCH_BCM_281XX=y
CONFIG_ARM_THUMBEE=y CONFIG_ARM_THUMBEE=y
CONFIG_SMP=y CONFIG_SMP=y
CONFIG_PREEMPT=y CONFIG_PREEMPT=y
......
...@@ -8,6 +8,9 @@ CONFIG_BLK_DEV_INITRD=y ...@@ -8,6 +8,9 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_MODULES=y CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_MULTI_V4T=y
CONFIG_ARCH_MULTI_V5=y
# CONFIG_ARCH_MULTI_V7 is not set
CONFIG_ARCH_INTEGRATOR=y CONFIG_ARCH_INTEGRATOR=y
CONFIG_ARCH_INTEGRATOR_AP=y CONFIG_ARCH_INTEGRATOR_AP=y
CONFIG_ARCH_INTEGRATOR_CP=y CONFIG_ARCH_INTEGRATOR_CP=y
......
...@@ -28,7 +28,7 @@ struct firmware_ops { ...@@ -28,7 +28,7 @@ struct firmware_ops {
/* /*
* Enters CPU idle mode * Enters CPU idle mode
*/ */
int (*do_idle)(void); int (*do_idle)(unsigned long mode);
/* /*
* Sets boot address of specified physical CPU * Sets boot address of specified physical CPU
*/ */
...@@ -41,6 +41,14 @@ struct firmware_ops { ...@@ -41,6 +41,14 @@ struct firmware_ops {
* Initializes L2 cache * Initializes L2 cache
*/ */
int (*l2x0_init)(void); int (*l2x0_init)(void);
/*
* Enter system-wide suspend.
*/
int (*suspend)(void);
/*
* Restore state of privileged hardware after system-wide suspend.
*/
int (*resume)(void);
}; };
/* Global pointer for current firmware_ops structure, can't be NULL. */ /* Global pointer for current firmware_ops structure, can't be NULL. */
......
/* Debugging macro include header
*
* Copyright (C) 1994-1999 Russell King
* Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
* Modified for ASM9260 by Oleksij Remepl <linux@rempel-privat.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
.macro addruart, rp, rv, tmp
ldr \rp, = CONFIG_DEBUG_UART_PHYS
ldr \rv, = CONFIG_DEBUG_UART_VIRT
.endm
.macro waituart,rd,rx
.endm
.macro senduart,rd,rx
str \rd, [\rx, #0x50] @ TXDATA
.endm
.macro busyuart,rd,rx
1002: ldr \rd, [\rx, #0x60] @ STAT
tst \rd, #1 << 27 @ TXEMPTY
beq 1002b @ wait until transmit done
.endm
/*
* Renesas SCIF(A) debugging macro include header
*
* Based on r8a7790.S
*
* Copyright (C) 2012-2013 Renesas Electronics Corporation
* Copyright (C) 1994-1999 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#define SCIF_PHYS CONFIG_DEBUG_UART_PHYS
#define SCIF_VIRT ((SCIF_PHYS & 0x00ffffff) | 0xfd000000)
#if CONFIG_DEBUG_UART_PHYS < 0xe6e00000
/* SCIFA */
#define FTDR 0x20
#define FSR 0x14
#else
/* SCIF */
#define FTDR 0x0c
#define FSR 0x10
#endif
#define TDFE (1 << 5)
#define TEND (1 << 6)
.macro addruart, rp, rv, tmp
ldr \rp, =SCIF_PHYS
ldr \rv, =SCIF_VIRT
.endm
.macro waituart, rd, rx
1001: ldrh \rd, [\rx, #FSR]
tst \rd, #TDFE
beq 1001b
.endm
.macro senduart, rd, rx
strb \rd, [\rx, #FTDR]
ldrh \rd, [\rx, #FSR]
bic \rd, \rd, #TEND
strh \rd, [\rx, #FSR]
.endm
.macro busyuart, rd, rx
1001: ldrh \rd, [\rx, #FSR]
tst \rd, #TEND
beq 1001b
.endm
/* arch/arm/mach-sa1100/include/mach/debug-macro.S /* arch/arm/include/debug/sa1100.S
* *
* Debugging macro include header * Debugging macro include header
* *
...@@ -10,7 +10,13 @@ ...@@ -10,7 +10,13 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
*/ */
#include <mach/hardware.h>
#define UTCR3 0x0c
#define UTDR 0x14
#define UTSR1 0x20
#define UTCR3_TXE 0x00000002 /* Transmit Enable */
#define UTSR1_TBY 0x00000001 /* Transmitter BusY (read) */
#define UTSR1_TNF 0x00000004 /* Transmit FIFO Not Full (read) */
.macro addruart, rp, rv, tmp .macro addruart, rp, rv, tmp
mrc p15, 0, \rp, c1, c0 mrc p15, 0, \rp, c1, c0
......
config MACH_ASM9260
bool "Alphascale ASM9260"
depends on ARCH_MULTI_V5
select CPU_ARM926T
help
Support for Alphascale ASM9260 based platform.
...@@ -5,8 +5,56 @@ menuconfig ARCH_BCM ...@@ -5,8 +5,56 @@ menuconfig ARCH_BCM
if ARCH_BCM if ARCH_BCM
comment "IPROC architected SoCs"
config ARCH_BCM_IPROC
bool
select ARM_GIC
select CACHE_L2X0
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
select ARM_GLOBAL_TIMER
select CLKSRC_MMIO
select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
select PINCTRL
help
This enables support for systems based on Broadcom IPROC architected SoCs.
The IPROC complex contains one or more ARM CPUs along with common
core periperals. Application specific SoCs are created by adding a
uArchitecture containing peripherals outside of the IPROC complex.
Currently supported SoCs are Cygnus.
config ARCH_BCM_CYGNUS
bool "Broadcom Cygnus Support" if ARCH_MULTI_V7
select ARCH_BCM_IPROC
help
Enable support for the Cygnus family,
which includes the following variants:
BCM11300, BCM11320, BCM11350, BCM11360,
BCM58300, BCM58302, BCM58303, BCM58305.
config ARCH_BCM_5301X
bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
select ARCH_BCM_IPROC
help
Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
This is a network SoC line mostly used in home routers and
wifi access points, it's internal name is Northstar.
This inclused the following SoC: BCM53010, BCM53011, BCM53012,
BCM53014, BCM53015, BCM53016, BCM53017, BCM53018, BCM4707,
BCM4708 and BCM4709.
Do not confuse this with the BCM4760 which is a totally
different SoC or with the older BCM47XX and BCM53XX based
network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx
comment "KONA architected SoCs"
config ARCH_BCM_MOBILE config ARCH_BCM_MOBILE
bool "Broadcom Mobile SoC Support" if ARCH_MULTI_V7 bool
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select ARM_ERRATA_754322 select ARM_ERRATA_754322
select ARM_ERRATA_775420 select ARM_ERRATA_775420
...@@ -15,16 +63,13 @@ config ARCH_BCM_MOBILE ...@@ -15,16 +63,13 @@ config ARCH_BCM_MOBILE
select TICK_ONESHOT select TICK_ONESHOT
select HAVE_ARM_ARCH_TIMER select HAVE_ARM_ARCH_TIMER
select PINCTRL select PINCTRL
select ARCH_BCM_MOBILE_SMP if SMP
help help
This enables support for systems based on Broadcom mobile SoCs. This enables support for systems based on Broadcom mobile SoCs.
if ARCH_BCM_MOBILE
menu "Broadcom Mobile SoC Selection"
config ARCH_BCM_281XX config ARCH_BCM_281XX
bool "Broadcom BCM281XX SoC family" bool "Broadcom BCM281XX SoC family"
default y select ARCH_BCM_MOBILE
select HAVE_SMP select HAVE_SMP
help help
Enable support for the BCM281XX family, which includes Enable support for the BCM281XX family, which includes
...@@ -33,7 +78,7 @@ config ARCH_BCM_281XX ...@@ -33,7 +78,7 @@ config ARCH_BCM_281XX
config ARCH_BCM_21664 config ARCH_BCM_21664
bool "Broadcom BCM21664 SoC family" bool "Broadcom BCM21664 SoC family"
default y select ARCH_BCM_MOBILE
select HAVE_SMP select HAVE_SMP
help help
Enable support for the BCM21664 family, which includes Enable support for the BCM21664 family, which includes
...@@ -41,19 +86,18 @@ config ARCH_BCM_21664 ...@@ -41,19 +86,18 @@ config ARCH_BCM_21664
config ARCH_BCM_MOBILE_L2_CACHE config ARCH_BCM_MOBILE_L2_CACHE
bool "Broadcom mobile SoC level 2 cache support" bool "Broadcom mobile SoC level 2 cache support"
depends on (ARCH_BCM_281XX || ARCH_BCM_21664) depends on ARCH_BCM_MOBILE
default y default y
select CACHE_L2X0 select CACHE_L2X0
select ARCH_BCM_MOBILE_SMC select ARCH_BCM_MOBILE_SMC
config ARCH_BCM_MOBILE_SMC config ARCH_BCM_MOBILE_SMC
bool bool
depends on ARCH_BCM_281XX || ARCH_BCM_21664 depends on ARCH_BCM_MOBILE
config ARCH_BCM_MOBILE_SMP config ARCH_BCM_MOBILE_SMP
bool "Broadcom mobile SoC SMP support" bool
depends on (ARCH_BCM_281XX || ARCH_BCM_21664) && SMP depends on ARCH_BCM_MOBILE
default y
select HAVE_ARM_SCU select HAVE_ARM_SCU
select ARM_ERRATA_764369 select ARM_ERRATA_764369
help help
...@@ -61,9 +105,7 @@ config ARCH_BCM_MOBILE_SMP ...@@ -61,9 +105,7 @@ config ARCH_BCM_MOBILE_SMP
Provided as an option so SMP support for SoCs of this type Provided as an option so SMP support for SoCs of this type
can be disabled for an SMP-enabled kernel. can be disabled for an SMP-enabled kernel.
endmenu comment "Other Architectures"
endif
config ARCH_BCM2835 config ARCH_BCM2835
bool "Broadcom BCM2835 family" if ARCH_MULTI_V6 bool "Broadcom BCM2835 family" if ARCH_MULTI_V6
...@@ -78,27 +120,6 @@ config ARCH_BCM2835 ...@@ -78,27 +120,6 @@ config ARCH_BCM2835
This enables support for the Broadcom BCM2835 SoC. This SoC is This enables support for the Broadcom BCM2835 SoC. This SoC is
used in the Raspberry Pi and Roku 2 devices. used in the Raspberry Pi and Roku 2 devices.
config ARCH_BCM_5301X
bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
select ARM_GIC
select CACHE_L2X0
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
select ARM_GLOBAL_TIMER
select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
help
Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
This is a network SoC line mostly used in home routers and
wifi access points, it's internal name is Northstar.
This inclused the following SoC: BCM53010, BCM53011, BCM53012,
BCM53014, BCM53015, BCM53016, BCM53017, BCM53018, BCM4707,
BCM4708 and BCM4709.
Do not confuse this with the BCM4760 which is a totally
different SoC or with the older BCM47XX and BCM53XX based
network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx
config ARCH_BCM_63XX config ARCH_BCM_63XX
bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7 bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7
depends on MMU depends on MMU
...@@ -118,10 +139,7 @@ config ARCH_BCM_63XX ...@@ -118,10 +139,7 @@ config ARCH_BCM_63XX
config ARCH_BRCMSTB config ARCH_BRCMSTB
bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7 bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7
depends on MMU
select ARM_GIC select ARM_GIC
select MIGHT_HAVE_PCI
select HAVE_SMP
select HAVE_ARM_ARCH_TIMER select HAVE_ARM_ARCH_TIMER
select BRCMSTB_GISB_ARB select BRCMSTB_GISB_ARB
select BRCMSTB_L2_IRQ select BRCMSTB_L2_IRQ
......
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# Cygnus
obj-$(CONFIG_ARCH_BCM_CYGNUS) += bcm_cygnus.o
# BCM281XX # BCM281XX
obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o
...@@ -38,5 +41,7 @@ obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o ...@@ -38,5 +41,7 @@ obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
obj-$(CONFIG_ARCH_BCM_63XX) := bcm63xx.o obj-$(CONFIG_ARCH_BCM_63XX) := bcm63xx.o
ifeq ($(CONFIG_ARCH_BRCMSTB),y) ifeq ($(CONFIG_ARCH_BRCMSTB),y)
CFLAGS_platsmp-brcmstb.o += -march=armv7-a
obj-y += brcmstb.o obj-y += brcmstb.o
obj-$(CONFIG_SMP) += headsmp-brcmstb.o platsmp-brcmstb.o
endif endif
/*
* Copyright (C) 2014 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <asm/mach/arch.h>
static const char const *bcm_cygnus_dt_compat[] = {
"brcm,cygnus",
NULL,
};
DT_MACHINE_START(BCM_CYGNUS_DT, "Broadcom Cygnus SoC")
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
.dt_compat = bcm_cygnus_dt_compat,
MACHINE_END
/*
* Copyright (C) 2013-2014 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __BRCMSTB_H__
#define __BRCMSTB_H__
void brcmstb_secondary_startup(void);
#endif /* __BRCMSTB_H__ */
/*
* SMP boot code for secondary CPUs
* Based on arch/arm/mach-tegra/headsmp.S
*
* Copyright (C) 2010 NVIDIA, Inc.
* Copyright (C) 2013-2014 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <asm/assembler.h>
#include <linux/linkage.h>
#include <linux/init.h>
.section ".text.head", "ax"
ENTRY(brcmstb_secondary_startup)
/*
* Ensure CPU is in a sane state by disabling all IRQs and switching
* into SVC mode.
*/
setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r0
bl v7_invalidate_l1
b secondary_startup
ENDPROC(brcmstb_secondary_startup)
/*
* Broadcom STB CPU SMP and hotplug support for ARM
*
* Copyright (C) 2013-2014 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/printk.h>
#include <linux/regmap.h>
#include <linux/smp.h>
#include <linux/mfd/syscon.h>
#include <asm/cacheflush.h>
#include <asm/cp15.h>
#include <asm/mach-types.h>
#include <asm/smp_plat.h>
#include "brcmstb.h"
enum {
ZONE_MAN_CLKEN_MASK = BIT(0),
ZONE_MAN_RESET_CNTL_MASK = BIT(1),
ZONE_MAN_MEM_PWR_MASK = BIT(4),
ZONE_RESERVED_1_MASK = BIT(5),
ZONE_MAN_ISO_CNTL_MASK = BIT(6),
ZONE_MANUAL_CONTROL_MASK = BIT(7),
ZONE_PWR_DN_REQ_MASK = BIT(9),
ZONE_PWR_UP_REQ_MASK = BIT(10),
ZONE_BLK_RST_ASSERT_MASK = BIT(12),
ZONE_PWR_OFF_STATE_MASK = BIT(25),
ZONE_PWR_ON_STATE_MASK = BIT(26),
ZONE_DPG_PWR_STATE_MASK = BIT(28),
ZONE_MEM_PWR_STATE_MASK = BIT(29),
ZONE_RESET_STATE_MASK = BIT(31),
CPU0_PWR_ZONE_CTRL_REG = 1,
CPU_RESET_CONFIG_REG = 2,
};
static void __iomem *cpubiuctrl_block;
static void __iomem *hif_cont_block;
static u32 cpu0_pwr_zone_ctrl_reg;
static u32 cpu_rst_cfg_reg;
static u32 hif_cont_reg;
#ifdef CONFIG_HOTPLUG_CPU
/*
* We must quiesce a dying CPU before it can be killed by the boot CPU. Because
* one or more cache may be disabled, we must flush to ensure coherency. We
* cannot use traditionl completion structures or spinlocks as they rely on
* coherency.
*/
static DEFINE_PER_CPU_ALIGNED(int, per_cpu_sw_state);
static int per_cpu_sw_state_rd(u32 cpu)
{
sync_cache_r(SHIFT_PERCPU_PTR(&per_cpu_sw_state, per_cpu_offset(cpu)));
return per_cpu(per_cpu_sw_state, cpu);
}
static void per_cpu_sw_state_wr(u32 cpu, int val)
{
dmb();
per_cpu(per_cpu_sw_state, cpu) = val;
sync_cache_w(SHIFT_PERCPU_PTR(&per_cpu_sw_state, per_cpu_offset(cpu)));
}
#else
static inline void per_cpu_sw_state_wr(u32 cpu, int val) { }
#endif
static void __iomem *pwr_ctrl_get_base(u32 cpu)
{
void __iomem *base = cpubiuctrl_block + cpu0_pwr_zone_ctrl_reg;
base += (cpu_logical_map(cpu) * 4);
return base;
}
static u32 pwr_ctrl_rd(u32 cpu)
{
void __iomem *base = pwr_ctrl_get_base(cpu);
return readl_relaxed(base);
}
static void pwr_ctrl_wr(u32 cpu, u32 val)
{
void __iomem *base = pwr_ctrl_get_base(cpu);
writel(val, base);
}
static void cpu_rst_cfg_set(u32 cpu, int set)
{
u32 val;
val = readl_relaxed(cpubiuctrl_block + cpu_rst_cfg_reg);
if (set)
val |= BIT(cpu_logical_map(cpu));
else
val &= ~BIT(cpu_logical_map(cpu));
writel_relaxed(val, cpubiuctrl_block + cpu_rst_cfg_reg);
}
static void cpu_set_boot_addr(u32 cpu, unsigned long boot_addr)
{
const int reg_ofs = cpu_logical_map(cpu) * 8;
writel_relaxed(0, hif_cont_block + hif_cont_reg + reg_ofs);
writel_relaxed(boot_addr, hif_cont_block + hif_cont_reg + 4 + reg_ofs);
}
static void brcmstb_cpu_boot(u32 cpu)
{
/* Mark this CPU as "up" */
per_cpu_sw_state_wr(cpu, 1);
/*
* Set the reset vector to point to the secondary_startup
* routine
*/
cpu_set_boot_addr(cpu, virt_to_phys(brcmstb_secondary_startup));
/* Unhalt the cpu */
cpu_rst_cfg_set(cpu, 0);
}
static void brcmstb_cpu_power_on(u32 cpu)
{
/*
* The secondary cores power was cut, so we must go through
* power-on initialization.
*/
u32 tmp;
/* Request zone power up */
pwr_ctrl_wr(cpu, ZONE_PWR_UP_REQ_MASK);
/* Wait for the power up FSM to complete */
do {
tmp = pwr_ctrl_rd(cpu);
} while (!(tmp & ZONE_PWR_ON_STATE_MASK));
}
static int brcmstb_cpu_get_power_state(u32 cpu)
{
int tmp = pwr_ctrl_rd(cpu);
return (tmp & ZONE_RESET_STATE_MASK) ? 0 : 1;
}
#ifdef CONFIG_HOTPLUG_CPU
static void brcmstb_cpu_die(u32 cpu)
{
v7_exit_coherency_flush(all);
per_cpu_sw_state_wr(cpu, 0);
/* Sit and wait to die */
wfi();
/* We should never get here... */
while (1)
;
}
static int brcmstb_cpu_kill(u32 cpu)
{
u32 tmp;
while (per_cpu_sw_state_rd(cpu))
;
/* Program zone reset */
pwr_ctrl_wr(cpu, ZONE_RESET_STATE_MASK | ZONE_BLK_RST_ASSERT_MASK |
ZONE_PWR_DN_REQ_MASK);
/* Verify zone reset */
tmp = pwr_ctrl_rd(cpu);
if (!(tmp & ZONE_RESET_STATE_MASK))
pr_err("%s: Zone reset bit for CPU %d not asserted!\n",
__func__, cpu);
/* Wait for power down */
do {
tmp = pwr_ctrl_rd(cpu);
} while (!(tmp & ZONE_PWR_OFF_STATE_MASK));
/* Flush pipeline before resetting CPU */
mb();
/* Assert reset on the CPU */
cpu_rst_cfg_set(cpu, 1);
return 1;
}
#endif /* CONFIG_HOTPLUG_CPU */
static int __init setup_hifcpubiuctrl_regs(struct device_node *np)
{
int rc = 0;
char *name;
struct device_node *syscon_np = NULL;
name = "syscon-cpu";
syscon_np = of_parse_phandle(np, name, 0);
if (!syscon_np) {
pr_err("can't find phandle %s\n", name);
rc = -EINVAL;
goto cleanup;
}
cpubiuctrl_block = of_iomap(syscon_np, 0);
if (!cpubiuctrl_block) {
pr_err("iomap failed for cpubiuctrl_block\n");
rc = -EINVAL;
goto cleanup;
}
rc = of_property_read_u32_index(np, name, CPU0_PWR_ZONE_CTRL_REG,
&cpu0_pwr_zone_ctrl_reg);
if (rc) {
pr_err("failed to read 1st entry from %s property (%d)\n", name,
rc);
rc = -EINVAL;
goto cleanup;
}
rc = of_property_read_u32_index(np, name, CPU_RESET_CONFIG_REG,
&cpu_rst_cfg_reg);
if (rc) {
pr_err("failed to read 2nd entry from %s property (%d)\n", name,
rc);
rc = -EINVAL;
goto cleanup;
}
cleanup:
of_node_put(syscon_np);
return rc;
}
static int __init setup_hifcont_regs(struct device_node *np)
{
int rc = 0;
char *name;
struct device_node *syscon_np = NULL;
name = "syscon-cont";
syscon_np = of_parse_phandle(np, name, 0);
if (!syscon_np) {
pr_err("can't find phandle %s\n", name);
rc = -EINVAL;
goto cleanup;
}
hif_cont_block = of_iomap(syscon_np, 0);
if (!hif_cont_block) {
pr_err("iomap failed for hif_cont_block\n");
rc = -EINVAL;
goto cleanup;
}
/* Offset is at top of hif_cont_block */
hif_cont_reg = 0;
cleanup:
of_node_put(syscon_np);
return rc;
}
static void __init brcmstb_cpu_ctrl_setup(unsigned int max_cpus)
{
int rc;
struct device_node *np;
char *name;
name = "brcm,brcmstb-smpboot";
np = of_find_compatible_node(NULL, NULL, name);
if (!np) {
pr_err("can't find compatible node %s\n", name);
return;
}
rc = setup_hifcpubiuctrl_regs(np);
if (rc)
return;
rc = setup_hifcont_regs(np);
if (rc)
return;
}
static int brcmstb_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
/* Missing the brcm,brcmstb-smpboot DT node? */
if (!cpubiuctrl_block || !hif_cont_block)
return -ENODEV;
/* Bring up power to the core if necessary */
if (brcmstb_cpu_get_power_state(cpu) == 0)
brcmstb_cpu_power_on(cpu);
brcmstb_cpu_boot(cpu);
return 0;
}
static struct smp_operations brcmstb_smp_ops __initdata = {
.smp_prepare_cpus = brcmstb_cpu_ctrl_setup,
.smp_boot_secondary = brcmstb_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_kill = brcmstb_cpu_kill,
.cpu_die = brcmstb_cpu_die,
#endif
};
CPU_METHOD_OF_DECLARE(brcmstb_smp, "brcm,brahma-b15", &brcmstb_smp_ops);
menuconfig ARCH_BERLIN menuconfig ARCH_BERLIN
bool "Marvell Berlin SoCs" if ARCH_MULTI_V7 bool "Marvell Berlin SoCs" if ARCH_MULTI_V7
select ARCH_HAS_RESET_CONTROLLER
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select ARM_GIC select ARM_GIC
select GENERIC_IRQ_CHIP
select DW_APB_ICTL select DW_APB_ICTL
select DW_APB_TIMER_OF select DW_APB_TIMER_OF
select GENERIC_IRQ_CHIP
select PINCTRL select PINCTRL
if ARCH_BERLIN if ARCH_BERLIN
......
...@@ -24,6 +24,7 @@ menuconfig ARCH_EXYNOS ...@@ -24,6 +24,7 @@ menuconfig ARCH_EXYNOS
select PM_GENERIC_DOMAINS if PM_RUNTIME select PM_GENERIC_DOMAINS if PM_RUNTIME
select S5P_DEV_MFC select S5P_DEV_MFC
select SRAM select SRAM
select MFD_SYSCON
help help
Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5) Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
...@@ -75,6 +76,11 @@ config SOC_EXYNOS4412 ...@@ -75,6 +76,11 @@ config SOC_EXYNOS4412
default y default y
depends on ARCH_EXYNOS4 depends on ARCH_EXYNOS4
config SOC_EXYNOS4415
bool "SAMSUNG EXYNOS4415"
default y
depends on ARCH_EXYNOS4
config SOC_EXYNOS5250 config SOC_EXYNOS5250
bool "SAMSUNG EXYNOS5250" bool "SAMSUNG EXYNOS5250"
default y default y
...@@ -123,4 +129,9 @@ config EXYNOS5420_MCPM ...@@ -123,4 +129,9 @@ config EXYNOS5420_MCPM
This is needed to provide CPU and cluster power management This is needed to provide CPU and cluster power management
on Exynos5420 implementing big.LITTLE. on Exynos5420 implementing big.LITTLE.
config EXYNOS_CPU_SUSPEND
bool
select ARM_CPU_SUSPEND
default PM_SLEEP || ARM_EXYNOS_CPUIDLE
endif endif
...@@ -11,13 +11,15 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include -I$(srctree) ...@@ -11,13 +11,15 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include -I$(srctree)
obj-$(CONFIG_ARCH_EXYNOS) += exynos.o pmu.o exynos-smc.o firmware.o obj-$(CONFIG_ARCH_EXYNOS) += exynos.o pmu.o exynos-smc.o firmware.o
obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o obj-$(CONFIG_EXYNOS_CPU_SUSPEND) += pm.o sleep.o
obj-$(CONFIG_PM_SLEEP) += suspend.o
obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o
plus_sec := $(call as-instr,.arch_extension sec,+sec) plus_sec := $(call as-instr,.arch_extension sec,+sec)
AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec) AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec)
AFLAGS_sleep.o :=-Wa,-march=armv7-a$(plus_sec)
obj-$(CONFIG_EXYNOS5420_MCPM) += mcpm-exynos.o obj-$(CONFIG_EXYNOS5420_MCPM) += mcpm-exynos.o
CFLAGS_mcpm-exynos.o += -march=armv7-a CFLAGS_mcpm-exynos.o += -march=armv7-a
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H #ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H
#define __ARCH_ARM_MACH_EXYNOS_COMMON_H #define __ARCH_ARM_MACH_EXYNOS_COMMON_H
#include <linux/reboot.h>
#include <linux/of.h> #include <linux/of.h>
#define EXYNOS3250_SOC_ID 0xE3472000 #define EXYNOS3250_SOC_ID 0xE3472000
...@@ -111,11 +110,19 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK) ...@@ -111,11 +110,19 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
#define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \ #define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \
soc_is_exynos5420() || soc_is_exynos5800()) soc_is_exynos5420() || soc_is_exynos5800())
extern u32 cp15_save_diag;
extern u32 cp15_save_power;
extern void __iomem *sysram_ns_base_addr; extern void __iomem *sysram_ns_base_addr;
extern void __iomem *sysram_base_addr; extern void __iomem *sysram_base_addr;
extern void __iomem *pmu_base_addr; extern void __iomem *pmu_base_addr;
void exynos_sysram_init(void); void exynos_sysram_init(void);
enum {
FW_DO_IDLE_SLEEP,
FW_DO_IDLE_AFTR,
};
void exynos_firmware_init(void); void exynos_firmware_init(void);
extern u32 exynos_get_eint_wake_mask(void); extern u32 exynos_get_eint_wake_mask(void);
...@@ -127,32 +134,20 @@ static inline void exynos_pm_init(void) {} ...@@ -127,32 +134,20 @@ static inline void exynos_pm_init(void) {}
#endif #endif
extern void exynos_cpu_resume(void); extern void exynos_cpu_resume(void);
extern void exynos_cpu_resume_ns(void);
extern struct smp_operations exynos_smp_ops; extern struct smp_operations exynos_smp_ops;
/* PMU(Power Management Unit) support */
#define PMU_TABLE_END (-1U)
enum sys_powerdown {
SYS_AFTR,
SYS_LPA,
SYS_SLEEP,
NUM_SYS_POWERDOWN,
};
struct exynos_pmu_conf {
unsigned int offset;
unsigned int val[NUM_SYS_POWERDOWN];
};
extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
extern void exynos_cpu_power_down(int cpu); extern void exynos_cpu_power_down(int cpu);
extern void exynos_cpu_power_up(int cpu); extern void exynos_cpu_power_up(int cpu);
extern int exynos_cpu_power_state(int cpu); extern int exynos_cpu_power_state(int cpu);
extern void exynos_cluster_power_down(int cluster); extern void exynos_cluster_power_down(int cluster);
extern void exynos_cluster_power_up(int cluster); extern void exynos_cluster_power_up(int cluster);
extern int exynos_cluster_power_state(int cluster); extern int exynos_cluster_power_state(int cluster);
extern void exynos_cpu_save_register(void);
extern void exynos_cpu_restore_register(void);
extern void exynos_pm_central_suspend(void);
extern int exynos_pm_central_resume(void);
extern void exynos_enter_aftr(void); extern void exynos_enter_aftr(void);
extern void s5p_init_cpu(void __iomem *cpuid_addr); extern void s5p_init_cpu(void __iomem *cpuid_addr);
......
/*
* Copyright (c) 2014 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Header for EXYNOS PMU Driver support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __EXYNOS_PMU_H
#define __EXYNOS_PMU_H
enum sys_powerdown {
SYS_AFTR,
SYS_LPA,
SYS_SLEEP,
NUM_SYS_POWERDOWN,
};
extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
#endif /* __EXYNOS_PMU_H */
...@@ -87,28 +87,6 @@ static struct map_desc exynos5_iodesc[] __initdata = { ...@@ -87,28 +87,6 @@ static struct map_desc exynos5_iodesc[] __initdata = {
}, },
}; };
static void exynos_restart(enum reboot_mode mode, const char *cmd)
{
struct device_node *np;
u32 val = 0x1;
void __iomem *addr = pmu_base_addr + EXYNOS_SWRESET;
if (of_machine_is_compatible("samsung,exynos5440")) {
u32 status;
np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock");
addr = of_iomap(np, 0) + 0xbc;
status = __raw_readl(addr);
addr = of_iomap(np, 0) + 0xcc;
val = __raw_readl(addr);
val = (val & 0xffff0000) | (status & 0xffff);
}
__raw_writel(val, addr);
}
static struct platform_device exynos_cpuidle = { static struct platform_device exynos_cpuidle = {
.name = "exynos_cpuidle", .name = "exynos_cpuidle",
#ifdef CONFIG_ARM_EXYNOS_CPUIDLE #ifdef CONFIG_ARM_EXYNOS_CPUIDLE
...@@ -202,6 +180,7 @@ static const struct of_device_id exynos_dt_pmu_match[] = { ...@@ -202,6 +180,7 @@ static const struct of_device_id exynos_dt_pmu_match[] = {
{ .compatible = "samsung,exynos4210-pmu" }, { .compatible = "samsung,exynos4210-pmu" },
{ .compatible = "samsung,exynos4212-pmu" }, { .compatible = "samsung,exynos4212-pmu" },
{ .compatible = "samsung,exynos4412-pmu" }, { .compatible = "samsung,exynos4412-pmu" },
{ .compatible = "samsung,exynos4415-pmu" },
{ .compatible = "samsung,exynos5250-pmu" }, { .compatible = "samsung,exynos5250-pmu" },
{ .compatible = "samsung,exynos5260-pmu" }, { .compatible = "samsung,exynos5260-pmu" },
{ .compatible = "samsung,exynos5410-pmu" }, { .compatible = "samsung,exynos5410-pmu" },
...@@ -268,7 +247,10 @@ static void __init exynos_dt_machine_init(void) ...@@ -268,7 +247,10 @@ static void __init exynos_dt_machine_init(void)
exynos_sysram_init(); exynos_sysram_init();
if (of_machine_is_compatible("samsung,exynos4210") || if (of_machine_is_compatible("samsung,exynos4210") ||
of_machine_is_compatible("samsung,exynos5250")) of_machine_is_compatible("samsung,exynos4212") ||
(of_machine_is_compatible("samsung,exynos4412") &&
of_machine_is_compatible("samsung,trats2")) ||
of_machine_is_compatible("samsung,exynos5250"))
platform_device_register(&exynos_cpuidle); platform_device_register(&exynos_cpuidle);
platform_device_register_simple("exynos-cpufreq", -1, NULL, 0); platform_device_register_simple("exynos-cpufreq", -1, NULL, 0);
...@@ -283,6 +265,7 @@ static char const *exynos_dt_compat[] __initconst = { ...@@ -283,6 +265,7 @@ static char const *exynos_dt_compat[] __initconst = {
"samsung,exynos4210", "samsung,exynos4210",
"samsung,exynos4212", "samsung,exynos4212",
"samsung,exynos4412", "samsung,exynos4412",
"samsung,exynos4415",
"samsung,exynos5", "samsung,exynos5",
"samsung,exynos5250", "samsung,exynos5250",
"samsung,exynos5260", "samsung,exynos5260",
...@@ -328,7 +311,6 @@ DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)") ...@@ -328,7 +311,6 @@ DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
.init_machine = exynos_dt_machine_init, .init_machine = exynos_dt_machine_init,
.init_late = exynos_init_late, .init_late = exynos_init_late,
.dt_compat = exynos_dt_compat, .dt_compat = exynos_dt_compat,
.restart = exynos_restart,
.reserve = exynos_reserve, .reserve = exynos_reserve,
.dt_fixup = exynos_dt_fixup, .dt_fixup = exynos_dt_fixup,
MACHINE_END MACHINE_END
...@@ -14,16 +14,44 @@ ...@@ -14,16 +14,44 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <asm/cacheflush.h>
#include <asm/cputype.h>
#include <asm/firmware.h> #include <asm/firmware.h>
#include <asm/suspend.h>
#include <mach/map.h> #include <mach/map.h>
#include "common.h" #include "common.h"
#include "smc.h" #include "smc.h"
static int exynos_do_idle(void) #define EXYNOS_SLEEP_MAGIC 0x00000bad
#define EXYNOS_AFTR_MAGIC 0xfcba0d10
#define EXYNOS_BOOT_ADDR 0x8
#define EXYNOS_BOOT_FLAG 0xc
static void exynos_save_cp15(void)
{ {
exynos_smc(SMC_CMD_SLEEP, 0, 0, 0); /* Save Power control and Diagnostic registers */
asm ("mrc p15, 0, %0, c15, c0, 0\n"
"mrc p15, 0, %1, c15, c0, 1\n"
: "=r" (cp15_save_power), "=r" (cp15_save_diag)
: : "cc");
}
static int exynos_do_idle(unsigned long mode)
{
switch (mode) {
case FW_DO_IDLE_AFTR:
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
exynos_save_cp15();
__raw_writel(virt_to_phys(exynos_cpu_resume_ns),
sysram_ns_base_addr + 0x24);
__raw_writel(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
break;
case FW_DO_IDLE_SLEEP:
exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
}
return 0; return 0;
} }
...@@ -69,10 +97,43 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr) ...@@ -69,10 +97,43 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
return 0; return 0;
} }
static int exynos_cpu_suspend(unsigned long arg)
{
flush_cache_all();
outer_flush_all();
exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
pr_info("Failed to suspend the system\n");
writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
return 1;
}
static int exynos_suspend(void)
{
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
exynos_save_cp15();
writel(EXYNOS_SLEEP_MAGIC, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
writel(virt_to_phys(exynos_cpu_resume_ns),
sysram_ns_base_addr + EXYNOS_BOOT_ADDR);
return cpu_suspend(0, exynos_cpu_suspend);
}
static int exynos_resume(void)
{
writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
return 0;
}
static const struct firmware_ops exynos_firmware_ops = { static const struct firmware_ops exynos_firmware_ops = {
.do_idle = exynos_do_idle, .do_idle = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL,
.set_cpu_boot_addr = exynos_set_cpu_boot_addr, .set_cpu_boot_addr = exynos_set_cpu_boot_addr,
.cpu_boot = exynos_cpu_boot, .cpu_boot = exynos_cpu_boot,
.suspend = IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL,
.resume = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
}; };
void __init exynos_firmware_init(void) void __init exynos_firmware_init(void)
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/syscore_ops.h>
#include <asm/cputype.h> #include <asm/cputype.h>
#include <asm/cp15.h> #include <asm/cp15.h>
...@@ -30,6 +31,8 @@ ...@@ -30,6 +31,8 @@
#define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29) #define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29)
#define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30) #define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30)
static void __iomem *ns_sram_base_addr;
/* /*
* The common v7_exit_coherency_flush API could not be used because of the * The common v7_exit_coherency_flush API could not be used because of the
* Erratum 799270 workaround. This macro is the same as the common one (in * Erratum 799270 workaround. This macro is the same as the common one (in
...@@ -318,10 +321,26 @@ static const struct of_device_id exynos_dt_mcpm_match[] = { ...@@ -318,10 +321,26 @@ static const struct of_device_id exynos_dt_mcpm_match[] = {
{}, {},
}; };
static void exynos_mcpm_setup_entry_point(void)
{
/*
* U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr
* as part of secondary_cpu_start(). Let's redirect it to the
* mcpm_entry_point(). This is done during both secondary boot-up as
* well as system resume.
*/
__raw_writel(0xe59f0000, ns_sram_base_addr); /* ldr r0, [pc, #0] */
__raw_writel(0xe12fff10, ns_sram_base_addr + 4); /* bx r0 */
__raw_writel(virt_to_phys(mcpm_entry_point), ns_sram_base_addr + 8);
}
static struct syscore_ops exynos_mcpm_syscore_ops = {
.resume = exynos_mcpm_setup_entry_point,
};
static int __init exynos_mcpm_init(void) static int __init exynos_mcpm_init(void)
{ {
struct device_node *node; struct device_node *node;
void __iomem *ns_sram_base_addr;
unsigned int value, i; unsigned int value, i;
int ret; int ret;
...@@ -387,16 +406,9 @@ static int __init exynos_mcpm_init(void) ...@@ -387,16 +406,9 @@ static int __init exynos_mcpm_init(void)
pmu_raw_writel(value, EXYNOS_COMMON_OPTION(i)); pmu_raw_writel(value, EXYNOS_COMMON_OPTION(i));
} }
/* exynos_mcpm_setup_entry_point();
* U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr
* as part of secondary_cpu_start(). Let's redirect it to the
* mcpm_entry_point().
*/
__raw_writel(0xe59f0000, ns_sram_base_addr); /* ldr r0, [pc, #0] */
__raw_writel(0xe12fff10, ns_sram_base_addr + 4); /* bx r0 */
__raw_writel(virt_to_phys(mcpm_entry_point), ns_sram_base_addr + 8);
iounmap(ns_sram_base_addr); register_syscore_ops(&exynos_mcpm_syscore_ops);
return ret; return ret;
} }
......
...@@ -126,6 +126,18 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious) ...@@ -126,6 +126,18 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
*/ */
void exynos_cpu_power_down(int cpu) void exynos_cpu_power_down(int cpu)
{ {
if (cpu == 0 && (of_machine_is_compatible("samsung,exynos5420") ||
of_machine_is_compatible("samsung,exynos5800"))) {
/*
* Bypass power down for CPU0 during suspend. Check for
* the SYS_PWR_REG value to decide if we are suspending
* the system.
*/
int val = pmu_raw_readl(EXYNOS5_ARM_CORE0_SYS_PWR_REG);
if (!(val & S5P_CORE_LOCAL_PWR_EN))
return;
}
pmu_raw_writel(0, EXYNOS_ARM_CORE_CONFIGURATION(cpu)); pmu_raw_writel(0, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
} }
...@@ -203,6 +215,26 @@ static inline void __iomem *cpu_boot_reg(int cpu) ...@@ -203,6 +215,26 @@ static inline void __iomem *cpu_boot_reg(int cpu)
return boot_reg; return boot_reg;
} }
/*
* Set wake up by local power mode and execute software reset for given core.
*
* Currently this is needed only when booting secondary CPU on Exynos3250.
*/
static void exynos_core_restart(u32 core_id)
{
u32 val;
if (!of_machine_is_compatible("samsung,exynos3250"))
return;
val = pmu_raw_readl(EXYNOS_ARM_CORE_STATUS(core_id));
val |= S5P_CORE_WAKEUP_FROM_LOCAL_CFG;
pmu_raw_writel(val, EXYNOS_ARM_CORE_STATUS(core_id));
pr_info("CPU%u: Software reset\n", core_id);
pmu_raw_writel(EXYNOS_CORE_PO_RESET(core_id), EXYNOS_SWRESET);
}
/* /*
* Write pen_release in a way that is guaranteed to be visible to all * Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency * observers, irrespective of whether they're taking part in coherency
...@@ -279,6 +311,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -279,6 +311,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
return -ETIMEDOUT; return -ETIMEDOUT;
} }
} }
exynos_core_restart(core_id);
/* /*
* Send the secondary CPU a soft interrupt, thereby causing * Send the secondary CPU a soft interrupt, thereby causing
* the boot monitor to read the system wide flags register, * the boot monitor to read the system wide flags register,
......
/* /*
* Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
* http://www.samsung.com * http://www.samsung.com
* *
* EXYNOS - Power Management support * EXYNOS - Power Management support
...@@ -15,109 +15,45 @@ ...@@ -15,109 +15,45 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/syscore_ops.h>
#include <linux/cpu_pm.h> #include <linux/cpu_pm.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/irqchip/arm-gic.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/clk.h>
#include <asm/cacheflush.h> #include <asm/firmware.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <asm/suspend.h> #include <asm/suspend.h>
#include <plat/pm-common.h> #include <plat/pm-common.h>
#include <plat/regs-srom.h>
#include <mach/map.h>
#include "common.h" #include "common.h"
#include "exynos-pmu.h"
#include "regs-pmu.h" #include "regs-pmu.h"
#include "regs-sys.h" #include "regs-sys.h"
/** static inline void __iomem *exynos_boot_vector_addr(void)
* struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping
* @hwirq: Hardware IRQ signal of the GIC
* @mask: Mask in PMU wake-up mask register
*/
struct exynos_wkup_irq {
unsigned int hwirq;
u32 mask;
};
static struct sleep_save exynos5_sys_save[] = {
SAVE_ITEM(EXYNOS5_SYS_I2C_CFG),
};
static struct sleep_save exynos_core_save[] = {
/* SROM side */
SAVE_ITEM(S5P_SROM_BW),
SAVE_ITEM(S5P_SROM_BC0),
SAVE_ITEM(S5P_SROM_BC1),
SAVE_ITEM(S5P_SROM_BC2),
SAVE_ITEM(S5P_SROM_BC3),
};
/*
* GIC wake-up support
*/
static u32 exynos_irqwake_intmask = 0xffffffff;
static const struct exynos_wkup_irq exynos4_wkup_irq[] = {
{ 76, BIT(1) }, /* RTC alarm */
{ 77, BIT(2) }, /* RTC tick */
{ /* sentinel */ },
};
static const struct exynos_wkup_irq exynos5250_wkup_irq[] = {
{ 75, BIT(1) }, /* RTC alarm */
{ 76, BIT(2) }, /* RTC tick */
{ /* sentinel */ },
};
static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
{ {
const struct exynos_wkup_irq *wkup_irq; if (samsung_rev() == EXYNOS4210_REV_1_1)
return pmu_base_addr + S5P_INFORM7;
if (soc_is_exynos5250()) else if (samsung_rev() == EXYNOS4210_REV_1_0)
wkup_irq = exynos5250_wkup_irq; return sysram_base_addr + 0x24;
else return pmu_base_addr + S5P_INFORM0;
wkup_irq = exynos4_wkup_irq;
while (wkup_irq->mask) {
if (wkup_irq->hwirq == data->hwirq) {
if (!state)
exynos_irqwake_intmask |= wkup_irq->mask;
else
exynos_irqwake_intmask &= ~wkup_irq->mask;
return 0;
}
++wkup_irq;
}
return -ENOENT;
} }
#define EXYNOS_BOOT_VECTOR_ADDR (samsung_rev() == EXYNOS4210_REV_1_1 ? \ static inline void __iomem *exynos_boot_vector_flag(void)
pmu_base_addr + S5P_INFORM7 : \ {
(samsung_rev() == EXYNOS4210_REV_1_0 ? \ if (samsung_rev() == EXYNOS4210_REV_1_1)
(sysram_base_addr + 0x24) : \ return pmu_base_addr + S5P_INFORM6;
pmu_base_addr + S5P_INFORM0)) else if (samsung_rev() == EXYNOS4210_REV_1_0)
#define EXYNOS_BOOT_VECTOR_FLAG (samsung_rev() == EXYNOS4210_REV_1_1 ? \ return sysram_base_addr + 0x20;
pmu_base_addr + S5P_INFORM6 : \ return pmu_base_addr + S5P_INFORM1;
(samsung_rev() == EXYNOS4210_REV_1_0 ? \ }
(sysram_base_addr + 0x20) : \
pmu_base_addr + S5P_INFORM1))
#define S5P_CHECK_AFTR 0xFCBA0D10 #define S5P_CHECK_AFTR 0xFCBA0D10
#define S5P_CHECK_SLEEP 0x00000BAD
/* For Cortex-A9 Diagnostic and Power control register */ /* For Cortex-A9 Diagnostic and Power control register */
static unsigned int save_arm_register[2]; static unsigned int save_arm_register[2];
static void exynos_cpu_save_register(void) void exynos_cpu_save_register(void)
{ {
unsigned long tmp; unsigned long tmp;
...@@ -134,7 +70,7 @@ static void exynos_cpu_save_register(void) ...@@ -134,7 +70,7 @@ static void exynos_cpu_save_register(void)
save_arm_register[1] = tmp; save_arm_register[1] = tmp;
} }
static void exynos_cpu_restore_register(void) void exynos_cpu_restore_register(void)
{ {
unsigned long tmp; unsigned long tmp;
...@@ -153,7 +89,7 @@ static void exynos_cpu_restore_register(void) ...@@ -153,7 +89,7 @@ static void exynos_cpu_restore_register(void)
: "cc"); : "cc");
} }
static void exynos_pm_central_suspend(void) void exynos_pm_central_suspend(void)
{ {
unsigned long tmp; unsigned long tmp;
...@@ -161,9 +97,13 @@ static void exynos_pm_central_suspend(void) ...@@ -161,9 +97,13 @@ static void exynos_pm_central_suspend(void)
tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
tmp &= ~S5P_CENTRAL_LOWPWR_CFG; tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
/* Setting SEQ_OPTION register */
pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
S5P_CENTRAL_SEQ_OPTION);
} }
static int exynos_pm_central_resume(void) int exynos_pm_central_resume(void)
{ {
unsigned long tmp; unsigned long tmp;
...@@ -194,17 +134,26 @@ static void exynos_set_wakeupmask(long mask) ...@@ -194,17 +134,26 @@ static void exynos_set_wakeupmask(long mask)
static void exynos_cpu_set_boot_vector(long flags) static void exynos_cpu_set_boot_vector(long flags)
{ {
__raw_writel(virt_to_phys(exynos_cpu_resume), EXYNOS_BOOT_VECTOR_ADDR); __raw_writel(virt_to_phys(exynos_cpu_resume),
__raw_writel(flags, EXYNOS_BOOT_VECTOR_FLAG); exynos_boot_vector_addr());
__raw_writel(flags, exynos_boot_vector_flag());
} }
static int exynos_aftr_finisher(unsigned long flags) static int exynos_aftr_finisher(unsigned long flags)
{ {
int ret;
exynos_set_wakeupmask(0x0000ff3e); exynos_set_wakeupmask(0x0000ff3e);
exynos_cpu_set_boot_vector(S5P_CHECK_AFTR);
/* Set value of power down register for aftr mode */ /* Set value of power down register for aftr mode */
exynos_sys_powerdown_conf(SYS_AFTR); exynos_sys_powerdown_conf(SYS_AFTR);
cpu_do_idle();
ret = call_firmware_op(do_idle, FW_DO_IDLE_AFTR);
if (ret == -ENOSYS) {
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
exynos_cpu_save_register();
exynos_cpu_set_boot_vector(S5P_CHECK_AFTR);
cpu_do_idle();
}
return 1; return 1;
} }
...@@ -214,196 +163,16 @@ void exynos_enter_aftr(void) ...@@ -214,196 +163,16 @@ void exynos_enter_aftr(void)
cpu_pm_enter(); cpu_pm_enter();
exynos_pm_central_suspend(); exynos_pm_central_suspend();
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
exynos_cpu_save_register();
cpu_suspend(0, exynos_aftr_finisher); cpu_suspend(0, exynos_aftr_finisher);
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) { if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
scu_enable(S5P_VA_SCU); scu_enable(S5P_VA_SCU);
exynos_cpu_restore_register(); if (call_firmware_op(resume) == -ENOSYS)
exynos_cpu_restore_register();
} }
exynos_pm_central_resume(); exynos_pm_central_resume();
cpu_pm_exit(); cpu_pm_exit();
} }
static int exynos_cpu_suspend(unsigned long arg)
{
#ifdef CONFIG_CACHE_L2X0
outer_flush_all();
#endif
if (soc_is_exynos5250())
flush_cache_all();
/* issue the standby signal into the pm unit. */
cpu_do_idle();
pr_info("Failed to suspend the system\n");
return 1; /* Aborting suspend */
}
static void exynos_pm_prepare(void)
{
unsigned int tmp;
/* Set wake-up mask registers */
pmu_raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
pmu_raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
if (soc_is_exynos5250()) {
s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save));
/* Disable USE_RETENTION of JPEG_MEM_OPTION */
tmp = pmu_raw_readl(EXYNOS5_JPEG_MEM_OPTION);
tmp &= ~EXYNOS5_OPTION_USE_RETENTION;
pmu_raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION);
}
/* Set value of power down register for sleep mode */
exynos_sys_powerdown_conf(SYS_SLEEP);
pmu_raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1);
/* ensure at least INFORM0 has the resume address */
pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
}
static int exynos_pm_suspend(void)
{
unsigned long tmp;
exynos_pm_central_suspend();
/* Setting SEQ_OPTION register */
tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
exynos_cpu_save_register();
return 0;
}
static void exynos_pm_resume(void)
{
if (exynos_pm_central_resume())
goto early_wakeup;
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
exynos_cpu_restore_register();
/* For release retention */
pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
if (soc_is_exynos5250())
s3c_pm_do_restore(exynos5_sys_save,
ARRAY_SIZE(exynos5_sys_save));
s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
scu_enable(S5P_VA_SCU);
early_wakeup:
/* Clear SLEEP mode set in INFORM1 */
pmu_raw_writel(0x0, S5P_INFORM1);
return;
}
static struct syscore_ops exynos_pm_syscore_ops = {
.suspend = exynos_pm_suspend,
.resume = exynos_pm_resume,
};
/*
* Suspend Ops
*/
static int exynos_suspend_enter(suspend_state_t state)
{
int ret;
s3c_pm_debug_init();
S3C_PMDBG("%s: suspending the system...\n", __func__);
S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__,
exynos_irqwake_intmask, exynos_get_eint_wake_mask());
if (exynos_irqwake_intmask == -1U
&& exynos_get_eint_wake_mask() == -1U) {
pr_err("%s: No wake-up sources!\n", __func__);
pr_err("%s: Aborting sleep\n", __func__);
return -EINVAL;
}
s3c_pm_save_uarts();
exynos_pm_prepare();
flush_cache_all();
s3c_pm_check_store();
ret = cpu_suspend(0, exynos_cpu_suspend);
if (ret)
return ret;
s3c_pm_restore_uarts();
S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
pmu_raw_readl(S5P_WAKEUP_STAT));
s3c_pm_check_restore();
S3C_PMDBG("%s: resuming the system...\n", __func__);
return 0;
}
static int exynos_suspend_prepare(void)
{
s3c_pm_check_prepare();
return 0;
}
static void exynos_suspend_finish(void)
{
s3c_pm_check_cleanup();
}
static const struct platform_suspend_ops exynos_suspend_ops = {
.enter = exynos_suspend_enter,
.prepare = exynos_suspend_prepare,
.finish = exynos_suspend_finish,
.valid = suspend_valid_only_mem,
};
void __init exynos_pm_init(void)
{
u32 tmp;
/* Platform-specific GIC callback */
gic_arch_extn.irq_set_wake = exynos_irq_set_wake;
/* All wakeup disable */
tmp = pmu_raw_readl(S5P_WAKEUP_MASK);
tmp |= ((0xFF << 8) | (0x1F << 1));
pmu_raw_writel(tmp, S5P_WAKEUP_MASK);
register_syscore_ops(&exynos_pm_syscore_ops);
suspend_set_ops(&exynos_suspend_ops);
}
此差异已折叠。
...@@ -19,9 +19,24 @@ ...@@ -19,9 +19,24 @@
#define S5P_CENTRAL_SEQ_OPTION 0x0208 #define S5P_CENTRAL_SEQ_OPTION 0x0208
#define S5P_USE_STANDBY_WFI0 (1 << 16) #define S5P_USE_STANDBY_WFI0 (1 << 16)
#define S5P_USE_STANDBY_WFI1 (1 << 17)
#define S5P_USE_STANDBY_WFI2 (1 << 19)
#define S5P_USE_STANDBY_WFI3 (1 << 20)
#define S5P_USE_STANDBY_WFE0 (1 << 24) #define S5P_USE_STANDBY_WFE0 (1 << 24)
#define S5P_USE_STANDBY_WFE1 (1 << 25)
#define S5P_USE_STANDBY_WFE2 (1 << 27)
#define S5P_USE_STANDBY_WFE3 (1 << 28)
#define S5P_USE_STANDBY_WFI_ALL \
(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFI1 | \
S5P_USE_STANDBY_WFI2 | S5P_USE_STANDBY_WFI3 | \
S5P_USE_STANDBY_WFE0 | S5P_USE_STANDBY_WFE1 | \
S5P_USE_STANDBY_WFE2 | S5P_USE_STANDBY_WFE3)
#define S5P_USE_DELAYED_RESET_ASSERTION BIT(12) #define S5P_USE_DELAYED_RESET_ASSERTION BIT(12)
#define EXYNOS_CORE_PO_RESET(n) ((1 << 4) << n)
#define EXYNOS_WAKEUP_FROM_LOWPWR (1 << 28)
#define EXYNOS_SWRESET 0x0400 #define EXYNOS_SWRESET 0x0400
#define EXYNOS5440_SWRESET 0x00C4 #define EXYNOS5440_SWRESET 0x00C4
...@@ -36,6 +51,7 @@ ...@@ -36,6 +51,7 @@
#define S5P_INFORM7 0x081C #define S5P_INFORM7 0x081C
#define S5P_PMU_SPARE3 0x090C #define S5P_PMU_SPARE3 0x090C
#define EXYNOS_IROM_DATA2 0x0988
#define S5P_ARM_CORE0_LOWPWR 0x1000 #define S5P_ARM_CORE0_LOWPWR 0x1000
#define S5P_DIS_IRQ_CORE0 0x1004 #define S5P_DIS_IRQ_CORE0 0x1004
#define S5P_DIS_IRQ_CENTRAL0 0x1008 #define S5P_DIS_IRQ_CENTRAL0 0x1008
...@@ -118,6 +134,31 @@ ...@@ -118,6 +134,31 @@
#define EXYNOS_COMMON_OPTION(_nr) \ #define EXYNOS_COMMON_OPTION(_nr) \
(EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8) (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8)
#define EXYNOS_CORE_LOCAL_PWR_EN 0x3
#define EXYNOS_ARM_COMMON_STATUS 0x2504
#define EXYNOS_COMMON_OPTION(_nr) \
(EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8)
#define EXYNOS_ARM_L2_CONFIGURATION 0x2600
#define EXYNOS_L2_CONFIGURATION(_nr) \
(EXYNOS_ARM_L2_CONFIGURATION + ((_nr) * 0x80))
#define EXYNOS_L2_STATUS(_nr) \
(EXYNOS_L2_CONFIGURATION(_nr) + 0x4)
#define EXYNOS_L2_OPTION(_nr) \
(EXYNOS_L2_CONFIGURATION(_nr) + 0x8)
#define EXYNOS_L2_COMMON_PWR_EN 0x3
#define EXYNOS_ARM_CORE_X_STATUS_OFFSET 0x4
#define EXYNOS5_APLL_SYSCLK_CONFIGURATION 0x2A00
#define EXYNOS5_APLL_SYSCLK_STATUS 0x2A04
#define EXYNOS5_ARM_L2_OPTION 0x2608
#define EXYNOS5_USE_RETENTION BIT(4)
#define EXYNOS5_L2RSTDISABLE_VALUE BIT(3)
#define S5P_PAD_RET_MAUDIO_OPTION 0x3028 #define S5P_PAD_RET_MAUDIO_OPTION 0x3028
#define S5P_PAD_RET_GPIO_OPTION 0x3108 #define S5P_PAD_RET_GPIO_OPTION 0x3108
#define S5P_PAD_RET_UART_OPTION 0x3128 #define S5P_PAD_RET_UART_OPTION 0x3128
...@@ -126,7 +167,19 @@ ...@@ -126,7 +167,19 @@
#define S5P_PAD_RET_EBIA_OPTION 0x3188 #define S5P_PAD_RET_EBIA_OPTION 0x3188
#define S5P_PAD_RET_EBIB_OPTION 0x31A8 #define S5P_PAD_RET_EBIB_OPTION 0x31A8
#define S5P_PS_HOLD_CONTROL 0x330C
#define S5P_PS_HOLD_EN (1 << 31)
#define S5P_PS_HOLD_OUTPUT_HIGH (3 << 8)
#define S5P_CAM_OPTION 0x3C08
#define S5P_MFC_OPTION 0x3C48
#define S5P_G3D_OPTION 0x3C68
#define S5P_LCD0_OPTION 0x3C88
#define S5P_LCD1_OPTION 0x3CA8
#define S5P_ISP_OPTION S5P_LCD1_OPTION
#define S5P_CORE_LOCAL_PWR_EN 0x3 #define S5P_CORE_LOCAL_PWR_EN 0x3
#define S5P_CORE_WAKEUP_FROM_LOCAL_CFG (0x3 << 8)
/* Only for EXYNOS4210 */ /* Only for EXYNOS4210 */
#define S5P_CMU_CLKSTOP_LCD1_LOWPWR 0x1154 #define S5P_CMU_CLKSTOP_LCD1_LOWPWR 0x1154
...@@ -185,11 +238,116 @@ ...@@ -185,11 +238,116 @@
#define S5P_DIS_IRQ_CORE3 0x1034 #define S5P_DIS_IRQ_CORE3 0x1034
#define S5P_DIS_IRQ_CENTRAL3 0x1038 #define S5P_DIS_IRQ_CENTRAL3 0x1038
/* Only for EXYNOS3XXX */
#define EXYNOS3_ARM_CORE0_SYS_PWR_REG 0x1000
#define EXYNOS3_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG 0x1004
#define EXYNOS3_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG 0x1008
#define EXYNOS3_ARM_CORE1_SYS_PWR_REG 0x1010
#define EXYNOS3_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG 0x1014
#define EXYNOS3_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG 0x1018
#define EXYNOS3_ISP_ARM_SYS_PWR_REG 0x1050
#define EXYNOS3_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG 0x1054
#define EXYNOS3_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG 0x1058
#define EXYNOS3_ARM_COMMON_SYS_PWR_REG 0x1080
#define EXYNOS3_ARM_L2_SYS_PWR_REG 0x10C0
#define EXYNOS3_CMU_ACLKSTOP_SYS_PWR_REG 0x1100
#define EXYNOS3_CMU_SCLKSTOP_SYS_PWR_REG 0x1104
#define EXYNOS3_CMU_RESET_SYS_PWR_REG 0x110C
#define EXYNOS3_CMU_ACLKSTOP_COREBLK_SYS_PWR_REG 0x1110
#define EXYNOS3_CMU_SCLKSTOP_COREBLK_SYS_PWR_REG 0x1114
#define EXYNOS3_CMU_RESET_COREBLK_SYS_PWR_REG 0x111C
#define EXYNOS3_APLL_SYSCLK_SYS_PWR_REG 0x1120
#define EXYNOS3_MPLL_SYSCLK_SYS_PWR_REG 0x1124
#define EXYNOS3_VPLL_SYSCLK_SYS_PWR_REG 0x1128
#define EXYNOS3_EPLL_SYSCLK_SYS_PWR_REG 0x112C
#define EXYNOS3_MPLLUSER_SYSCLK_SYS_PWR_REG 0x1130
#define EXYNOS3_BPLLUSER_SYSCLK_SYS_PWR_REG 0x1134
#define EXYNOS3_EPLLUSER_SYSCLK_SYS_PWR_REG 0x1138
#define EXYNOS3_CMU_CLKSTOP_CAM_SYS_PWR_REG 0x1140
#define EXYNOS3_CMU_CLKSTOP_MFC_SYS_PWR_REG 0x1148
#define EXYNOS3_CMU_CLKSTOP_G3D_SYS_PWR_REG 0x114C
#define EXYNOS3_CMU_CLKSTOP_LCD0_SYS_PWR_REG 0x1150
#define EXYNOS3_CMU_CLKSTOP_ISP_SYS_PWR_REG 0x1154
#define EXYNOS3_CMU_CLKSTOP_MAUDIO_SYS_PWR_REG 0x1158
#define EXYNOS3_CMU_RESET_CAM_SYS_PWR_REG 0x1160
#define EXYNOS3_CMU_RESET_MFC_SYS_PWR_REG 0x1168
#define EXYNOS3_CMU_RESET_G3D_SYS_PWR_REG 0x116C
#define EXYNOS3_CMU_RESET_LCD0_SYS_PWR_REG 0x1170
#define EXYNOS3_CMU_RESET_ISP_SYS_PWR_REG 0x1174
#define EXYNOS3_CMU_RESET_MAUDIO_SYS_PWR_REG 0x1178
#define EXYNOS3_TOP_BUS_SYS_PWR_REG 0x1180
#define EXYNOS3_TOP_RETENTION_SYS_PWR_REG 0x1184
#define EXYNOS3_TOP_PWR_SYS_PWR_REG 0x1188
#define EXYNOS3_TOP_BUS_COREBLK_SYS_PWR_REG 0x1190
#define EXYNOS3_TOP_RETENTION_COREBLK_SYS_PWR_REG 0x1194
#define EXYNOS3_TOP_PWR_COREBLK_SYS_PWR_REG 0x1198
#define EXYNOS3_LOGIC_RESET_SYS_PWR_REG 0x11A0
#define EXYNOS3_OSCCLK_GATE_SYS_PWR_REG 0x11A4
#define EXYNOS3_LOGIC_RESET_COREBLK_SYS_PWR_REG 0x11B0
#define EXYNOS3_OSCCLK_GATE_COREBLK_SYS_PWR_REG 0x11B4
#define EXYNOS3_PAD_RETENTION_DRAM_SYS_PWR_REG 0x1200
#define EXYNOS3_PAD_RETENTION_MAUDIO_SYS_PWR_REG 0x1204
#define EXYNOS3_PAD_RETENTION_SPI_SYS_PWR_REG 0x1208
#define EXYNOS3_PAD_RETENTION_MMC2_SYS_PWR_REG 0x1218
#define EXYNOS3_PAD_RETENTION_GPIO_SYS_PWR_REG 0x1220
#define EXYNOS3_PAD_RETENTION_UART_SYS_PWR_REG 0x1224
#define EXYNOS3_PAD_RETENTION_MMC0_SYS_PWR_REG 0x1228
#define EXYNOS3_PAD_RETENTION_MMC1_SYS_PWR_REG 0x122C
#define EXYNOS3_PAD_RETENTION_EBIA_SYS_PWR_REG 0x1230
#define EXYNOS3_PAD_RETENTION_EBIB_SYS_PWR_REG 0x1234
#define EXYNOS3_PAD_RETENTION_JTAG_SYS_PWR_REG 0x1238
#define EXYNOS3_PAD_ISOLATION_SYS_PWR_REG 0x1240
#define EXYNOS3_PAD_ALV_SEL_SYS_PWR_REG 0x1260
#define EXYNOS3_XUSBXTI_SYS_PWR_REG 0x1280
#define EXYNOS3_XXTI_SYS_PWR_REG 0x1284
#define EXYNOS3_EXT_REGULATOR_SYS_PWR_REG 0x12C0
#define EXYNOS3_EXT_REGULATOR_COREBLK_SYS_PWR_REG 0x12C4
#define EXYNOS3_GPIO_MODE_SYS_PWR_REG 0x1300
#define EXYNOS3_GPIO_MODE_MAUDIO_SYS_PWR_REG 0x1340
#define EXYNOS3_TOP_ASB_RESET_SYS_PWR_REG 0x1344
#define EXYNOS3_TOP_ASB_ISOLATION_SYS_PWR_REG 0x1348
#define EXYNOS3_TOP_ASB_RESET_COREBLK_SYS_PWR_REG 0x1350
#define EXYNOS3_TOP_ASB_ISOLATION_COREBLK_SYS_PWR_REG 0x1354
#define EXYNOS3_CAM_SYS_PWR_REG 0x1380
#define EXYNOS3_MFC_SYS_PWR_REG 0x1388
#define EXYNOS3_G3D_SYS_PWR_REG 0x138C
#define EXYNOS3_LCD0_SYS_PWR_REG 0x1390
#define EXYNOS3_ISP_SYS_PWR_REG 0x1394
#define EXYNOS3_MAUDIO_SYS_PWR_REG 0x1398
#define EXYNOS3_DRAM_FREQ_DOWN_SYS_PWR_REG 0x13B0
#define EXYNOS3_DDRPHY_DLLOFF_SYS_PWR_REG 0x13B4
#define EXYNOS3_CMU_SYSCLK_ISP_SYS_PWR_REG 0x13B8
#define EXYNOS3_LPDDR_PHY_DLL_LOCK_SYS_PWR_REG 0x13C0
#define EXYNOS3_BPLL_SYSCLK_SYS_PWR_REG 0x13C4
#define EXYNOS3_UPLL_SYSCLK_SYS_PWR_REG 0x13C8
#define EXYNOS3_ARM_CORE0_OPTION 0x2008
#define EXYNOS3_ARM_CORE_OPTION(_nr) \
(EXYNOS3_ARM_CORE0_OPTION + ((_nr) * 0x80))
#define EXYNOS3_ARM_COMMON_OPTION 0x2408
#define EXYNOS3_TOP_PWR_OPTION 0x2C48
#define EXYNOS3_CORE_TOP_PWR_OPTION 0x2CA8
#define EXYNOS3_XUSBXTI_DURATION 0x341C
#define EXYNOS3_XXTI_DURATION 0x343C
#define EXYNOS3_EXT_REGULATOR_DURATION 0x361C
#define EXYNOS3_EXT_REGULATOR_COREBLK_DURATION 0x363C
#define XUSBXTI_DURATION 0x00000BB8
#define XXTI_DURATION XUSBXTI_DURATION
#define EXT_REGULATOR_DURATION 0x00001D4C
#define EXT_REGULATOR_COREBLK_DURATION EXT_REGULATOR_DURATION
/* for XXX_OPTION */
#define EXYNOS3_OPTION_USE_SC_COUNTER (1 << 0)
#define EXYNOS3_OPTION_USE_SC_FEEDBACK (1 << 1)
#define EXYNOS3_OPTION_SKIP_DEACTIVATE_ACEACP_IN_PWDN (1 << 7)
/* For EXYNOS5 */ /* For EXYNOS5 */
#define EXYNOS5_AUTO_WDTRESET_DISABLE 0x0408 #define EXYNOS5_AUTO_WDTRESET_DISABLE 0x0408
#define EXYNOS5_MASK_WDTRESET_REQUEST 0x040C #define EXYNOS5_MASK_WDTRESET_REQUEST 0x040C
#define EXYNOS5_USE_RETENTION BIT(4)
#define EXYNOS5_SYS_WDTRESET (1 << 20) #define EXYNOS5_SYS_WDTRESET (1 << 20)
#define EXYNOS5_ARM_CORE0_SYS_PWR_REG 0x1000 #define EXYNOS5_ARM_CORE0_SYS_PWR_REG 0x1000
...@@ -329,4 +487,204 @@ static inline unsigned int exynos_pmu_cpunr(unsigned int mpidr) ...@@ -329,4 +487,204 @@ static inline unsigned int exynos_pmu_cpunr(unsigned int mpidr)
+ MPIDR_AFFINITY_LEVEL(mpidr, 0)); + MPIDR_AFFINITY_LEVEL(mpidr, 0));
} }
/* Only for EXYNOS5420 */
#define EXYNOS5420_ISP_ARM_OPTION 0x2488
#define EXYNOS5420_L2RSTDISABLE_VALUE BIT(3)
#define EXYNOS5420_LPI_MASK 0x0004
#define EXYNOS5420_LPI_MASK1 0x0008
#define EXYNOS5420_UFS BIT(8)
#define EXYNOS5420_ATB_KFC BIT(13)
#define EXYNOS5420_ATB_ISP_ARM BIT(19)
#define EXYNOS5420_EMULATION BIT(31)
#define ATB_ISP_ARM BIT(12)
#define ATB_KFC BIT(13)
#define ATB_NOC BIT(14)
#define EXYNOS5420_ARM_INTR_SPREAD_ENABLE 0x0100
#define EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI 0x0104
#define EXYNOS5420_UP_SCHEDULER 0x0120
#define SPREAD_ENABLE 0xF
#define SPREAD_USE_STANDWFI 0xF
#define EXYNOS5420_BB_CON1 0x0784
#define EXYNOS5420_BB_SEL_EN BIT(31)
#define EXYNOS5420_BB_PMOS_EN BIT(7)
#define EXYNOS5420_BB_1300X 0XF
#define EXYNOS5420_ARM_CORE2_SYS_PWR_REG 0x1020
#define EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG 0x1024
#define EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG 0x1028
#define EXYNOS5420_ARM_CORE3_SYS_PWR_REG 0x1030
#define EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG 0x1034
#define EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG 0x1038
#define EXYNOS5420_KFC_CORE0_SYS_PWR_REG 0x1040
#define EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG 0x1044
#define EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG 0x1048
#define EXYNOS5420_KFC_CORE1_SYS_PWR_REG 0x1050
#define EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG 0x1054
#define EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG 0x1058
#define EXYNOS5420_KFC_CORE2_SYS_PWR_REG 0x1060
#define EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG 0x1064
#define EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG 0x1068
#define EXYNOS5420_KFC_CORE3_SYS_PWR_REG 0x1070
#define EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG 0x1074
#define EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG 0x1078
#define EXYNOS5420_ISP_ARM_SYS_PWR_REG 0x1090
#define EXYNOS5420_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG 0x1094
#define EXYNOS5420_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG 0x1098
#define EXYNOS5420_ARM_COMMON_SYS_PWR_REG 0x10A0
#define EXYNOS5420_KFC_COMMON_SYS_PWR_REG 0x10B0
#define EXYNOS5420_KFC_L2_SYS_PWR_REG 0x10D0
#define EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG 0x1158
#define EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG 0x115C
#define EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG 0x1160
#define EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG 0x1174
#define EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG 0x1178
#define EXYNOS5420_INTRAM_MEM_SYS_PWR_REG 0x11B8
#define EXYNOS5420_INTROM_MEM_SYS_PWR_REG 0x11BC
#define EXYNOS5420_ONENANDXL_MEM_SYS_PWR 0x11C0
#define EXYNOS5420_USBDEV_MEM_SYS_PWR 0x11CC
#define EXYNOS5420_USBDEV1_MEM_SYS_PWR 0x11D0
#define EXYNOS5420_SDMMC_MEM_SYS_PWR 0x11D4
#define EXYNOS5420_CSSYS_MEM_SYS_PWR 0x11D8
#define EXYNOS5420_SECSS_MEM_SYS_PWR 0x11DC
#define EXYNOS5420_ROTATOR_MEM_SYS_PWR 0x11E0
#define EXYNOS5420_INTRAM_MEM_SYS_PWR 0x11E4
#define EXYNOS5420_INTROM_MEM_SYS_PWR 0x11E8
#define EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG 0x1208
#define EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG 0x1210
#define EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG 0x1214
#define EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG 0x1218
#define EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG 0x121C
#define EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG 0x1220
#define EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG 0x1224
#define EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG 0x1228
#define EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG 0x122C
#define EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG 0x1230
#define EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG 0x1234
#define EXYNOS5420_DISP1_SYS_PWR_REG 0x1410
#define EXYNOS5420_MAU_SYS_PWR_REG 0x1414
#define EXYNOS5420_G2D_SYS_PWR_REG 0x1418
#define EXYNOS5420_MSC_SYS_PWR_REG 0x141C
#define EXYNOS5420_FSYS_SYS_PWR_REG 0x1420
#define EXYNOS5420_FSYS2_SYS_PWR_REG 0x1424
#define EXYNOS5420_PSGEN_SYS_PWR_REG 0x1428
#define EXYNOS5420_PERIC_SYS_PWR_REG 0x142C
#define EXYNOS5420_WCORE_SYS_PWR_REG 0x1430
#define EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG 0x1490
#define EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG 0x1494
#define EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG 0x1498
#define EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG 0x149C
#define EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG 0x14A0
#define EXYNOS5420_CMU_CLKSTOP_FSYS2_SYS_PWR_REG 0x14A4
#define EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG 0x14A8
#define EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG 0x14AC
#define EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG 0x14B0
#define EXYNOS5420_CMU_SYSCLK_TOPPWR_SYS_PWR_REG 0x14BC
#define EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG 0x14D0
#define EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG 0x14D4
#define EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG 0x14D8
#define EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG 0x14DC
#define EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG 0x14E0
#define EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG 0x14E4
#define EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG 0x14E8
#define EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG 0x14EC
#define EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG 0x14F0
#define EXYNOS5420_CMU_SYSCLK_SYSMEM_TOPPWR_SYS_PWR_REG 0x14F4
#define EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG 0x1570
#define EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG 0x1574
#define EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG 0x1578
#define EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG 0x157C
#define EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG 0x1590
#define EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG 0x1594
#define EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG 0x1598
#define EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG 0x159C
#define EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG 0x15A0
#define EXYNOS5420_SFR_AXI_CGDIS1 0x15E4
#define EXYNOS_ARM_CORE2_CONFIGURATION 0x2100
#define EXYNOS5420_ARM_CORE2_OPTION 0x2108
#define EXYNOS_ARM_CORE3_CONFIGURATION 0x2180
#define EXYNOS5420_ARM_CORE3_OPTION 0x2188
#define EXYNOS5420_ARM_COMMON_STATUS 0x2504
#define EXYNOS5420_ARM_COMMON_OPTION 0x2508
#define EXYNOS5420_KFC_COMMON_STATUS 0x2584
#define EXYNOS5420_KFC_COMMON_OPTION 0x2588
#define EXYNOS5420_LOGIC_RESET_DURATION3 0x2D1C
#define EXYNOS5420_PAD_RET_GPIO_OPTION 0x30C8
#define EXYNOS5420_PAD_RET_UART_OPTION 0x30E8
#define EXYNOS5420_PAD_RET_MMCA_OPTION 0x3108
#define EXYNOS5420_PAD_RET_MMCB_OPTION 0x3128
#define EXYNOS5420_PAD_RET_MMCC_OPTION 0x3148
#define EXYNOS5420_PAD_RET_HSI_OPTION 0x3168
#define EXYNOS5420_PAD_RET_SPI_OPTION 0x31C8
#define EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION 0x31E8
#define EXYNOS_PAD_RET_DRAM_OPTION 0x3008
#define EXYNOS_PAD_RET_MAUDIO_OPTION 0x3028
#define EXYNOS_PAD_RET_JTAG_OPTION 0x3048
#define EXYNOS_PAD_RET_GPIO_OPTION 0x3108
#define EXYNOS_PAD_RET_UART_OPTION 0x3128
#define EXYNOS_PAD_RET_MMCA_OPTION 0x3148
#define EXYNOS_PAD_RET_MMCB_OPTION 0x3168
#define EXYNOS_PAD_RET_EBIA_OPTION 0x3188
#define EXYNOS_PAD_RET_EBIB_OPTION 0x31A8
#define EXYNOS_PS_HOLD_CONTROL 0x330C
/* For SYS_PWR_REG */
#define EXYNOS_SYS_PWR_CFG BIT(0)
#define EXYNOS5420_MFC_CONFIGURATION 0x4060
#define EXYNOS5420_MFC_STATUS 0x4064
#define EXYNOS5420_MFC_OPTION 0x4068
#define EXYNOS5420_G3D_CONFIGURATION 0x4080
#define EXYNOS5420_G3D_STATUS 0x4084
#define EXYNOS5420_G3D_OPTION 0x4088
#define EXYNOS5420_DISP0_CONFIGURATION 0x40A0
#define EXYNOS5420_DISP0_STATUS 0x40A4
#define EXYNOS5420_DISP0_OPTION 0x40A8
#define EXYNOS5420_DISP1_CONFIGURATION 0x40C0
#define EXYNOS5420_DISP1_STATUS 0x40C4
#define EXYNOS5420_DISP1_OPTION 0x40C8
#define EXYNOS5420_MAU_CONFIGURATION 0x40E0
#define EXYNOS5420_MAU_STATUS 0x40E4
#define EXYNOS5420_MAU_OPTION 0x40E8
#define EXYNOS5420_FSYS2_OPTION 0x4168
#define EXYNOS5420_PSGEN_OPTION 0x4188
/* For EXYNOS_CENTRAL_SEQ_OPTION */
#define EXYNOS5_USE_STANDBYWFI_ARM_CORE0 BIT(16)
#define EXYNOS5_USE_STANDBYWFI_ARM_CORE1 BUT(17)
#define EXYNOS5_USE_STANDBYWFE_ARM_CORE0 BIT(24)
#define EXYNOS5_USE_STANDBYWFE_ARM_CORE1 BIT(25)
#define EXYNOS5420_ARM_USE_STANDBY_WFI0 BIT(4)
#define EXYNOS5420_ARM_USE_STANDBY_WFI1 BIT(5)
#define EXYNOS5420_ARM_USE_STANDBY_WFI2 BIT(6)
#define EXYNOS5420_ARM_USE_STANDBY_WFI3 BIT(7)
#define EXYNOS5420_KFC_USE_STANDBY_WFI0 BIT(8)
#define EXYNOS5420_KFC_USE_STANDBY_WFI1 BIT(9)
#define EXYNOS5420_KFC_USE_STANDBY_WFI2 BIT(10)
#define EXYNOS5420_KFC_USE_STANDBY_WFI3 BIT(11)
#define EXYNOS5420_ARM_USE_STANDBY_WFE0 BIT(16)
#define EXYNOS5420_ARM_USE_STANDBY_WFE1 BIT(17)
#define EXYNOS5420_ARM_USE_STANDBY_WFE2 BIT(18)
#define EXYNOS5420_ARM_USE_STANDBY_WFE3 BIT(19)
#define EXYNOS5420_KFC_USE_STANDBY_WFE0 BIT(20)
#define EXYNOS5420_KFC_USE_STANDBY_WFE1 BIT(21)
#define EXYNOS5420_KFC_USE_STANDBY_WFE2 BIT(22)
#define EXYNOS5420_KFC_USE_STANDBY_WFE3 BIT(23)
#define DUR_WAIT_RESET 0xF
#define EXYNOS5420_USE_STANDBY_WFI_ALL (EXYNOS5420_ARM_USE_STANDBY_WFI0 \
| EXYNOS5420_ARM_USE_STANDBY_WFI1 \
| EXYNOS5420_ARM_USE_STANDBY_WFI2 \
| EXYNOS5420_ARM_USE_STANDBY_WFI3 \
| EXYNOS5420_KFC_USE_STANDBY_WFI0 \
| EXYNOS5420_KFC_USE_STANDBY_WFI1 \
| EXYNOS5420_KFC_USE_STANDBY_WFI2 \
| EXYNOS5420_KFC_USE_STANDBY_WFI3)
#endif /* __ASM_ARCH_REGS_PMU_H */ #endif /* __ASM_ARCH_REGS_PMU_H */
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
*/ */
#include <linux/linkage.h> #include <linux/linkage.h>
#include "smc.h"
#define CPU_MASK 0xff0ffff0 #define CPU_MASK 0xff0ffff0
#define CPU_CORTEX_A9 0x410fc090 #define CPU_CORTEX_A9 0x410fc090
...@@ -55,3 +56,30 @@ ENTRY(exynos_cpu_resume) ...@@ -55,3 +56,30 @@ ENTRY(exynos_cpu_resume)
#endif #endif
b cpu_resume b cpu_resume
ENDPROC(exynos_cpu_resume) ENDPROC(exynos_cpu_resume)
.align
ENTRY(exynos_cpu_resume_ns)
mrc p15, 0, r0, c0, c0, 0
ldr r1, =CPU_MASK
and r0, r0, r1
ldr r1, =CPU_CORTEX_A9
cmp r0, r1
bne skip_cp15
adr r0, cp15_save_power
ldr r1, [r0]
adr r0, cp15_save_diag
ldr r2, [r0]
mov r0, #SMC_CMD_C15RESUME
dsb
smc #0
skip_cp15:
b cpu_resume
ENDPROC(exynos_cpu_resume_ns)
.globl cp15_save_diag
cp15_save_diag:
.long 0 @ cp15 diagnostic
.globl cp15_save_power
cp15_save_power:
.long 0 @ cp15 power control
...@@ -26,6 +26,10 @@ ...@@ -26,6 +26,10 @@
#define SMC_CMD_L2X0INVALL (-24) #define SMC_CMD_L2X0INVALL (-24)
#define SMC_CMD_L2X0DEBUG (-25) #define SMC_CMD_L2X0DEBUG (-25)
#ifndef __ASSEMBLY__
extern void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3); extern void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3);
#endif /* __ASSEMBLY__ */
#endif #endif
/*
* Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* EXYNOS - Suspend support
*
* Based on arch/arm/mach-s3c2410/pm.c
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/suspend.h>
#include <linux/syscore_ops.h>
#include <linux/cpu_pm.h>
#include <linux/io.h>
#include <linux/irqchip/arm-gic.h>
#include <linux/err.h>
#include <linux/regulator/machine.h>
#include <asm/cacheflush.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/firmware.h>
#include <asm/mcpm.h>
#include <asm/smp_scu.h>
#include <asm/suspend.h>
#include <plat/pm-common.h>
#include <plat/regs-srom.h>
#include "common.h"
#include "regs-pmu.h"
#include "regs-sys.h"
#include "exynos-pmu.h"
#define S5P_CHECK_SLEEP 0x00000BAD
#define REG_TABLE_END (-1U)
#define EXYNOS5420_CPU_STATE 0x28
/**
* struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping
* @hwirq: Hardware IRQ signal of the GIC
* @mask: Mask in PMU wake-up mask register
*/
struct exynos_wkup_irq {
unsigned int hwirq;
u32 mask;
};
static struct sleep_save exynos5_sys_save[] = {
SAVE_ITEM(EXYNOS5_SYS_I2C_CFG),
};
static struct sleep_save exynos_core_save[] = {
/* SROM side */
SAVE_ITEM(S5P_SROM_BW),
SAVE_ITEM(S5P_SROM_BC0),
SAVE_ITEM(S5P_SROM_BC1),
SAVE_ITEM(S5P_SROM_BC2),
SAVE_ITEM(S5P_SROM_BC3),
};
struct exynos_pm_data {
const struct exynos_wkup_irq *wkup_irq;
struct sleep_save *extra_save;
int num_extra_save;
unsigned int wake_disable_mask;
unsigned int *release_ret_regs;
void (*pm_prepare)(void);
void (*pm_resume_prepare)(void);
void (*pm_resume)(void);
int (*pm_suspend)(void);
int (*cpu_suspend)(unsigned long);
};
struct exynos_pm_data *pm_data;
static int exynos5420_cpu_state;
static unsigned int exynos_pmu_spare3;
/*
* GIC wake-up support
*/
static u32 exynos_irqwake_intmask = 0xffffffff;
static const struct exynos_wkup_irq exynos4_wkup_irq[] = {
{ 76, BIT(1) }, /* RTC alarm */
{ 77, BIT(2) }, /* RTC tick */
{ /* sentinel */ },
};
static const struct exynos_wkup_irq exynos5250_wkup_irq[] = {
{ 75, BIT(1) }, /* RTC alarm */
{ 76, BIT(2) }, /* RTC tick */
{ /* sentinel */ },
};
unsigned int exynos_release_ret_regs[] = {
S5P_PAD_RET_MAUDIO_OPTION,
S5P_PAD_RET_GPIO_OPTION,
S5P_PAD_RET_UART_OPTION,
S5P_PAD_RET_MMCA_OPTION,
S5P_PAD_RET_MMCB_OPTION,
S5P_PAD_RET_EBIA_OPTION,
S5P_PAD_RET_EBIB_OPTION,
REG_TABLE_END,
};
unsigned int exynos5420_release_ret_regs[] = {
EXYNOS_PAD_RET_DRAM_OPTION,
EXYNOS_PAD_RET_MAUDIO_OPTION,
EXYNOS_PAD_RET_JTAG_OPTION,
EXYNOS5420_PAD_RET_GPIO_OPTION,
EXYNOS5420_PAD_RET_UART_OPTION,
EXYNOS5420_PAD_RET_MMCA_OPTION,
EXYNOS5420_PAD_RET_MMCB_OPTION,
EXYNOS5420_PAD_RET_MMCC_OPTION,
EXYNOS5420_PAD_RET_HSI_OPTION,
EXYNOS_PAD_RET_EBIA_OPTION,
EXYNOS_PAD_RET_EBIB_OPTION,
EXYNOS5420_PAD_RET_SPI_OPTION,
EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION,
REG_TABLE_END,
};
static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
{
const struct exynos_wkup_irq *wkup_irq;
if (!pm_data->wkup_irq)
return -ENOENT;
wkup_irq = pm_data->wkup_irq;
while (wkup_irq->mask) {
if (wkup_irq->hwirq == data->hwirq) {
if (!state)
exynos_irqwake_intmask |= wkup_irq->mask;
else
exynos_irqwake_intmask &= ~wkup_irq->mask;
return 0;
}
++wkup_irq;
}
return -ENOENT;
}
static int exynos_cpu_do_idle(void)
{
/* issue the standby signal into the pm unit. */
cpu_do_idle();
pr_info("Failed to suspend the system\n");
return 1; /* Aborting suspend */
}
static void exynos_flush_cache_all(void)
{
flush_cache_all();
outer_flush_all();
}
static int exynos_cpu_suspend(unsigned long arg)
{
exynos_flush_cache_all();
return exynos_cpu_do_idle();
}
static int exynos5420_cpu_suspend(unsigned long arg)
{
/* MCPM works with HW CPU identifiers */
unsigned int mpidr = read_cpuid_mpidr();
unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
__raw_writel(0x0, sysram_base_addr + EXYNOS5420_CPU_STATE);
if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) {
mcpm_set_entry_vector(cpu, cluster, exynos_cpu_resume);
/*
* Residency value passed to mcpm_cpu_suspend back-end
* has to be given clear semantics. Set to 0 as a
* temporary value.
*/
mcpm_cpu_suspend(0);
}
pr_info("Failed to suspend the system\n");
/* return value != 0 means failure */
return 1;
}
static void exynos_pm_set_wakeup_mask(void)
{
/* Set wake-up mask registers */
pmu_raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
pmu_raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
}
static void exynos_pm_enter_sleep_mode(void)
{
/* Set value of power down register for sleep mode */
exynos_sys_powerdown_conf(SYS_SLEEP);
pmu_raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1);
}
static void exynos_pm_prepare(void)
{
/* Set wake-up mask registers */
exynos_pm_set_wakeup_mask();
s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
if (pm_data->extra_save)
s3c_pm_do_save(pm_data->extra_save,
pm_data->num_extra_save);
exynos_pm_enter_sleep_mode();
/* ensure at least INFORM0 has the resume address */
pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
}
static void exynos5420_pm_prepare(void)
{
unsigned int tmp;
/* Set wake-up mask registers */
exynos_pm_set_wakeup_mask();
s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
exynos_pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
/*
* The cpu state needs to be saved and restored so that the
* secondary CPUs will enter low power start. Though the U-Boot
* is setting the cpu state with low power flag, the kernel
* needs to restore it back in case, the primary cpu fails to
* suspend for any reason.
*/
exynos5420_cpu_state = __raw_readl(sysram_base_addr +
EXYNOS5420_CPU_STATE);
exynos_pm_enter_sleep_mode();
/* ensure at least INFORM0 has the resume address */
if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
pmu_raw_writel(virt_to_phys(mcpm_entry_point), S5P_INFORM0);
tmp = pmu_raw_readl(EXYNOS5_ARM_L2_OPTION);
tmp &= ~EXYNOS5_USE_RETENTION;
pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION);
tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
tmp |= EXYNOS5420_UFS;
pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
tmp = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION);
tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE;
pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION);
tmp = pmu_raw_readl(EXYNOS5420_FSYS2_OPTION);
tmp |= EXYNOS5420_EMULATION;
pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
tmp = pmu_raw_readl(EXYNOS5420_PSGEN_OPTION);
tmp |= EXYNOS5420_EMULATION;
pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
}
static int exynos_pm_suspend(void)
{
exynos_pm_central_suspend();
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
exynos_cpu_save_register();
return 0;
}
static int exynos5420_pm_suspend(void)
{
u32 this_cluster;
exynos_pm_central_suspend();
/* Setting SEQ_OPTION register */
this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1);
if (!this_cluster)
pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0,
S5P_CENTRAL_SEQ_OPTION);
else
pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0,
S5P_CENTRAL_SEQ_OPTION);
return 0;
}
static void exynos_pm_release_retention(void)
{
unsigned int i;
for (i = 0; (pm_data->release_ret_regs[i] != REG_TABLE_END); i++)
pmu_raw_writel(EXYNOS_WAKEUP_FROM_LOWPWR,
pm_data->release_ret_regs[i]);
}
static void exynos_pm_resume(void)
{
u32 cpuid = read_cpuid_part();
if (exynos_pm_central_resume())
goto early_wakeup;
/* For release retention */
exynos_pm_release_retention();
if (pm_data->extra_save)
s3c_pm_do_restore_core(pm_data->extra_save,
pm_data->num_extra_save);
s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
if (cpuid == ARM_CPU_PART_CORTEX_A9)
scu_enable(S5P_VA_SCU);
if (call_firmware_op(resume) == -ENOSYS
&& cpuid == ARM_CPU_PART_CORTEX_A9)
exynos_cpu_restore_register();
early_wakeup:
/* Clear SLEEP mode set in INFORM1 */
pmu_raw_writel(0x0, S5P_INFORM1);
}
static void exynos5420_prepare_pm_resume(void)
{
if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
WARN_ON(mcpm_cpu_powered_up());
}
static void exynos5420_pm_resume(void)
{
unsigned long tmp;
/* Restore the CPU0 low power state register */
tmp = pmu_raw_readl(EXYNOS5_ARM_CORE0_SYS_PWR_REG);
pmu_raw_writel(tmp | S5P_CORE_LOCAL_PWR_EN,
EXYNOS5_ARM_CORE0_SYS_PWR_REG);
/* Restore the sysram cpu state register */
__raw_writel(exynos5420_cpu_state,
sysram_base_addr + EXYNOS5420_CPU_STATE);
pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL,
S5P_CENTRAL_SEQ_OPTION);
if (exynos_pm_central_resume())
goto early_wakeup;
/* For release retention */
exynos_pm_release_retention();
pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3);
s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
early_wakeup:
tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
tmp &= ~EXYNOS5420_UFS;
pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
tmp = pmu_raw_readl(EXYNOS5420_FSYS2_OPTION);
tmp &= ~EXYNOS5420_EMULATION;
pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
tmp = pmu_raw_readl(EXYNOS5420_PSGEN_OPTION);
tmp &= ~EXYNOS5420_EMULATION;
pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
/* Clear SLEEP mode set in INFORM1 */
pmu_raw_writel(0x0, S5P_INFORM1);
}
/*
* Suspend Ops
*/
static int exynos_suspend_enter(suspend_state_t state)
{
int ret;
s3c_pm_debug_init();
S3C_PMDBG("%s: suspending the system...\n", __func__);
S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__,
exynos_irqwake_intmask, exynos_get_eint_wake_mask());
if (exynos_irqwake_intmask == -1U
&& exynos_get_eint_wake_mask() == -1U) {
pr_err("%s: No wake-up sources!\n", __func__);
pr_err("%s: Aborting sleep\n", __func__);
return -EINVAL;
}
s3c_pm_save_uarts();
if (pm_data->pm_prepare)
pm_data->pm_prepare();
flush_cache_all();
s3c_pm_check_store();
ret = call_firmware_op(suspend);
if (ret == -ENOSYS)
ret = cpu_suspend(0, pm_data->cpu_suspend);
if (ret)
return ret;
if (pm_data->pm_resume_prepare)
pm_data->pm_resume_prepare();
s3c_pm_restore_uarts();
S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
pmu_raw_readl(S5P_WAKEUP_STAT));
s3c_pm_check_restore();
S3C_PMDBG("%s: resuming the system...\n", __func__);
return 0;
}
static int exynos_suspend_prepare(void)
{
int ret;
/*
* REVISIT: It would be better if struct platform_suspend_ops
* .prepare handler get the suspend_state_t as a parameter to
* avoid hard-coding the suspend to mem state. It's safe to do
* it now only because the suspend_valid_only_mem function is
* used as the .valid callback used to check if a given state
* is supported by the platform anyways.
*/
ret = regulator_suspend_prepare(PM_SUSPEND_MEM);
if (ret) {
pr_err("Failed to prepare regulators for suspend (%d)\n", ret);
return ret;
}
s3c_pm_check_prepare();
return 0;
}
static void exynos_suspend_finish(void)
{
int ret;
s3c_pm_check_cleanup();
ret = regulator_suspend_finish();
if (ret)
pr_warn("Failed to resume regulators from suspend (%d)\n", ret);
}
static const struct platform_suspend_ops exynos_suspend_ops = {
.enter = exynos_suspend_enter,
.prepare = exynos_suspend_prepare,
.finish = exynos_suspend_finish,
.valid = suspend_valid_only_mem,
};
static const struct exynos_pm_data exynos4_pm_data = {
.wkup_irq = exynos4_wkup_irq,
.wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
.release_ret_regs = exynos_release_ret_regs,
.pm_suspend = exynos_pm_suspend,
.pm_resume = exynos_pm_resume,
.pm_prepare = exynos_pm_prepare,
.cpu_suspend = exynos_cpu_suspend,
};
static const struct exynos_pm_data exynos5250_pm_data = {
.wkup_irq = exynos5250_wkup_irq,
.wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
.release_ret_regs = exynos_release_ret_regs,
.extra_save = exynos5_sys_save,
.num_extra_save = ARRAY_SIZE(exynos5_sys_save),
.pm_suspend = exynos_pm_suspend,
.pm_resume = exynos_pm_resume,
.pm_prepare = exynos_pm_prepare,
.cpu_suspend = exynos_cpu_suspend,
};
static struct exynos_pm_data exynos5420_pm_data = {
.wkup_irq = exynos5250_wkup_irq,
.wake_disable_mask = (0x7F << 7) | (0x1F << 1),
.release_ret_regs = exynos5420_release_ret_regs,
.pm_resume_prepare = exynos5420_prepare_pm_resume,
.pm_resume = exynos5420_pm_resume,
.pm_suspend = exynos5420_pm_suspend,
.pm_prepare = exynos5420_pm_prepare,
.cpu_suspend = exynos5420_cpu_suspend,
};
static struct of_device_id exynos_pmu_of_device_ids[] = {
{
.compatible = "samsung,exynos4210-pmu",
.data = &exynos4_pm_data,
}, {
.compatible = "samsung,exynos4212-pmu",
.data = &exynos4_pm_data,
}, {
.compatible = "samsung,exynos4412-pmu",
.data = &exynos4_pm_data,
}, {
.compatible = "samsung,exynos5250-pmu",
.data = &exynos5250_pm_data,
}, {
.compatible = "samsung,exynos5420-pmu",
.data = &exynos5420_pm_data,
},
{ /*sentinel*/ },
};
static struct syscore_ops exynos_pm_syscore_ops;
void __init exynos_pm_init(void)
{
const struct of_device_id *match;
u32 tmp;
of_find_matching_node_and_match(NULL, exynos_pmu_of_device_ids, &match);
if (!match) {
pr_err("Failed to find PMU node\n");
return;
}
pm_data = (struct exynos_pm_data *) match->data;
/* Platform-specific GIC callback */
gic_arch_extn.irq_set_wake = exynos_irq_set_wake;
/* All wakeup disable */
tmp = pmu_raw_readl(S5P_WAKEUP_MASK);
tmp |= pm_data->wake_disable_mask;
pmu_raw_writel(tmp, S5P_WAKEUP_MASK);
exynos_pm_syscore_ops.suspend = pm_data->pm_suspend;
exynos_pm_syscore_ops.resume = pm_data->pm_resume;
register_syscore_ops(&exynos_pm_syscore_ops);
suspend_set_ops(&exynos_suspend_ops);
}
...@@ -633,12 +633,41 @@ config SOC_VF610 ...@@ -633,12 +633,41 @@ config SOC_VF610
bool "Vybrid Family VF610 support" bool "Vybrid Family VF610 support"
select ARM_GIC select ARM_GIC
select PINCTRL_VF610 select PINCTRL_VF610
select VF_PIT_TIMER
select PL310_ERRATA_769419 if CACHE_L2X0 select PL310_ERRATA_769419 if CACHE_L2X0
help help
This enable support for Freescale Vybrid VF610 processor. This enable support for Freescale Vybrid VF610 processor.
choice
prompt "Clocksource for scheduler clock"
depends on SOC_VF610
default VF_USE_ARM_GLOBAL_TIMER
config VF_USE_ARM_GLOBAL_TIMER
bool "Use ARM Global Timer"
select ARM_GLOBAL_TIMER
select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
help
Use the ARM Global Timer as clocksource
config VF_USE_PIT_TIMER
bool "Use PIT timer"
select VF_PIT_TIMER
help
Use SoC Periodic Interrupt Timer (PIT) as clocksource
endchoice
config SOC_LS1021A
bool "Freescale LS1021A support"
select ARM_GIC
select HAVE_ARM_ARCH_TIMER
select PCI_DOMAINS if PCI
select ZONE_DMA if ARM_LPAE
help
This enable support for Freescale LS1021A processor.
endif endif
source "arch/arm/mach-imx/devices/Kconfig" source "arch/arm/mach-imx/devices/Kconfig"
......
...@@ -12,7 +12,7 @@ obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci- ...@@ -12,7 +12,7 @@ obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-
obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o
imx5-pm-$(CONFIG_PM) += pm-imx5.o imx5-pm-$(CONFIG_PM) += pm-imx5.o
obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o clk-imx51-imx53.o $(imx5-pm-y) obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o clk-imx51-imx53.o clk-cpu.o $(imx5-pm-y)
obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
clk-pfd.o clk-busy.o clk.o \ clk-pfd.o clk-busy.o clk.o \
...@@ -89,7 +89,7 @@ obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o ...@@ -89,7 +89,7 @@ obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
obj-$(CONFIG_HAVE_IMX_SRC) += src.o obj-$(CONFIG_HAVE_IMX_SRC) += src.o
ifdef CONFIG_SOC_IMX6 ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),)
AFLAGS_headsmp.o :=-Wa,-march=armv7-a AFLAGS_headsmp.o :=-Wa,-march=armv7-a
obj-$(CONFIG_SMP) += headsmp.o platsmp.o obj-$(CONFIG_SMP) += headsmp.o platsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
...@@ -110,4 +110,6 @@ obj-$(CONFIG_SOC_IMX53) += mach-imx53.o ...@@ -110,4 +110,6 @@ obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o
obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o
obj-y += devices/ obj-y += devices/
...@@ -30,8 +30,11 @@ ...@@ -30,8 +30,11 @@
#define ANADIG_DIGPROG_IMX6SL 0x280 #define ANADIG_DIGPROG_IMX6SL 0x280
#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 #define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000
#define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN 0x8
#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000 #define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000
#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000 #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000
/* Below MISC0_DISCON_HIGH_SNVS is only for i.MX6SL */
#define BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS 0x2000
#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000 #define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000
#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000 #define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000
...@@ -56,16 +59,43 @@ static void imx_anatop_enable_fet_odrive(bool enable) ...@@ -56,16 +59,43 @@ static void imx_anatop_enable_fet_odrive(bool enable)
BM_ANADIG_REG_CORE_FET_ODRIVE); BM_ANADIG_REG_CORE_FET_ODRIVE);
} }
static inline void imx_anatop_enable_2p5_pulldown(bool enable)
{
regmap_write(anatop, ANADIG_REG_2P5 + (enable ? REG_SET : REG_CLR),
BM_ANADIG_REG_2P5_ENABLE_PULLDOWN);
}
static inline void imx_anatop_disconnect_high_snvs(bool enable)
{
regmap_write(anatop, ANADIG_ANA_MISC0 + (enable ? REG_SET : REG_CLR),
BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS);
}
void imx_anatop_pre_suspend(void) void imx_anatop_pre_suspend(void)
{ {
imx_anatop_enable_weak2p5(true); if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
imx_anatop_enable_2p5_pulldown(true);
else
imx_anatop_enable_weak2p5(true);
imx_anatop_enable_fet_odrive(true); imx_anatop_enable_fet_odrive(true);
if (cpu_is_imx6sl())
imx_anatop_disconnect_high_snvs(true);
} }
void imx_anatop_post_resume(void) void imx_anatop_post_resume(void)
{ {
if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
imx_anatop_enable_2p5_pulldown(false);
else
imx_anatop_enable_weak2p5(false);
imx_anatop_enable_fet_odrive(false); imx_anatop_enable_fet_odrive(false);
imx_anatop_enable_weak2p5(false);
if (cpu_is_imx6sl())
imx_anatop_disconnect_high_snvs(false);
} }
static void imx_anatop_usb_chrg_detect_disable(void) static void imx_anatop_usb_chrg_detect_disable(void)
......
/*
* Copyright (c) 2014 Lucas Stach <l.stach@pengutronix.de>, Pengutronix
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/slab.h>
struct clk_cpu {
struct clk_hw hw;
struct clk *div;
struct clk *mux;
struct clk *pll;
struct clk *step;
};
static inline struct clk_cpu *to_clk_cpu(struct clk_hw *hw)
{
return container_of(hw, struct clk_cpu, hw);
}
static unsigned long clk_cpu_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_cpu *cpu = to_clk_cpu(hw);
return clk_get_rate(cpu->div);
}
static long clk_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
struct clk_cpu *cpu = to_clk_cpu(hw);
return clk_round_rate(cpu->pll, rate);
}
static int clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_cpu *cpu = to_clk_cpu(hw);
int ret;
/* switch to PLL bypass clock */
ret = clk_set_parent(cpu->mux, cpu->step);
if (ret)
return ret;
/* reprogram PLL */
ret = clk_set_rate(cpu->pll, rate);
if (ret) {
clk_set_parent(cpu->mux, cpu->pll);
return ret;
}
/* switch back to PLL clock */
clk_set_parent(cpu->mux, cpu->pll);
/* Ensure the divider is what we expect */
clk_set_rate(cpu->div, rate);
return 0;
}
static const struct clk_ops clk_cpu_ops = {
.recalc_rate = clk_cpu_recalc_rate,
.round_rate = clk_cpu_round_rate,
.set_rate = clk_cpu_set_rate,
};
struct clk *imx_clk_cpu(const char *name, const char *parent_name,
struct clk *div, struct clk *mux, struct clk *pll,
struct clk *step)
{
struct clk_cpu *cpu;
struct clk *clk;
struct clk_init_data init;
cpu = kzalloc(sizeof(*cpu), GFP_KERNEL);
if (!cpu)
return ERR_PTR(-ENOMEM);
cpu->div = div;
cpu->mux = mux;
cpu->pll = pll;
cpu->step = step;
init.name = name;
init.ops = &clk_cpu_ops;
init.flags = 0;
init.parent_names = &parent_name;
init.num_parents = 1;
cpu->hw.init = &init;
clk = clk_register(NULL, &cpu->hw);
if (IS_ERR(clk))
kfree(cpu);
return clk;
}
...@@ -125,6 +125,8 @@ static const char *mx53_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", "pll4_sw", ...@@ -125,6 +125,8 @@ static const char *mx53_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", "pll4_sw",
static const char *spdif_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "spdif_xtal_sel", }; static const char *spdif_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "spdif_xtal_sel", };
static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", }; static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", };
static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", }; static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", };
static const char *step_sels[] = { "lp_apm", };
static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" };
static struct clk *clk[IMX5_CLK_END]; static struct clk *clk[IMX5_CLK_END];
static struct clk_onecell_data clk_data; static struct clk_onecell_data clk_data;
...@@ -193,7 +195,9 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base) ...@@ -193,7 +195,9 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base)
clk[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3); clk[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3);
clk[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1, clk[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1,
usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str)); usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
clk[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3); clk[IMX5_CLK_STEP_SEL] = imx_clk_mux("step_sel", MXC_CCM_CCSR, 7, 2, step_sels, ARRAY_SIZE(step_sels));
clk[IMX5_CLK_CPU_PODF_SEL] = imx_clk_mux("cpu_podf_sel", MXC_CCM_CCSR, 2, 1, cpu_podf_sels, ARRAY_SIZE(cpu_podf_sels));
clk[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf", "cpu_podf_sel", MXC_CCM_CACRR, 0, 3);
clk[IMX5_CLK_DI_PRED] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); clk[IMX5_CLK_DI_PRED] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3);
clk[IMX5_CLK_IIM_GATE] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); clk[IMX5_CLK_IIM_GATE] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30);
clk[IMX5_CLK_UART1_IPG_GATE] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); clk[IMX5_CLK_UART1_IPG_GATE] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6);
...@@ -537,6 +541,11 @@ static void __init mx53_clocks_init(struct device_node *np) ...@@ -537,6 +541,11 @@ static void __init mx53_clocks_init(struct device_node *np)
clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24); clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel)); mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel));
clk[IMX5_CLK_ARM] = imx_clk_cpu("arm", "cpu_podf",
clk[IMX5_CLK_CPU_PODF],
clk[IMX5_CLK_CPU_PODF_SEL],
clk[IMX5_CLK_PLL1_SW],
clk[IMX5_CLK_STEP_SEL]);
imx_check_clocks(clk, ARRAY_SIZE(clk)); imx_check_clocks(clk, ARRAY_SIZE(clk));
...@@ -551,6 +560,9 @@ static void __init mx53_clocks_init(struct device_node *np) ...@@ -551,6 +560,9 @@ static void __init mx53_clocks_init(struct device_node *np)
/* move can bus clk to 24MHz */ /* move can bus clk to 24MHz */
clk_set_parent(clk[IMX5_CLK_CAN_SEL], clk[IMX5_CLK_LP_APM]); clk_set_parent(clk[IMX5_CLK_CAN_SEL], clk[IMX5_CLK_LP_APM]);
/* make sure step clock is running from 24MHz */
clk_set_parent(clk[IMX5_CLK_STEP_SEL], clk[IMX5_CLK_LP_APM]);
clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]); clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]);
imx_print_silicon_rev("i.MX53", mx53_revision()); imx_print_silicon_rev("i.MX53", mx53_revision());
clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]); clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]);
......
...@@ -120,6 +120,17 @@ static unsigned int const clks_init_on[] __initconst = { ...@@ -120,6 +120,17 @@ static unsigned int const clks_init_on[] __initconst = {
VF610_CLK_DDR_SEL, VF610_CLK_DDR_SEL,
}; };
static struct clk * __init vf610_get_fixed_clock(
struct device_node *ccm_node, const char *name)
{
struct clk *clk = of_clk_get_by_name(ccm_node, name);
/* Backward compatibility if device tree is missing clks assignments */
if (IS_ERR(clk))
clk = imx_obtain_fixed_clock(name, 0);
return clk;
};
static void __init vf610_clocks_init(struct device_node *ccm_node) static void __init vf610_clocks_init(struct device_node *ccm_node)
{ {
struct device_node *np; struct device_node *np;
...@@ -130,13 +141,13 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) ...@@ -130,13 +141,13 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
clk[VF610_CLK_SIRC_32K] = imx_clk_fixed("sirc_32k", 32000); clk[VF610_CLK_SIRC_32K] = imx_clk_fixed("sirc_32k", 32000);
clk[VF610_CLK_FIRC] = imx_clk_fixed("firc", 24000000); clk[VF610_CLK_FIRC] = imx_clk_fixed("firc", 24000000);
clk[VF610_CLK_SXOSC] = imx_obtain_fixed_clock("sxosc", 0); clk[VF610_CLK_SXOSC] = vf610_get_fixed_clock(ccm_node, "sxosc");
clk[VF610_CLK_FXOSC] = imx_obtain_fixed_clock("fxosc", 0); clk[VF610_CLK_FXOSC] = vf610_get_fixed_clock(ccm_node, "fxosc");
clk[VF610_CLK_AUDIO_EXT] = imx_obtain_fixed_clock("audio_ext", 0); clk[VF610_CLK_AUDIO_EXT] = vf610_get_fixed_clock(ccm_node, "audio_ext");
clk[VF610_CLK_ENET_EXT] = imx_obtain_fixed_clock("enet_ext", 0); clk[VF610_CLK_ENET_EXT] = vf610_get_fixed_clock(ccm_node, "enet_ext");
/* Clock source from external clock via LVDs PAD */ /* Clock source from external clock via LVDs PAD */
clk[VF610_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0); clk[VF610_CLK_ANACLK1] = vf610_get_fixed_clock(ccm_node, "anaclk1");
clk[VF610_CLK_FXOSC_HALF] = imx_clk_fixed_factor("fxosc_half", "fxosc", 1, 2); clk[VF610_CLK_FXOSC_HALF] = imx_clk_fixed_factor("fxosc_half", "fxosc", 1, 2);
......
...@@ -131,4 +131,8 @@ static inline struct clk *imx_clk_fixed_factor(const char *name, ...@@ -131,4 +131,8 @@ static inline struct clk *imx_clk_fixed_factor(const char *name,
CLK_SET_RATE_PARENT, mult, div); CLK_SET_RATE_PARENT, mult, div);
} }
struct clk *imx_clk_cpu(const char *name, const char *parent_name,
struct clk *div, struct clk *mux, struct clk *pll,
struct clk *step);
#endif #endif
...@@ -115,6 +115,7 @@ void imx_anatop_post_resume(void); ...@@ -115,6 +115,7 @@ void imx_anatop_post_resume(void);
int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
void imx6q_set_int_mem_clk_lpm(bool enable); void imx6q_set_int_mem_clk_lpm(bool enable);
void imx6sl_set_wait_clk(bool enter); void imx6sl_set_wait_clk(bool enter);
int imx_mmdc_get_ddr_type(void);
void imx_cpu_die(unsigned int cpu); void imx_cpu_die(unsigned int cpu);
int imx_cpu_kill(unsigned int cpu); int imx_cpu_kill(unsigned int cpu);
...@@ -156,5 +157,6 @@ static inline void imx_init_l2cache(void) {} ...@@ -156,5 +157,6 @@ static inline void imx_init_l2cache(void) {}
#endif #endif
extern struct smp_operations imx_smp_ops; extern struct smp_operations imx_smp_ops;
extern struct smp_operations ls1021a_smp_ops;
#endif #endif
...@@ -40,6 +40,8 @@ static void __init imx53_dt_init(void) ...@@ -40,6 +40,8 @@ static void __init imx53_dt_init(void)
static void __init imx53_init_late(void) static void __init imx53_init_late(void)
{ {
imx53_pm_init(); imx53_pm_init();
platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
} }
static const char * const imx53_dt_board_compat[] __initconst = { static const char * const imx53_dt_board_compat[] __initconst = {
......
...@@ -8,12 +8,62 @@ ...@@ -8,12 +8,62 @@
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/phy.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include "common.h" #include "common.h"
#include "cpuidle.h" #include "cpuidle.h"
static int ar8031_phy_fixup(struct phy_device *dev)
{
u16 val;
/* Set RGMII IO voltage to 1.8V */
phy_write(dev, 0x1d, 0x1f);
phy_write(dev, 0x1e, 0x8);
/* introduce tx clock delay */
phy_write(dev, 0x1d, 0x5);
val = phy_read(dev, 0x1e);
val |= 0x0100;
phy_write(dev, 0x1e, val);
return 0;
}
#define PHY_ID_AR8031 0x004dd074
static void __init imx6sx_enet_phy_init(void)
{
if (IS_BUILTIN(CONFIG_PHYLIB))
phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
ar8031_phy_fixup);
}
static void __init imx6sx_enet_clk_sel(void)
{
struct regmap *gpr;
gpr = syscon_regmap_lookup_by_compatible("fsl,imx6sx-iomuxc-gpr");
if (!IS_ERR(gpr)) {
regmap_update_bits(gpr, IOMUXC_GPR1,
IMX6SX_GPR1_FEC_CLOCK_MUX_SEL_MASK, 0);
regmap_update_bits(gpr, IOMUXC_GPR1,
IMX6SX_GPR1_FEC_CLOCK_PAD_DIR_MASK, 0);
} else {
pr_err("failed to find fsl,imx6sx-iomux-gpr regmap\n");
}
}
static inline void imx6sx_enet_init(void)
{
imx6sx_enet_phy_init();
imx6sx_enet_clk_sel();
}
static void __init imx6sx_init_machine(void) static void __init imx6sx_init_machine(void)
{ {
struct device *parent; struct device *parent;
...@@ -24,6 +74,7 @@ static void __init imx6sx_init_machine(void) ...@@ -24,6 +74,7 @@ static void __init imx6sx_init_machine(void)
of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
imx6sx_enet_init();
imx_anatop_init(); imx_anatop_init();
imx6sx_pm_init(); imx6sx_pm_init();
} }
......
/*
* Copyright 2013-2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <asm/mach/arch.h>
#include "common.h"
static const char * const ls1021a_dt_compat[] __initconst = {
"fsl,ls1021a",
NULL,
};
DT_MACHINE_START(LS1021A, "Freescale LS1021A")
.smp = smp_ops(ls1021a_smp_ops),
.dt_compat = ls1021a_dt_compat,
MACHINE_END
...@@ -21,6 +21,12 @@ ...@@ -21,6 +21,12 @@
#define BP_MMDC_MAPSR_PSD 0 #define BP_MMDC_MAPSR_PSD 0
#define BP_MMDC_MAPSR_PSS 4 #define BP_MMDC_MAPSR_PSS 4
#define MMDC_MDMISC 0x18
#define BM_MMDC_MDMISC_DDR_TYPE 0x18
#define BP_MMDC_MDMISC_DDR_TYPE 0x3
static int ddr_type;
static int imx_mmdc_probe(struct platform_device *pdev) static int imx_mmdc_probe(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
...@@ -31,6 +37,12 @@ static int imx_mmdc_probe(struct platform_device *pdev) ...@@ -31,6 +37,12 @@ static int imx_mmdc_probe(struct platform_device *pdev)
mmdc_base = of_iomap(np, 0); mmdc_base = of_iomap(np, 0);
WARN_ON(!mmdc_base); WARN_ON(!mmdc_base);
reg = mmdc_base + MMDC_MDMISC;
/* Get ddr type */
val = readl_relaxed(reg);
ddr_type = (val & BM_MMDC_MDMISC_DDR_TYPE) >>
BP_MMDC_MDMISC_DDR_TYPE;
reg = mmdc_base + MMDC_MAPSR; reg = mmdc_base + MMDC_MAPSR;
/* Enable automatic power saving */ /* Enable automatic power saving */
...@@ -51,6 +63,11 @@ static int imx_mmdc_probe(struct platform_device *pdev) ...@@ -51,6 +63,11 @@ static int imx_mmdc_probe(struct platform_device *pdev)
return 0; return 0;
} }
int imx_mmdc_get_ddr_type(void)
{
return ddr_type;
}
static struct of_device_id imx_mmdc_dt_ids[] = { static struct of_device_id imx_mmdc_dt_ids[] = {
{ .compatible = "fsl,imx6q-mmdc", }, { .compatible = "fsl,imx6q-mmdc", },
{ /* sentinel */ } { /* sentinel */ }
......
...@@ -55,6 +55,8 @@ ...@@ -55,6 +55,8 @@
#define IMX_CHIP_REVISION_3_3 0x33 #define IMX_CHIP_REVISION_3_3 0x33
#define IMX_CHIP_REVISION_UNKNOWN 0xff #define IMX_CHIP_REVISION_UNKNOWN 0xff
#define IMX_DDR_TYPE_LPDDR2 1
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
extern unsigned int __mxc_cpu_type; extern unsigned int __mxc_cpu_type;
#endif #endif
......
...@@ -11,7 +11,10 @@ ...@@ -11,7 +11,10 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
...@@ -94,3 +97,33 @@ struct smp_operations imx_smp_ops __initdata = { ...@@ -94,3 +97,33 @@ struct smp_operations imx_smp_ops __initdata = {
.cpu_kill = imx_cpu_kill, .cpu_kill = imx_cpu_kill,
#endif #endif
}; };
#define DCFG_CCSR_SCRATCHRW1 0x200
static int ls1021a_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
arch_send_wakeup_ipi_mask(cpumask_of(cpu));
return 0;
}
static void __init ls1021a_smp_prepare_cpus(unsigned int max_cpus)
{
struct device_node *np;
void __iomem *dcfg_base;
unsigned long paddr;
np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcfg");
dcfg_base = of_iomap(np, 0);
BUG_ON(!dcfg_base);
paddr = virt_to_phys(secondary_startup);
writel_relaxed(cpu_to_be32(paddr), dcfg_base + DCFG_CCSR_SCRATCHRW1);
iounmap(dcfg_base);
}
struct smp_operations ls1021a_smp_ops __initdata = {
.smp_prepare_cpus = ls1021a_smp_prepare_cpus,
.smp_boot_secondary = ls1021a_boot_secondary,
};
...@@ -88,7 +88,7 @@ struct imx6_pm_base { ...@@ -88,7 +88,7 @@ struct imx6_pm_base {
}; };
struct imx6_pm_socdata { struct imx6_pm_socdata {
u32 cpu_type; u32 ddr_type;
const char *mmdc_compat; const char *mmdc_compat;
const char *src_compat; const char *src_compat;
const char *iomuxc_compat; const char *iomuxc_compat;
...@@ -138,7 +138,6 @@ static const u32 imx6sx_mmdc_io_offset[] __initconst = { ...@@ -138,7 +138,6 @@ static const u32 imx6sx_mmdc_io_offset[] __initconst = {
}; };
static const struct imx6_pm_socdata imx6q_pm_data __initconst = { static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
.cpu_type = MXC_CPU_IMX6Q,
.mmdc_compat = "fsl,imx6q-mmdc", .mmdc_compat = "fsl,imx6q-mmdc",
.src_compat = "fsl,imx6q-src", .src_compat = "fsl,imx6q-src",
.iomuxc_compat = "fsl,imx6q-iomuxc", .iomuxc_compat = "fsl,imx6q-iomuxc",
...@@ -148,7 +147,6 @@ static const struct imx6_pm_socdata imx6q_pm_data __initconst = { ...@@ -148,7 +147,6 @@ static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
}; };
static const struct imx6_pm_socdata imx6dl_pm_data __initconst = { static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
.cpu_type = MXC_CPU_IMX6DL,
.mmdc_compat = "fsl,imx6q-mmdc", .mmdc_compat = "fsl,imx6q-mmdc",
.src_compat = "fsl,imx6q-src", .src_compat = "fsl,imx6q-src",
.iomuxc_compat = "fsl,imx6dl-iomuxc", .iomuxc_compat = "fsl,imx6dl-iomuxc",
...@@ -158,7 +156,6 @@ static const struct imx6_pm_socdata imx6dl_pm_data __initconst = { ...@@ -158,7 +156,6 @@ static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
}; };
static const struct imx6_pm_socdata imx6sl_pm_data __initconst = { static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
.cpu_type = MXC_CPU_IMX6SL,
.mmdc_compat = "fsl,imx6sl-mmdc", .mmdc_compat = "fsl,imx6sl-mmdc",
.src_compat = "fsl,imx6sl-src", .src_compat = "fsl,imx6sl-src",
.iomuxc_compat = "fsl,imx6sl-iomuxc", .iomuxc_compat = "fsl,imx6sl-iomuxc",
...@@ -168,7 +165,6 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = { ...@@ -168,7 +165,6 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
}; };
static const struct imx6_pm_socdata imx6sx_pm_data __initconst = { static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
.cpu_type = MXC_CPU_IMX6SX,
.mmdc_compat = "fsl,imx6sx-mmdc", .mmdc_compat = "fsl,imx6sx-mmdc",
.src_compat = "fsl,imx6sx-src", .src_compat = "fsl,imx6sx-src",
.iomuxc_compat = "fsl,imx6sx-iomuxc", .iomuxc_compat = "fsl,imx6sx-iomuxc",
...@@ -187,7 +183,7 @@ static const struct imx6_pm_socdata imx6sx_pm_data __initconst = { ...@@ -187,7 +183,7 @@ static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
struct imx6_cpu_pm_info { struct imx6_cpu_pm_info {
phys_addr_t pbase; /* The physical address of pm_info. */ phys_addr_t pbase; /* The physical address of pm_info. */
phys_addr_t resume_addr; /* The physical resume address for asm code */ phys_addr_t resume_addr; /* The physical resume address for asm code */
u32 cpu_type; u32 ddr_type;
u32 pm_info_size; /* Size of pm_info. */ u32 pm_info_size; /* Size of pm_info. */
struct imx6_pm_base mmdc_base; struct imx6_pm_base mmdc_base;
struct imx6_pm_base src_base; struct imx6_pm_base src_base;
...@@ -521,7 +517,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) ...@@ -521,7 +517,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
goto pl310_cache_map_failed; goto pl310_cache_map_failed;
} }
pm_info->cpu_type = socdata->cpu_type; pm_info->ddr_type = imx_mmdc_get_ddr_type();
pm_info->mmdc_io_num = socdata->mmdc_io_num; pm_info->mmdc_io_num = socdata->mmdc_io_num;
mmdc_offset_array = socdata->mmdc_io_offset; mmdc_offset_array = socdata->mmdc_io_offset;
......
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
*/ */
#define PM_INFO_PBASE_OFFSET 0x0 #define PM_INFO_PBASE_OFFSET 0x0
#define PM_INFO_RESUME_ADDR_OFFSET 0x4 #define PM_INFO_RESUME_ADDR_OFFSET 0x4
#define PM_INFO_CPU_TYPE_OFFSET 0x8 #define PM_INFO_DDR_TYPE_OFFSET 0x8
#define PM_INFO_PM_INFO_SIZE_OFFSET 0xC #define PM_INFO_PM_INFO_SIZE_OFFSET 0xC
#define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10 #define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10
#define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14 #define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14
...@@ -110,7 +110,7 @@ ...@@ -110,7 +110,7 @@
ldreq r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET] ldreq r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
ldrne r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET] ldrne r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
cmp r3, #MXC_CPU_IMX6SL cmp r3, #IMX_DDR_TYPE_LPDDR2
bne 4f bne 4f
/* reset read FIFO, RST_RD_FIFO */ /* reset read FIFO, RST_RD_FIFO */
...@@ -151,7 +151,7 @@ ...@@ -151,7 +151,7 @@
ENTRY(imx6_suspend) ENTRY(imx6_suspend)
ldr r1, [r0, #PM_INFO_PBASE_OFFSET] ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET] ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
ldr r3, [r0, #PM_INFO_CPU_TYPE_OFFSET] ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET] ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
/* /*
...@@ -209,8 +209,8 @@ poll_dvfs_set: ...@@ -209,8 +209,8 @@ poll_dvfs_set:
ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET] ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
add r8, r8, r0 add r8, r8, r0
/* i.MX6SL's last 3 IOs need special setting */ /* LPDDR2's last 3 IOs need special setting */
cmp r3, #MXC_CPU_IMX6SL cmp r3, #IMX_DDR_TYPE_LPDDR2
subeq r7, r7, #0x3 subeq r7, r7, #0x3
set_mmdc_io_lpm: set_mmdc_io_lpm:
ldr r9, [r8], #0x8 ldr r9, [r8], #0x8
...@@ -218,7 +218,7 @@ set_mmdc_io_lpm: ...@@ -218,7 +218,7 @@ set_mmdc_io_lpm:
subs r7, r7, #0x1 subs r7, r7, #0x1
bne set_mmdc_io_lpm bne set_mmdc_io_lpm
cmp r3, #MXC_CPU_IMX6SL cmp r3, #IMX_DDR_TYPE_LPDDR2
bne set_mmdc_io_lpm_done bne set_mmdc_io_lpm_done
ldr r6, =0x1000 ldr r6, =0x1000
ldr r9, [r8], #0x8 ldr r9, [r8], #0x8
...@@ -324,7 +324,7 @@ resume: ...@@ -324,7 +324,7 @@ resume:
str r7, [r11, #MX6Q_SRC_GPR1] str r7, [r11, #MX6Q_SRC_GPR1]
str r7, [r11, #MX6Q_SRC_GPR2] str r7, [r11, #MX6Q_SRC_GPR2]
ldr r3, [r0, #PM_INFO_CPU_TYPE_OFFSET] ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
mov r5, #0x1 mov r5, #0x1
resume_mmdc resume_mmdc
......
config ARCH_INTEGRATOR
bool "ARM Ltd. Integrator family" if (ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6)
select ARM_AMBA
select ARM_PATCH_PHYS_VIRT if MMU
select AUTO_ZRELADDR
select COMMON_CLK
select COMMON_CLK_VERSATILE
select GENERIC_CLOCKEVENTS
select HAVE_TCM
select ICST
select MFD_SYSCON
select MULTI_IRQ_HANDLER
select PLAT_VERSATILE
select POWER_RESET
select POWER_RESET_VERSATILE
select POWER_SUPPLY
select SOC_INTEGRATOR_CM
select SPARSE_IRQ
select USE_OF
select VERSATILE_FPGA_IRQ
help
Support for ARM's Integrator platform.
if ARCH_INTEGRATOR if ARCH_INTEGRATOR
menu "Integrator Options" menu "Integrator Options"
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Object file lists. # Object file lists.
obj-y := core.o lm.o leds.o obj-y := core.o lm.o
obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o
obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o
......
...@@ -11,7 +11,6 @@ void cm_clear_irqs(void); ...@@ -11,7 +11,6 @@ void cm_clear_irqs(void);
#define CM_CTRL_LED (1 << 0) #define CM_CTRL_LED (1 << 0)
#define CM_CTRL_nMBDET (1 << 1) #define CM_CTRL_nMBDET (1 << 1)
#define CM_CTRL_REMAP (1 << 2) #define CM_CTRL_REMAP (1 << 2)
#define CM_CTRL_RESET (1 << 3)
/* /*
* Integrator/AP,PP2 specific * Integrator/AP,PP2 specific
......
...@@ -4,5 +4,3 @@ extern struct amba_pl010_data ap_uart_data; ...@@ -4,5 +4,3 @@ extern struct amba_pl010_data ap_uart_data;
void integrator_init_early(void); void integrator_init_early(void);
int integrator_init(bool is_cp); int integrator_init(bool is_cp);
void integrator_reserve(void); void integrator_reserve(void);
void integrator_restart(enum reboot_mode, const char *);
void integrator_init_sysfs(struct device *parent, u32 id);
...@@ -60,40 +60,6 @@ void cm_control(u32 mask, u32 set) ...@@ -60,40 +60,6 @@ void cm_control(u32 mask, u32 set)
raw_spin_unlock_irqrestore(&cm_lock, flags); raw_spin_unlock_irqrestore(&cm_lock, flags);
} }
static const char *integrator_arch_str(u32 id)
{
switch ((id >> 16) & 0xff) {
case 0x00:
return "ASB little-endian";
case 0x01:
return "AHB little-endian";
case 0x03:
return "AHB-Lite system bus, bi-endian";
case 0x04:
return "AHB";
case 0x08:
return "AHB system bus, ASB processor bus";
default:
return "Unknown";
}
}
static const char *integrator_fpga_str(u32 id)
{
switch ((id >> 12) & 0xf) {
case 0x01:
return "XC4062";
case 0x02:
return "XC4085";
case 0x03:
return "XVC600";
case 0x04:
return "EPM7256AE (Altera PLD)";
default:
return "Unknown";
}
}
void cm_clear_irqs(void) void cm_clear_irqs(void)
{ {
/* disable core module IRQs */ /* disable core module IRQs */
...@@ -109,7 +75,6 @@ static const struct of_device_id cm_match[] = { ...@@ -109,7 +75,6 @@ static const struct of_device_id cm_match[] = {
void cm_init(void) void cm_init(void)
{ {
struct device_node *cm = of_find_matching_node(NULL, cm_match); struct device_node *cm = of_find_matching_node(NULL, cm_match);
u32 val;
if (!cm) { if (!cm) {
pr_crit("no core module node found in device tree\n"); pr_crit("no core module node found in device tree\n");
...@@ -121,13 +86,6 @@ void cm_init(void) ...@@ -121,13 +86,6 @@ void cm_init(void)
return; return;
} }
cm_clear_irqs(); cm_clear_irqs();
val = readl(cm_base + INTEGRATOR_HDR_ID_OFFSET);
pr_info("Detected ARM core module:\n");
pr_info(" Manufacturer: %02x\n", (val >> 24));
pr_info(" Architecture: %s\n", integrator_arch_str(val));
pr_info(" FPGA: %s\n", integrator_fpga_str(val));
pr_info(" Build: %02x\n", (val >> 4) & 0xFF);
pr_info(" Rev: %c\n", ('A' + (val & 0x03)));
} }
/* /*
...@@ -139,64 +97,3 @@ void __init integrator_reserve(void) ...@@ -139,64 +97,3 @@ void __init integrator_reserve(void)
{ {
memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET); memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
} }
/*
* To reset, we hit the on-board reset register in the system FPGA
*/
void integrator_restart(enum reboot_mode mode, const char *cmd)
{
cm_control(CM_CTRL_RESET, CM_CTRL_RESET);
}
static u32 integrator_id;
static ssize_t intcp_get_manf(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%02x\n", integrator_id >> 24);
}
static struct device_attribute intcp_manf_attr =
__ATTR(manufacturer, S_IRUGO, intcp_get_manf, NULL);
static ssize_t intcp_get_arch(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%s\n", integrator_arch_str(integrator_id));
}
static struct device_attribute intcp_arch_attr =
__ATTR(architecture, S_IRUGO, intcp_get_arch, NULL);
static ssize_t intcp_get_fpga(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%s\n", integrator_fpga_str(integrator_id));
}
static struct device_attribute intcp_fpga_attr =
__ATTR(fpga, S_IRUGO, intcp_get_fpga, NULL);
static ssize_t intcp_get_build(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%02x\n", (integrator_id >> 4) & 0xFF);
}
static struct device_attribute intcp_build_attr =
__ATTR(build, S_IRUGO, intcp_get_build, NULL);
void integrator_init_sysfs(struct device *parent, u32 id)
{
integrator_id = id;
device_create_file(parent, &intcp_manf_attr);
device_create_file(parent, &intcp_arch_attr);
device_create_file(parent, &intcp_fpga_attr);
device_create_file(parent, &intcp_build_attr);
}
/*
* arch/arm/mach-integrator/include/mach/uncompress.h
*
* Copyright (C) 1999 ARM Limited
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define AMBA_UART_DR (*(volatile unsigned char *)0x16000000)
#define AMBA_UART_LCRH (*(volatile unsigned char *)0x16000008)
#define AMBA_UART_LCRM (*(volatile unsigned char *)0x1600000c)
#define AMBA_UART_LCRL (*(volatile unsigned char *)0x16000010)
#define AMBA_UART_CR (*(volatile unsigned char *)0x16000014)
#define AMBA_UART_FR (*(volatile unsigned char *)0x16000018)
/*
* This does not append a newline
*/
static void putc(int c)
{
while (AMBA_UART_FR & (1 << 5))
barrier();
AMBA_UART_DR = c;
}
static inline void flush(void)
{
while (AMBA_UART_FR & (1 << 3))
barrier();
}
/*
* nothing to do
*/
#define arch_decomp_setup()
此差异已折叠。
config ARCH_MEDIATEK config ARCH_MEDIATEK
bool "Mediatek MT6589 SoC" if ARCH_MULTI_V7 bool "Mediatek MT65xx & MT81xx SoC" if ARCH_MULTI_V7
select ARM_GIC select ARM_GIC
select MTK_TIMER select MTK_TIMER
help help
Support for Mediatek Cortex-A7 Quad-Core-SoC MT6589. Support for Mediatek MT65xx & MT81xx SoCs
...@@ -2,6 +2,7 @@ menuconfig ARCH_MESON ...@@ -2,6 +2,7 @@ menuconfig ARCH_MESON
bool "Amlogic Meson SoCs" if ARCH_MULTI_V7 bool "Amlogic Meson SoCs" if ARCH_MULTI_V7
select GENERIC_IRQ_CHIP select GENERIC_IRQ_CHIP
select ARM_GIC select ARM_GIC
select CACHE_L2X0
if ARCH_MESON if ARCH_MESON
...@@ -10,4 +11,9 @@ config MACH_MESON6 ...@@ -10,4 +11,9 @@ config MACH_MESON6
default ARCH_MESON default ARCH_MESON
select MESON6_TIMER select MESON6_TIMER
config MACH_MESON8
bool "Amlogic Meson8 SoCs support"
default ARCH_MESON
select MESON6_TIMER
endif endif
此差异已折叠。
...@@ -7,7 +7,7 @@ CFLAGS_pmsu.o := -march=armv7-a ...@@ -7,7 +7,7 @@ CFLAGS_pmsu.o := -march=armv7-a
obj-$(CONFIG_MACH_MVEBU_ANY) += system-controller.o mvebu-soc-id.o obj-$(CONFIG_MACH_MVEBU_ANY) += system-controller.o mvebu-soc-id.o
ifeq ($(CONFIG_MACH_MVEBU_V7),y) ifeq ($(CONFIG_MACH_MVEBU_V7),y)
obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o pm.o pm-board.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o
endif endif
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册