1
0
Fork 0

ARM: SoC: platform support for v4.2

Our SoC branch usually contains expanded support for new SoCs and
 other core platform code. Some highlights from this round:
 
 - sunxi: SMP support for A23 SoC
 - socpga: big-endian support
 - pxa: conversion to common clock framework
 - bcm: SMP support for BCM63138
 - imx: support new I.MX7D SoC
 - zte: basic support for ZX296702 SoC
 
  Conflicts:
 	arch/arm/mach-socfpga/core.h
 
 Trivial remove/remove conflict with our cleanup branch.
 Resolution: remove both sides
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJVi4RMAAoJEFk3GJrT+8Zl6/kP/1Rv9O++1Kxua6R54Og6AF1J
 0miFr2fnUrUWUYg/NVbseRH5bBe6N6ir3SQMfde8W2/QibEjOoEwSwrle+mC/eiq
 CE0x0gtyRvXMrMU/FWkOvbmmw9uv5oz1z3IHZV6AiecNuSMLUBPfamryikQ8C+d1
 O/QZtX543tJQJDOBihO5cuhoVVM37UX0unNmqGsyswlyqTPF8FxcIJAYVNtnxjmj
 AFaOB0nDJKLKFTiX2Ype2wOxxJX1lrLatNo4W4T+YaaK+i1uCOhgTdSN+n49K7YA
 KNDFEgZFQqT8VMJyG+eJVeYF+cI7yWQ7lBzIftPUjPk/7+dIHBjWPz2QdjVz3U38
 kxncf4S9xGAF5G2rcKe4mFrfT3Y8QLWQpA/jFs06yLwW1O3Hlfq3DzMdGNcF7hth
 17LOP8namn9+NepZEp/vAlFzRRypxWWtbkPNBIItkImC6zn0IiGjBy50DE1io27W
 hmQcnMb7d+0wWl2Y8OmR2lZSB97JiRZkRYMCVHVt+0zGJzp4prLvl9wbjh1VXkPv
 ERCDJ9nCmZsl7ZVmIXMI7KNXYuPNp7R/QAzCvuSUueswF0qxTAQ0VSSBwRMqvQsQ
 UUNC6p63VnjUeMUdn2EBsUQZ0Uqw3t2U5TtvooHNt9FkiGsSpwjWrvVD+LItaPoJ
 GPeeJrJaYQsDvTrO8wjU
 =ZtPK
 -----END PGP SIGNATURE-----

Merge tag 'armsoc-soc' into test-merge

ARM: SoC: platform support for v4.2

Our SoC branch usually contains expanded support for new SoCs and
other core platform code. Some highlights from this round:

- sunxi: SMP support for A23 SoC
- socpga: big-endian support
- pxa: conversion to common clock framework
- bcm: SMP support for BCM63138
- imx: support new I.MX7D SoC
- zte: basic support for ZX296702 SoC

 Conflicts:
	arch/arm/mach-socfpga/core.h

Trivial remove/remove conflict with our cleanup branch.
Resolution: remove both sides

# gpg: Signature made Wed Jun 24 21:32:12 2015 PDT using RSA key ID D3FBC665
# gpg: Good signature from "Kevin Hilman <khilman@deeprootsystems.com>"
# gpg:                 aka "Kevin Hilman <khilman@linaro.org>"
# gpg:                 aka "Kevin Hilman <khilman@kernel.org>"

# Conflicts:
#	arch/arm/mach-socfpga/core.h
hifive-unleashed-5.1
Kevin Hilman 2015-06-24 21:32:13 -07:00
commit 03fa626774
225 changed files with 6677 additions and 2077 deletions

View File

@ -0,0 +1,32 @@
STM32 ARM Linux Overview
========================
Introduction
------------
The STMicroelectronics family of Cortex-M based MCUs are supported by the
'STM32' platform of ARM Linux. Currently only the STM32F429 is supported.
Configuration
-------------
A generic configuration is provided for STM32 family, and can be used as the
default by
make stm32_defconfig
Layout
------
All the files for multiple machine families are located in the platform code
contained in arch/arm/mach-stm32
There is a generic board board-dt.c in the mach folder which support
Flattened Device Tree, which means, it works with any compatible board with
Device Trees.
Document Author
---------------
Maxime Coquelin <mcoquelin.stm32@gmail.com>

View File

@ -0,0 +1,22 @@
STM32F429 Overview
==================
Introduction
------------
The STM32F429 is a Cortex-M4 MCU aimed at various applications.
It features:
- ARM Cortex-M4 up to 180MHz with FPU
- 2MB internal Flash Memory
- External memory support through FMC controller (PSRAM, SDRAM, NOR, NAND)
- I2C, SPI, SAI, CAN, USB OTG, Ethernet controllers
- LCD controller & Camera interface
- Cryptographic processor
Resources
---------
Datasheet and reference manual are publicly available on ST website:
- http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1577/LN1806?ecmp=stm32f429-439_pron_pr-ces2014_nov2013
Document Author
---------------
Maxime Coquelin <mcoquelin.stm32@gmail.com>

View File

@ -188,6 +188,7 @@ nodes to be present and contain the properties described below.
# On ARM 32-bit systems this property is optional and
can be one of:
"allwinner,sun6i-a31"
"allwinner,sun8i-a23"
"arm,psci"
"brcm,brahma-b15"
"marvell,armada-375-smp"

View File

@ -19,9 +19,10 @@ Optional Properties:
domains.
- clock-names: The following clocks can be specified:
- oscclk: Oscillator clock.
- pclkN, clkN: Pairs of parent of input clock and input clock to the
devices in this power domain. Maximum of 4 pairs (N = 0 to 3)
are supported currently.
- clkN: Input clocks to the devices in this power domain. These clocks
will be reparented to oscclk before swithing power domain off.
Their original parent will be brought back after turning on
the domain. Maximum of 4 clocks (N = 0 to 3) are supported.
- asbN: Clocks required by asynchronous bridges (ASB) present in
the power domain. These clock should be enabled during power
domain on/off operations.

View File

@ -81,12 +81,15 @@ Freescale Vybrid Platform Device Tree Bindings
For the Vybrid SoC familiy all variants with DDR controller are supported,
which is the VF5xx and VF6xx series. Out of historical reasons, in most
places the kernel uses vf610 to refer to the whole familiy.
The compatible string "fsl,vf610m4" is used for the secondary Cortex-M4
core support.
Required root node compatible property (one of them):
- compatible = "fsl,vf500";
- compatible = "fsl,vf510";
- compatible = "fsl,vf600";
- compatible = "fsl,vf610";
- compatible = "fsl,vf610m4";
Freescale LS1021A Platform Device Tree Bindings
------------------------------------------------

View File

@ -0,0 +1,15 @@
ZTE platforms device tree bindings
---------------------------------------
- ZX296702 board:
Required root node properties:
- compatible = "zte,zx296702-ad1", "zte,zx296702"
System management required properties:
- compatible = "zte,sysctrl"
Low power management required properties:
- compatible = "zte,zx296702-pcu"
Bus matrix required properties:
- compatible = "zte,zx-bus-matrix"

View File

@ -0,0 +1,35 @@
Device Tree Clock bindings for ZTE zx296702
This binding uses the common clock binding[1].
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible : shall be one of the following:
"zte,zx296702-topcrm-clk":
zx296702 top clock selection, divider and gating
"zte,zx296702-lsp0crpm-clk" and
"zte,zx296702-lsp1crpm-clk":
zx296702 device level clock selection and gating
- reg: Address and length of the register set
The clock consumer should specify the desired clock by having the clock
ID in its "clocks" phandle cell. See include/dt-bindings/clock/zx296702-clock.h
for the full list of zx296702 clock IDs.
topclk: topcrm@0x09800000 {
compatible = "zte,zx296702-topcrm-clk";
reg = <0x09800000 0x1000>;
#clock-cells = <1>;
};
uart0: serial@0x09405000 {
compatible = "zte,zx296702-uart";
reg = <0x09405000 0x1000>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&lsp1clk ZX296702_UART0_PCLK>;
status = "disabled";
};

View File

@ -1,7 +1,7 @@
* ARM AMBA Primecell PL011 serial UART
Required properties:
- compatible: must be "arm,primecell", "arm,pl011"
- compatible: must be "arm,primecell", "arm,pl011", "zte,zx296702-uart"
- reg: exactly one register range with length 0x1000
- interrupts: exactly one interrupt specifier

View File

@ -211,3 +211,4 @@ xillybus Xillybus Ltd.
xlnx Xilinx
zyxel ZyXEL Communications Corp.
zarlink Zarlink Semiconductor
zte ZTE Corp.

View File

@ -1035,7 +1035,7 @@ F: arch/arm/include/asm/hardware/dec21285.h
F: arch/arm/mach-footbridge/
ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
M: Shawn Guo <shawn.guo@linaro.org>
M: Shawn Guo <shawnguo@kernel.org>
M: Sascha Hauer <kernel@pengutronix.de>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
@ -1044,9 +1044,11 @@ F: arch/arm/mach-imx/
F: arch/arm/mach-mxs/
F: arch/arm/boot/dts/imx*
F: arch/arm/configs/imx*_defconfig
F: drivers/clk/imx/
F: include/soc/imx/
ARM/FREESCALE VYBRID ARM ARCHITECTURE
M: Shawn Guo <shawn.guo@linaro.org>
M: Shawn Guo <shawnguo@kernel.org>
M: Sascha Hauer <kernel@pengutronix.de>
R: Stefan Agner <stefan@agner.ch>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@ -1189,6 +1191,12 @@ M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
ARM/LPC18XX ARCHITECTURE
M: Joachim Eastwood <manabian@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
N: lpc18xx
ARM/MAGICIAN MACHINE SUPPORT
M: Philipp Zabel <philipp.zabel@gmail.com>
S: Maintained
@ -1385,6 +1393,7 @@ L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/boot/dts/s3c*
F: arch/arm/boot/dts/exynos*
F: arch/arm64/boot/dts/exynos/
F: arch/arm/plat-samsung/
F: arch/arm/mach-s3c24*/
F: arch/arm/mach-s3c64xx/
@ -1494,6 +1503,14 @@ F: drivers/usb/host/ehci-st.c
F: drivers/usb/host/ohci-st.c
F: drivers/ata/ahci_st.c
ARM/STM32 ARCHITECTURE
M: Maxime Coquelin <mcoquelin.stm32@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/stm32.git
N: stm32
F: drivers/clocksource/armv7m_systick.c
ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@ -1540,6 +1557,13 @@ F: drivers/rtc/rtc-ab3100.c
F: drivers/rtc/rtc-coh901331.c
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
ARM/UNIPHIER ARCHITECTURE
M: Masahiro Yamada <yamada.masahiro@socionext.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-uniphier/
N: uniphier
ARM/Ux500 ARM ARCHITECTURE
M: Linus Walleij <linus.walleij@linaro.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@ -1617,6 +1641,15 @@ S: Maintained
F: arch/arm/mach-pxa/z2.c
F: arch/arm/mach-pxa/include/mach/z2.h
ARM/ZTE ARCHITECTURE
M: Jun Nie <jun.nie@linaro.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-zx/
F: drivers/clk/zte/
F: Documentation/devicetree/bindings/arm/zte.txt
F: Documentation/devicetree/bindings/clock/zx296702-clk.txt
ARM/ZYNQ ARCHITECTURE
M: Michal Simek <michal.simek@xilinx.com>
R: Sören Brinkmann <soren.brinkmann@xilinx.com>
@ -2193,6 +2226,7 @@ S: Maintained
F: arch/arm/mach-bcm/*brcmstb*
F: arch/arm/boot/dts/bcm7*.dts*
F: drivers/bus/brcmstb_gisb.c
N: brcmstb
BROADCOM BMIPS MIPS ARCHITECTURE
M: Kevin Cernekee <cernekee@gmail.com>

View File

@ -329,6 +329,20 @@ config ARCH_MULTIPLATFORM
select SPARSE_IRQ
select USE_OF
config ARM_SINGLE_ARMV7M
bool "ARMv7-M based platforms (Cortex-M0/M3/M4)"
depends on !MMU
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_NVIC
select AUTO_ZRELADDR
select CLKSRC_OF
select COMMON_CLK
select CPU_V7M
select GENERIC_CLOCKEVENTS
select NO_IOPORT_MAP
select SPARSE_IRQ
select USE_OF
config ARCH_REALVIEW
bool "ARM Ltd. RealView family"
select ARCH_WANT_OPTIONAL_GPIOLIB
@ -398,24 +412,6 @@ config ARCH_EBSA110
Ethernet interface, two PCMCIA sockets, two serial ports and a
parallel port.
config ARCH_EFM32
bool "Energy Micro efm32"
depends on !MMU
select ARCH_REQUIRE_GPIOLIB
select ARM_NVIC
select AUTO_ZRELADDR
select CLKSRC_OF
select COMMON_CLK
select CPU_V7M
select GENERIC_CLOCKEVENTS
select NO_DMA
select NO_IOPORT_MAP
select SPARSE_IRQ
select USE_OF
help
Support for Energy Micro's (now Silicon Labs) efm32 Giant Gecko
processors.
config ARCH_EP93XX
bool "EP93xx-based"
select ARCH_HAS_HOLES_MEMORYMODEL
@ -606,6 +602,7 @@ config ARCH_PXA
select ARCH_REQUIRE_GPIOLIB
select ARM_CPU_SUSPEND if PM
select AUTO_ZRELADDR
select COMMON_CLK
select CLKDEV_LOOKUP
select CLKSRC_MMIO
select CLKSRC_OF
@ -752,8 +749,10 @@ config ARCH_OMAP1
select GENERIC_IRQ_CHIP
select HAVE_IDE
select IRQ_DOMAIN
select MULTI_IRQ_HANDLER
select NEED_MACH_IO_H if PCCARD
select NEED_MACH_MEMORY_H
select SPARSE_IRQ
help
Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
@ -937,6 +936,8 @@ source "arch/arm/mach-tegra/Kconfig"
source "arch/arm/mach-u300/Kconfig"
source "arch/arm/mach-uniphier/Kconfig"
source "arch/arm/mach-ux500/Kconfig"
source "arch/arm/mach-versatile/Kconfig"
@ -948,8 +949,40 @@ source "arch/arm/mach-vt8500/Kconfig"
source "arch/arm/mach-w90x900/Kconfig"
source "arch/arm/mach-zx/Kconfig"
source "arch/arm/mach-zynq/Kconfig"
# ARMv7-M architecture
config ARCH_EFM32
bool "Energy Micro efm32"
depends on ARM_SINGLE_ARMV7M
select ARCH_REQUIRE_GPIOLIB
help
Support for Energy Micro's (now Silicon Labs) efm32 Giant Gecko
processors.
config ARCH_LPC18XX
bool "NXP LPC18xx/LPC43xx"
depends on ARM_SINGLE_ARMV7M
select ARCH_HAS_RESET_CONTROLLER
select ARM_AMBA
select CLKSRC_LPC32XX
select PINCTRL
help
Support for NXP's LPC18xx Cortex-M3 and LPC43xx Cortex-M4
high performance microcontrollers.
config ARCH_STM32
bool "STMicrolectronics STM32"
depends on ARM_SINGLE_ARMV7M
select ARCH_HAS_RESET_CONTROLLER
select ARMV7M_SYSTICK
select CLKSRC_STM32
select RESET_CONTROLLER
help
Support for STMicroelectronics STM32 processors.
# Definitions to make life easier
config ARCH_ACORN
bool
@ -1477,7 +1510,8 @@ config ARM_PSCI
# selected platforms.
config ARCH_NR_GPIO
int
default 1024 if ARCH_SHMOBILE || ARCH_TEGRA || ARCH_ZYNQ
default 1024 if ARCH_BRCMSTB || ARCH_SHMOBILE || ARCH_TEGRA || \
ARCH_ZYNQ
default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \
SOC_DRA7XX || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210
default 416 if ARCH_SUNXI

View File

@ -410,6 +410,13 @@ choice
Say Y here if you want kernel low-level debugging support
on i.MX6SX.
config DEBUG_IMX7D_UART
bool "i.MX7D Debug UART"
depends on SOC_IMX7D
help
Say Y here if you want kernel low-level debugging support
on i.MX7D.
config DEBUG_KEYSTONE_UART0
bool "Kernel low-level debugging on KEYSTONE2 using UART0"
depends on ARCH_KEYSTONE
@ -433,6 +440,14 @@ choice
Say Y here if you want kernel low-level debugging support
on KS8695.
config DEBUG_LPC18XX_UART0
bool "Kernel low-level debugging via LPC18xx/43xx UART0"
depends on ARCH_LPC18XX
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
on NXP LPC18xx/43xx UART0.
config DEBUG_MESON_UARTAO
bool "Kernel low-level debugging via Meson6 UARTAO"
depends on ARCH_MESON
@ -908,13 +923,22 @@ choice
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_UART0
depends on ARCH_SOCFPGA
bool "Use SOCFPGA UART for low-level debug"
bool "Use SOCFPGA UART0 for low-level debug"
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
on SOCFPGA based platforms.
on SOCFPGA(Cyclone 5 and Arria 5) based platforms.
config DEBUG_SOCFPGA_UART1
depends on ARCH_SOCFPGA
bool "Use SOCFPGA UART1 for low-level debug"
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
on SOCFPGA(Arria 10) based platforms.
config DEBUG_SUN9I_UART0
bool "Kernel low-level debugging messages via sun9i UART0"
@ -1157,6 +1181,18 @@ choice
For more details about semihosting, please see
chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd.
config DEBUG_ZTE_ZX
bool "Use ZTE ZX UART"
select DEBUG_UART_PL01X
depends on ARCH_ZX
help
Say Y here if you are enabling ZTE ZX296702 SOC and need
debug uart support.
This option is preferred over the platform specific
options; the platform specific options are deprecated
and will be soon removed.
config DEBUG_LL_UART_8250
bool "Kernel low-level debugging via 8250 UART"
help
@ -1231,7 +1267,8 @@ config DEBUG_IMX_UART_PORT
DEBUG_IMX53_UART || \
DEBUG_IMX6Q_UART || \
DEBUG_IMX6SL_UART || \
DEBUG_IMX6SX_UART
DEBUG_IMX6SX_UART || \
DEBUG_IMX7D_UART
default 1
depends on ARCH_MXC
help
@ -1281,7 +1318,8 @@ config DEBUG_LL_INCLUDE
DEBUG_IMX53_UART ||\
DEBUG_IMX6Q_UART || \
DEBUG_IMX6SL_UART || \
DEBUG_IMX6SX_UART
DEBUG_IMX6SX_UART || \
DEBUG_IMX7D_UART
default "debug/ks8695.S" if DEBUG_KS8695_UART
default "debug/msm.S" if DEBUG_QCOM_UARTDM
default "debug/netx.S" if DEBUG_NETX_UART
@ -1337,6 +1375,7 @@ config DEBUG_UART_PHYS
default 0x02531000 if DEBUG_KEYSTONE_UART1
default 0x03010fe0 if ARCH_RPC
default 0x07000000 if DEBUG_SUN9I_UART0
default 0x09405000 if DEBUG_ZTE_ZX
default 0x10009000 if DEBUG_REALVIEW_STD_PORT || \
DEBUG_VEXPRESS_UART0_CA9
default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT
@ -1359,6 +1398,7 @@ config DEBUG_UART_PHYS
default 0x20201000 if DEBUG_BCM2835
default 0x3e000000 if DEBUG_BCM_KONA_UART
default 0x4000e400 if DEBUG_LL_UART_EFM32
default 0x40081000 if DEBUG_LPC18XX_UART0
default 0x40090000 if ARCH_LPC32XX
default 0x40100000 if DEBUG_PXA_UART1
default 0x42000000 if ARCH_GEMINI
@ -1407,7 +1447,8 @@ config DEBUG_UART_PHYS
default 0xfd883000 if DEBUG_ALPINE_UART0
default 0xfe800000 if ARCH_IOP32X
default 0xff690000 if DEBUG_RK32_UART2
default 0xffc02000 if DEBUG_SOCFPGA_UART
default 0xffc02000 if DEBUG_SOCFPGA_UART0
default 0xffc02100 if DEBUG_SOCFPGA_UART1
default 0xffd82340 if ARCH_IOP13XX
default 0xffe40000 if DEBUG_RCAR_GEN1_SCIF0
default 0xffe42000 if DEBUG_RCAR_GEN1_SCIF2
@ -1466,6 +1507,7 @@ config DEBUG_UART_VIRT
default 0xfb009000 if DEBUG_REALVIEW_STD_PORT
default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT
default 0xfc40ab00 if DEBUG_BRCMSTB_UART
default 0xfc705000 if DEBUG_ZTE_ZX
default 0xfcfe8600 if DEBUG_UART_BCM63XX
default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
default 0xfd000000 if ARCH_SPEAR13XX
@ -1485,7 +1527,8 @@ config DEBUG_UART_VIRT
default 0xfeb26000 if DEBUG_RK3X_UART1
default 0xfeb30c00 if DEBUG_KEYSTONE_UART0
default 0xfeb31000 if DEBUG_KEYSTONE_UART1
default 0xfec02000 if DEBUG_SOCFPGA_UART
default 0xfec02000 if DEBUG_SOCFPGA_UART0
default 0xfec02100 if DEBUG_SOCFPGA_UART1
default 0xfec12000 if DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE
default 0xfec12100 if DEBUG_MVEBU_UART1_ALTERNATE
default 0xfec10000 if DEBUG_SIRFATLAS7_UART0
@ -1530,8 +1573,9 @@ config DEBUG_UART_8250_WORD
bool "Use 32-bit accesses for 8250 UART"
depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
depends on DEBUG_UART_8250_SHIFT >= 2
default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART || \
ARCH_KEYSTONE || DEBUG_ALPINE_UART0 || \
default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART0 || \
DEBUG_SOCFPGA_UART1 || ARCH_KEYSTONE || \
DEBUG_ALPINE_UART0 || \
DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
DEBUG_DAVINCI_DA8XX_UART2 || \
DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 || \
@ -1544,7 +1588,7 @@ config DEBUG_UART_8250_FLOW_CONTROL
config DEBUG_UNCOMPRESS
bool
depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG
depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG || ARM_SINGLE_ARMV7M
default y if DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \
(!DEBUG_TEGRA_UART || !ZBOOT_ROM)
help
@ -1561,7 +1605,7 @@ config DEBUG_UNCOMPRESS
config UNCOMPRESS_INCLUDE
string
default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM || \
PLAT_SAMSUNG || ARCH_EFM32 || \
PLAT_SAMSUNG || ARM_SINGLE_ARMV7M || \
ARCH_SHMOBILE_LEGACY
default "mach/uncompress.h"

View File

@ -167,6 +167,7 @@ machine-$(CONFIG_ARCH_IOP33X) += iop33x
machine-$(CONFIG_ARCH_IXP4XX) += ixp4xx
machine-$(CONFIG_ARCH_KEYSTONE) += keystone
machine-$(CONFIG_ARCH_KS8695) += ks8695
machine-$(CONFIG_ARCH_LPC18XX) += lpc18xx
machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx
machine-$(CONFIG_ARCH_MESON) += meson
machine-$(CONFIG_ARCH_MMP) += mmp
@ -196,14 +197,17 @@ machine-$(CONFIG_ARCH_SHMOBILE) += shmobile
machine-$(CONFIG_ARCH_SIRF) += prima2
machine-$(CONFIG_ARCH_SOCFPGA) += socfpga
machine-$(CONFIG_ARCH_STI) += sti
machine-$(CONFIG_ARCH_STM32) += stm32
machine-$(CONFIG_ARCH_SUNXI) += sunxi
machine-$(CONFIG_ARCH_TEGRA) += tegra
machine-$(CONFIG_ARCH_U300) += u300
machine-$(CONFIG_ARCH_U8500) += ux500
machine-$(CONFIG_ARCH_UNIPHIER) += uniphier
machine-$(CONFIG_ARCH_VERSATILE) += versatile
machine-$(CONFIG_ARCH_VEXPRESS) += vexpress
machine-$(CONFIG_ARCH_VT8500) += vt8500
machine-$(CONFIG_ARCH_W90X900) += w90x900
machine-$(CONFIG_ARCH_ZX) += zx
machine-$(CONFIG_ARCH_ZYNQ) += zynq
machine-$(CONFIG_PLAT_SPEAR) += spear

View File

@ -660,6 +660,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
mt6592-evb.dtb \
mt8127-moose.dtb \
mt8135-evbp1.dtb
dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb
endif
always := $(dtb-y)

View File

@ -0,0 +1,48 @@
/dts-v1/;
#include "zx296702.dtsi"
/ {
model = "ZTE ZX296702 AD1 Board";
compatible = "zte,zx296702-ad1", "zte,zx296702";
aliases {
serial0 = &uart0;
serial1 = &uart1;
};
memory {
reg = <0x50000000 0x20000000>;
};
};
&mmc0 {
num-slots = <1>;
supports-highspeed;
non-removable;
disable-wp;
status = "okay";
slot@0 {
reg = <0>;
bus-width = <4>;
};
};
&mmc1 {
num-slots = <1>;
supports-highspeed;
non-removable;
disable-wp;
status = "okay";
slot@0 {
reg = <0>;
bus-width = <8>;
};
};
&uart0 {
status = "okay";
};

View File

@ -0,0 +1,139 @@
#include "skeleton.dtsi"
#include <dt-bindings/clock/zx296702-clock.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
cpus {
#address-cells = <1>;
#size-cells = <0>;
enable-method = "zte,zx296702-smp";
cpu@0 {
compatible = "arm,cortex-a9";
device_type = "cpu";
next-level-cache = <&l2cc>;
reg = <0>;
};
cpu@1 {
compatible = "arm,cortex-a9";
device_type = "cpu";
next-level-cache = <&l2cc>;
reg = <1>;
};
};
soc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
interrupt-parent = <&intc>;
ranges;
matrix: bus-matrix@400000 {
compatible = "zte,zx-bus-matrix";
reg = <0x00400000 0x1000>;
};
intc: interrupt-controller@00801000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
#address-cells = <1>;
#size-cells = <1>;
interrupt-controller;
reg = <0x00801000 0x1000>,
<0x00800100 0x100>;
};
global_timer: timer@008000200 {
compatible = "arm,cortex-a9-global-timer";
reg = <0x00800200 0x20>;
interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&intc>;
clocks = <&topclk ZX296702_A9_PERIPHCLK>;
};
l2cc: l2-cache-controller@0x00c00000 {
compatible = "arm,pl310-cache";
reg = <0x00c00000 0x1000>;
cache-unified;
cache-level = <2>;
arm,data-latency = <1 1 1>;
arm,tag-latency = <1 1 1>;
arm,double-linefill = <1>;
arm,double-linefill-incr = <0>;
};
pcu: pcu@0xa0008000 {
compatible = "zte,zx296702-pcu";
reg = <0xa0008000 0x1000>;
};
topclk: topclk@0x09800000 {
compatible = "zte,zx296702-topcrm-clk";
reg = <0x09800000 0x1000>;
#clock-cells = <1>;
};
lsp1clk: lsp1clk@0x09400000 {
compatible = "zte,zx296702-lsp1crpm-clk";
reg = <0x09400000 0x1000>;
#clock-cells = <1>;
};
lsp0clk: lsp0clk@0x0b000000 {
compatible = "zte,zx296702-lsp0crpm-clk";
reg = <0x0b000000 0x1000>;
#clock-cells = <1>;
};
uart0: serial@0x09405000 {
compatible = "zte,zx296702-uart";
reg = <0x09405000 0x1000>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&lsp1clk ZX296702_UART0_WCLK>;
status = "disabled";
};
uart1: serial@0x09406000 {
compatible = "zte,zx296702-uart";
reg = <0x09406000 0x1000>;
interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&lsp1clk ZX296702_UART1_WCLK>;
status = "disabled";
};
mmc0: mmc@0x09408000 {
compatible = "snps,dw-mshc";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x09408000 0x1000>;
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
fifo-depth = <32>;
clocks = <&lsp1clk ZX296702_SDMMC0_PCLK>,
<&lsp1clk ZX296702_SDMMC0_WCLK>;
clock-names = "biu", "ciu";
status = "disabled";
};
mmc1: mmc@0x0b003000 {
compatible = "snps,dw-mshc";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0b003000 0x1000>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
fifo-depth = <32>;
clocks = <&lsp0clk ZX296702_SDMMC1_PCLK>,
<&lsp0clk ZX296702_SDMMC1_WCLK>;
clock-names = "biu", "ciu";
status = "disabled";
};
sysctrl: sysctrl@0xa0007000 {
compatible = "zte,sysctrl", "syscon";
reg = <0xa0007000 0x1000>;
};
};
};

View File

@ -16,6 +16,7 @@ CONFIG_EMBEDDED=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
# CONFIG_MMU is not set
CONFIG_ARM_SINGLE_ARMV7M=y
CONFIG_ARCH_EFM32=y
CONFIG_SET_MEM_PARAM=y
CONFIG_DRAM_BASE=0x88000000

View File

@ -0,0 +1,129 @@
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CGROUPS=y
CONFIG_CGROUP_DEBUG=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
CONFIG_SLAB=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARCH_ZX=y
CONFIG_SOC_ZX296702=y
# CONFIG_SWP_EMULATE is not set
CONFIG_ARM_ERRATA_754322=y
CONFIG_ARM_ERRATA_775420=y
CONFIG_SMP=y
CONFIG_VMSPLIT_2G=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_KSM=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_VFP=y
CONFIG_NEON=y
CONFIG_KERNEL_MODE_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_HIBERNATION=y
CONFIG_PM_RUNTIME=y
CONFIG_PM_DEBUG=y
CONFIG_SUSPEND_TIME=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="console=ttyAMA0,115200 debug earlyprintk root=/dev/ram rw rootwait"
#CONFIG_NET is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DMA_CMA=y
CONFIG_CMA_SIZE_MBYTES=192
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=1
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_UID_STAT=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SCH=y
CONFIG_SCSI_MULTI_LUN=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_NETDEVICES=y
# CONFIG_INPUT_MOUSE is not set
CONFIG_SERIO=y
CONFIG_SERIO_LIBPS2=y
CONFIG_SPI=y
CONFIG_LOGO=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_CONSOLE_POLL=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_MMC=y
CONFIG_MMC_UNSAFE_RESUME=y
CONFIG_MMC_BLOCK_MINORS=16
CONFIG_MMC_DW=y
CONFIG_MMC_DW_IDMAC=y
CONFIG_EXT2_FS=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXT4_DEBUG=y
CONFIG_FUSE_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=936
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
#CONFIG_NFS_FS is not set
CONFIG_NLS_CODEPAGE_936=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_UTF8=y
CONFIG_PRINTK_TIME=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_INFO=y
CONFIG_FRAME_WARN=4096
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_PANIC_TIMEOUT=5
# CONFIG_SCHED_DEBUG is not set
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_RCU_CPU_STALL_TIMEOUT=60
# CONFIG_FTRACE is not set
CONFIG_KGDB=y
CONFIG_KGDB_KDB=y
# CONFIG_ARM_UNWIND is not set
CONFIG_DEBUG_PREEMPT=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_LL=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_STACKTRACE=y
CONFIG_DEBUG_ZTE_ZX=y
CONFIG_EARLY_PRINTK=y
CONFIG_CRYPTO_LZO=y
CONFIG_GPIOLIB=y

View File

@ -33,6 +33,10 @@ struct firmware_ops {
* Sets boot address of specified physical CPU
*/
int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr);
/*
* Gets boot address of specified physical CPU
*/
int (*get_cpu_boot_addr)(int cpu, unsigned long *boot_addr);
/*
* Boots specified physical CPU
*/

View File

@ -5,6 +5,9 @@
* First, the standard VFP set.
*/
#ifndef __ASM_VFP_H
#define __ASM_VFP_H
#define FPSID cr0
#define FPSCR cr1
#define MVFR1 cr6
@ -87,3 +90,9 @@
#define VFPOPDESC_UNUSED_BIT (24)
#define VFPOPDESC_UNUSED_MASK (0xFF << VFPOPDESC_UNUSED_BIT)
#define VFPOPDESC_OPDESC_MASK (~(VFPOPDESC_LENGTH_MASK | VFPOPDESC_UNUSED_MASK))
#ifndef __ASSEMBLY__
void vfp_disable(void);
#endif
#endif /* __ASM_VFP_H */

View File

@ -16,11 +16,14 @@
#ifdef CONFIG_DEBUG_UART_8250_WORD
.macro store, rd, rx:vararg
ARM_BE8(rev \rd, \rd)
str \rd, \rx
ARM_BE8(rev \rd, \rd)
.endm
.macro load, rd, rx:vararg
ldr \rd, \rx
ARM_BE8(rev \rd, \rd)
.endm
#else
.macro store, rd, rx:vararg

View File

@ -16,7 +16,7 @@
#define UARTn_TXDATA 0x0034
.macro addruart, rx, tmp
.macro addruart, rx, tmp, tmp2
ldr \rx, =(CONFIG_DEBUG_UART_PHYS)
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2012 Freescale Semiconductor, Inc.
* Copyright (C) 2012-2015 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 version 2 as
@ -90,6 +90,16 @@
#define IMX6SX_UART_BASE_ADDR(n) IMX6SX_UART##n##_BASE_ADDR
#define IMX6SX_UART_BASE(n) IMX6SX_UART_BASE_ADDR(n)
#define IMX7D_UART1_BASE_ADDR 0x30860000
#define IMX7D_UART2_BASE_ADDR 0x30890000
#define IMX7D_UART3_BASE_ADDR 0x30880000
#define IMX7D_UART4_BASE_ADDR 0x30a60000
#define IMX7D_UART5_BASE_ADDR 0x30a70000
#define IMX7D_UART6_BASE_ADDR 0x30a80000
#define IMX7D_UART7_BASE_ADDR 0x30a90000
#define IMX7D_UART_BASE_ADDR(n) IMX7D_UART##n##_BASE_ADDR
#define IMX7D_UART_BASE(n) IMX7D_UART_BASE_ADDR(n)
#define IMX_DEBUG_UART_BASE(soc) soc##_UART_BASE(CONFIG_DEBUG_IMX_UART_PORT)
#ifdef CONFIG_DEBUG_IMX1_UART
@ -114,6 +124,9 @@
#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SL)
#elif defined(CONFIG_DEBUG_IMX6SX_UART)
#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SX)
#elif defined(CONFIG_DEBUG_IMX7D_UART)
#define UART_PADDR IMX_DEBUG_UART_BASE(IMX7D)
#endif
#endif /* __DEBUG_IMX_UART_H */

View File

@ -12,6 +12,13 @@
*/
#include <linux/amba/serial.h>
#ifdef CONFIG_DEBUG_ZTE_ZX
#undef UART01x_DR
#undef UART01x_FR
#define UART01x_DR 0x04
#define UART01x_FR 0x14
#endif
#ifdef CONFIG_DEBUG_UART_PHYS
.macro addruart, rp, rv, tmp
ldr \rp, =CONFIG_DEBUG_UART_PHYS

View File

@ -35,7 +35,7 @@
#else /* !CONFIG_MMU */
.macro addruart_current, rx, tmp1, tmp2
addruart \rx, \tmp1
addruart \rx, \tmp1, \tmp2
.endm
#endif /* CONFIG_MMU */

View File

@ -19,6 +19,7 @@ config ARCH_BCM_IPROC
select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
select PINCTRL
select MTD_NAND_BRCMNAND
help
This enables support for systems based on Broadcom IPROC architected SoCs.
The IPROC complex contains one or more ARM CPUs along with common
@ -144,6 +145,7 @@ config ARCH_BRCMSTB
select BRCMSTB_GISB_ARB
select BRCMSTB_L2_IRQ
select BCM7120_L2_IRQ
select ARCH_WANT_OPTIONAL_GPIOLIB
help
Say Y if you intend to run the kernel on a Broadcom ARM-based STB
chipset.

View File

@ -38,7 +38,12 @@ obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o
obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
# BCM63XXx
obj-$(CONFIG_ARCH_BCM_63XX) := bcm63xx.o
ifeq ($(CONFIG_ARCH_BCM_63XX),y)
CFLAGS_bcm63xx_headsmp.o += -march=armv7-a
obj-y += bcm63xx.o
obj-$(CONFIG_SMP) += bcm63xx_smp.o bcm63xx_headsmp.o \
bcm63xx_pmb.o
endif
ifeq ($(CONFIG_ARCH_BRCMSTB),y)
CFLAGS_platsmp-brcmstb.o += -march=armv7-a

View File

@ -0,0 +1,23 @@
/*
* Copyright (C) 2015, Broadcom Corporation
* All Rights Reserved
*
* 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/linkage.h>
#include <linux/init.h>
#include <asm/assembler.h>
ENTRY(bcm63138_secondary_startup)
ARM_BE8(setend be)
/*
* L1 cache does have unpredictable contents at power-up clean its
* contents without flushing
*/
bl v7_invalidate_l1
nop
b secondary_startup
ENDPROC(bcm63138_secondary_startup)

View File

@ -0,0 +1,221 @@
/*
* Broadcom BCM63138 PMB initialization for secondary CPU(s)
*
* Copyright (C) 2015 Broadcom Corporation
* Author: Florian Fainelli <f.fainelli@gmail.com>
*
* 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 <linux/kernel.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/reset/bcm63xx_pmb.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include "bcm63xx_smp.h"
/* ARM Control register definitions */
#define CORE_PWR_CTRL_SHIFT 0
#define CORE_PWR_CTRL_MASK 0x3
#define PLL_PWR_ON BIT(8)
#define PLL_LDO_PWR_ON BIT(9)
#define PLL_CLAMP_ON BIT(10)
#define CPU_RESET_N(x) BIT(13 + (x))
#define NEON_RESET_N BIT(15)
#define PWR_CTRL_STATUS_SHIFT 28
#define PWR_CTRL_STATUS_MASK 0x3
#define PWR_DOWN_SHIFT 30
#define PWR_DOWN_MASK 0x3
/* CPU Power control register definitions */
#define MEM_PWR_OK BIT(0)
#define MEM_PWR_ON BIT(1)
#define MEM_CLAMP_ON BIT(2)
#define MEM_PWR_OK_STATUS BIT(4)
#define MEM_PWR_ON_STATUS BIT(5)
#define MEM_PDA_SHIFT 8
#define MEM_PDA_MASK 0xf
#define MEM_PDA_CPU_MASK 0x1
#define MEM_PDA_NEON_MASK 0xf
#define CLAMP_ON BIT(15)
#define PWR_OK_SHIFT 16
#define PWR_OK_MASK 0xf
#define PWR_ON_SHIFT 20
#define PWR_CPU_MASK 0x03
#define PWR_NEON_MASK 0x01
#define PWR_ON_MASK 0xf
#define PWR_OK_STATUS_SHIFT 24
#define PWR_OK_STATUS_MASK 0xf
#define PWR_ON_STATUS_SHIFT 28
#define PWR_ON_STATUS_MASK 0xf
#define ARM_CONTROL 0x30
#define ARM_PWR_CONTROL_BASE 0x34
#define ARM_PWR_CONTROL(x) (ARM_PWR_CONTROL_BASE + (x) * 0x4)
#define ARM_NEON_L2 0x3c
/* Perform a value write, then spin until the value shifted by
* shift is seen, masked with mask and is different from cond.
*/
static int bpcm_wr_rd_mask(void __iomem *master,
unsigned int addr, u32 off, u32 *val,
u32 shift, u32 mask, u32 cond)
{
int ret;
ret = bpcm_wr(master, addr, off, *val);
if (ret)
return ret;
do {
ret = bpcm_rd(master, addr, off, val);
if (ret)
return ret;
cpu_relax();
} while (((*val >> shift) & mask) != cond);
return ret;
}
/* Global lock to serialize accesses to the PMB registers while we
* are bringing up the secondary CPU
*/
static DEFINE_SPINLOCK(pmb_lock);
static int bcm63xx_pmb_get_resources(struct device_node *dn,
void __iomem **base,
unsigned int *cpu,
unsigned int *addr)
{
struct device_node *pmb_dn;
struct of_phandle_args args;
int ret;
ret = of_property_read_u32(dn, "reg", cpu);
if (ret) {
pr_err("CPU is missing a reg node\n");
return ret;
}
ret = of_parse_phandle_with_args(dn, "resets", "#reset-cells",
0, &args);
if (ret) {
pr_err("CPU is missing a resets phandle\n");
return ret;
}
pmb_dn = args.np;
if (args.args_count != 2) {
pr_err("reset-controller does not conform to reset-cells\n");
return -EINVAL;
}
*base = of_iomap(args.np, 0);
if (!*base) {
pr_err("failed remapping PMB register\n");
return -ENOMEM;
}
/* We do not need the number of zones */
*addr = args.args[0];
return 0;
}
int bcm63xx_pmb_power_on_cpu(struct device_node *dn)
{
void __iomem *base;
unsigned int cpu, addr;
unsigned long flags;
u32 val, ctrl;
int ret;
ret = bcm63xx_pmb_get_resources(dn, &base, &cpu, &addr);
if (ret)
return ret;
/* We would not know how to enable a third and greater CPU */
WARN_ON(cpu > 1);
spin_lock_irqsave(&pmb_lock, flags);
/* Check if the CPU is already on and save the ARM_CONTROL register
* value since we will use it later for CPU de-assert once done with
* the CPU-specific power sequence
*/
ret = bpcm_rd(base, addr, ARM_CONTROL, &ctrl);
if (ret)
goto out;
if (ctrl & CPU_RESET_N(cpu)) {
pr_info("PMB: CPU%d is already powered on\n", cpu);
ret = 0;
goto out;
}
/* Power on PLL */
ret = bpcm_rd(base, addr, ARM_PWR_CONTROL(cpu), &val);
if (ret)
goto out;
val |= (PWR_CPU_MASK << PWR_ON_SHIFT);
ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val,
PWR_ON_STATUS_SHIFT, PWR_CPU_MASK, PWR_CPU_MASK);
if (ret)
goto out;
val |= (PWR_CPU_MASK << PWR_OK_SHIFT);
ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val,
PWR_OK_STATUS_SHIFT, PWR_CPU_MASK, PWR_CPU_MASK);
if (ret)
goto out;
val &= ~CLAMP_ON;
ret = bpcm_wr(base, addr, ARM_PWR_CONTROL(cpu), val);
if (ret)
goto out;
/* Power on CPU<N> RAM */
val &= ~(MEM_PDA_MASK << MEM_PDA_SHIFT);
ret = bpcm_wr(base, addr, ARM_PWR_CONTROL(cpu), val);
if (ret)
goto out;
val |= MEM_PWR_ON;
ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val,
0, MEM_PWR_ON_STATUS, MEM_PWR_ON_STATUS);
if (ret)
goto out;
val |= MEM_PWR_OK;
ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val,
0, MEM_PWR_OK_STATUS, MEM_PWR_OK_STATUS);
if (ret)
goto out;
val &= ~MEM_CLAMP_ON;
ret = bpcm_wr(base, addr, ARM_PWR_CONTROL(cpu), val);
if (ret)
goto out;
/* De-assert CPU reset */
ctrl |= CPU_RESET_N(cpu);
ret = bpcm_wr(base, addr, ARM_CONTROL, ctrl);
out:
spin_unlock_irqrestore(&pmb_lock, flags);
iounmap(base);
return ret;
}

View File

@ -0,0 +1,169 @@
/*
* Broadcom BCM63138 DSL SoCs SMP support code
*
* Copyright (C) 2015, Broadcom Corporation
*
* Licensed under the terms of the GPLv2
*/
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <asm/cacheflush.h>
#include <asm/smp_scu.h>
#include <asm/smp_plat.h>
#include <asm/vfp.h>
#include "bcm63xx_smp.h"
/* Size of mapped Cortex A9 SCU address space */
#define CORTEX_A9_SCU_SIZE 0x58
/*
* Enable the Cortex A9 Snoop Control Unit
*
* By the time this is called we already know there are multiple
* cores present. We assume we're running on a Cortex A9 processor,
* so any trouble getting the base address register or getting the
* SCU base is a problem.
*
* Return 0 if successful or an error code otherwise.
*/
static int __init scu_a9_enable(void)
{
unsigned long config_base;
void __iomem *scu_base;
unsigned int i, ncores;
if (!scu_a9_has_base()) {
pr_err("no configuration base address register!\n");
return -ENXIO;
}
/* Config base address register value is zero for uniprocessor */
config_base = scu_a9_get_base();
if (!config_base) {
pr_err("hardware reports only one core\n");
return -ENOENT;
}
scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE);
if (!scu_base) {
pr_err("failed to remap config base (%lu/%u) for SCU\n",
config_base, CORTEX_A9_SCU_SIZE);
return -ENOMEM;
}
scu_enable(scu_base);
ncores = scu_base ? scu_get_core_count(scu_base) : 1;
if (ncores > nr_cpu_ids) {
pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
ncores, nr_cpu_ids);
ncores = nr_cpu_ids;
}
/* The BCM63138 SoC has two Cortex-A9 CPUs, CPU0 features a complete
* and fully functional VFP unit that can be used, but CPU1 does not.
* Since we will not be able to trap kernel-mode NEON to force
* migration to CPU0, just do not advertise VFP support at all.
*
* This will make vfp_init bail out and do not attempt to use VFP at
* all, for kernel-mode NEON, we do not want to introduce any
* conditionals in hot-paths, so we just restrict the system to UP.
*/
#ifdef CONFIG_VFP
if (ncores > 1) {
pr_warn("SMP: secondary CPUs lack VFP unit, disabling VFP\n");
vfp_disable();
#ifdef CONFIG_KERNEL_MODE_NEON
WARN(1, "SMP: kernel-mode NEON enabled, restricting to UP\n");
ncores = 1;
#endif
}
#endif
for (i = 0; i < ncores; i++)
set_cpu_possible(i, true);
iounmap(scu_base); /* That's the last we'll need of this */
return 0;
}
static const struct of_device_id bcm63138_bootlut_ids[] = {
{ .compatible = "brcm,bcm63138-bootlut", },
{ /* sentinel */ },
};
#define BOOTLUT_RESET_VECT 0x20
static int bcm63138_smp_boot_secondary(unsigned int cpu,
struct task_struct *idle)
{
void __iomem *bootlut_base;
struct device_node *dn;
int ret = 0;
u32 val;
dn = of_find_matching_node(NULL, bcm63138_bootlut_ids);
if (!dn) {
pr_err("SMP: unable to find bcm63138 boot LUT node\n");
return -ENODEV;
}
bootlut_base = of_iomap(dn, 0);
of_node_put(dn);
if (!bootlut_base) {
pr_err("SMP: unable to remap boot LUT base register\n");
return -ENOMEM;
}
/* Locate the secondary CPU node */
dn = of_get_cpu_node(cpu_logical_map(cpu), NULL);
if (!dn) {
pr_err("SMP: failed to locate secondary CPU%d node\n", cpu);
ret = -ENODEV;
goto out;
}
/* Write the secondary init routine to the BootLUT reset vector */
val = virt_to_phys(bcm63138_secondary_startup);
writel_relaxed(val, bootlut_base + BOOTLUT_RESET_VECT);
/* Power up the core, will jump straight to its reset vector when we
* return
*/
ret = bcm63xx_pmb_power_on_cpu(dn);
if (ret)
goto out;
out:
iounmap(bootlut_base);
return ret;
}
static void __init bcm63138_smp_prepare_cpus(unsigned int max_cpus)
{
int ret;
ret = scu_a9_enable();
if (ret) {
pr_warn("SMP: Cortex-A9 SCU setup failed\n");
return;
}
}
struct smp_operations bcm63138_smp_ops __initdata = {
.smp_prepare_cpus = bcm63138_smp_prepare_cpus,
.smp_boot_secondary = bcm63138_smp_boot_secondary,
};
CPU_METHOD_OF_DECLARE(bcm63138_smp, "brcm,bcm63138", &bcm63138_smp_ops);

View File

@ -0,0 +1,9 @@
#ifndef __BCM63XX_SMP_H
#define __BCM63XX_SMP_H
struct device_node;
extern void bcm63138_secondary_startup(void);
extern int bcm63xx_pmb_power_on_cpu(struct device_node *dn);
#endif /* __BCM63XX_SMP_H */

View File

@ -18,15 +18,16 @@ static bool first_fault = true;
static int bcm5301x_abort_handler(unsigned long addr, unsigned int fsr,
struct pt_regs *regs)
{
if (fsr == 0x1c06 && first_fault) {
if ((fsr == 0x1406 || fsr == 0x1c06) && first_fault) {
first_fault = false;
/*
* These faults with code 0x1c06 happens for no good reason,
* possibly left over from the CFE boot loader.
* These faults with codes 0x1406 (BCM4709) or 0x1c06 happens
* for no good reason, possibly left over from the CFE boot
* loader.
*/
pr_warn("External imprecise Data abort at addr=%#lx, fsr=%#x ignored.\n",
addr, fsr);
addr, fsr);
/* Returning non-zero causes fault display and panic */
return 0;

View File

@ -12,7 +12,6 @@
* GNU General Public License for more details.
*/
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/irqchip.h>
#include <linux/of_address.h>
@ -22,97 +21,10 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#define PM_RSTC 0x1c
#define PM_RSTS 0x20
#define PM_WDOG 0x24
#define PM_PASSWORD 0x5a000000
#define PM_RSTC_WRCFG_MASK 0x00000030
#define PM_RSTC_WRCFG_FULL_RESET 0x00000020
#define PM_RSTS_HADWRH_SET 0x00000040
#define BCM2835_PERIPH_PHYS 0x20000000
#define BCM2835_PERIPH_VIRT 0xf0000000
#define BCM2835_PERIPH_SIZE SZ_16M
static void __iomem *wdt_regs;
/*
* The machine restart method can be called from an atomic context so we won't
* be able to ioremap the regs then.
*/
static void bcm2835_setup_restart(void)
{
struct device_node *np = of_find_compatible_node(NULL, NULL,
"brcm,bcm2835-pm-wdt");
if (WARN(!np, "unable to setup watchdog restart"))
return;
wdt_regs = of_iomap(np, 0);
WARN(!wdt_regs, "failed to remap watchdog regs");
}
static void bcm2835_restart(enum reboot_mode mode, const char *cmd)
{
u32 val;
if (!wdt_regs)
return;
/* use a timeout of 10 ticks (~150us) */
writel_relaxed(10 | PM_PASSWORD, wdt_regs + PM_WDOG);
val = readl_relaxed(wdt_regs + PM_RSTC);
val &= ~PM_RSTC_WRCFG_MASK;
val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
writel_relaxed(val, wdt_regs + PM_RSTC);
/* No sleeping, possibly atomic. */
mdelay(1);
}
/*
* We can't really power off, but if we do the normal reset scheme, and
* indicate to bootcode.bin not to reboot, then most of the chip will be
* powered off.
*/
static void bcm2835_power_off(void)
{
u32 val;
/*
* We set the watchdog hard reset bit here to distinguish this reset
* from the normal (full) reset. bootcode.bin will not reboot after a
* hard reset.
*/
val = readl_relaxed(wdt_regs + PM_RSTS);
val &= ~PM_RSTC_WRCFG_MASK;
val |= PM_PASSWORD | PM_RSTS_HADWRH_SET;
writel_relaxed(val, wdt_regs + PM_RSTS);
/* Continue with normal reset mechanism */
bcm2835_restart(REBOOT_HARD, "");
}
static struct map_desc io_map __initdata = {
.virtual = BCM2835_PERIPH_VIRT,
.pfn = __phys_to_pfn(BCM2835_PERIPH_PHYS),
.length = BCM2835_PERIPH_SIZE,
.type = MT_DEVICE
};
static void __init bcm2835_map_io(void)
{
iotable_init(&io_map, 1);
}
static void __init bcm2835_init(void)
{
int ret;
bcm2835_setup_restart();
if (wdt_regs)
pm_power_off = bcm2835_power_off;
bcm2835_init_clocks();
ret = of_platform_populate(NULL, of_default_bus_match_table, NULL,
@ -129,9 +41,6 @@ static const char * const bcm2835_compat[] = {
};
DT_MACHINE_START(BCM2835, "BCM2835")
.map_io = bcm2835_map_io,
.init_irq = irqchip_init,
.init_machine = bcm2835_init,
.restart = bcm2835_restart,
.dt_compat = bcm2835_compat
MACHINE_END

View File

@ -20,9 +20,14 @@
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/mmc/host.h>
#include <linux/spi/spi.h>
#include <linux/spi/mmc_spi.h>
#include <linux/platform_data/video-ep93xx.h>
#include <linux/platform_data/spi-ep93xx.h>
#include <linux/gpio.h>
#include <mach/hardware.h>
#include <linux/platform_data/video-ep93xx.h>
#include <mach/gpio-ep93xx.h>
#include <asm/mach-types.h>
@ -40,6 +45,132 @@ static struct ep93xxfb_mach_info __initdata simone_fb_info = {
.flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
};
/*
* GPIO lines used for MMC card detection.
*/
#define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0
/*
* Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes
* low between multi-message command blocks. From v1.4, it uses a GPIO instead.
* v1.3 parts will still work, since the signal on SFRMOUT is automatic.
*/
#define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO1
/*
* MMC SPI chip select GPIO handling. If you are using SFRMOUT (SFRM1) signal,
* you can leave these empty and pass NULL as .controller_data.
*/
static int simone_mmc_spi_setup(struct spi_device *spi)
{
unsigned int gpio = MMC_CHIP_SELECT_GPIO;
int err;
err = gpio_request(gpio, spi->modalias);
if (err)
return err;
err = gpio_direction_output(gpio, 1);
if (err) {
gpio_free(gpio);
return err;
}
return 0;
}
static void simone_mmc_spi_cleanup(struct spi_device *spi)
{
unsigned int gpio = MMC_CHIP_SELECT_GPIO;
gpio_set_value(gpio, 1);
gpio_direction_input(gpio);
gpio_free(gpio);
}
static void simone_mmc_spi_cs_control(struct spi_device *spi, int value)
{
gpio_set_value(MMC_CHIP_SELECT_GPIO, value);
}
static struct ep93xx_spi_chip_ops simone_mmc_spi_ops = {
.setup = simone_mmc_spi_setup,
.cleanup = simone_mmc_spi_cleanup,
.cs_control = simone_mmc_spi_cs_control,
};
/*
* MMC card detection GPIO setup.
*/
static int simone_mmc_spi_init(struct device *dev,
irqreturn_t (*irq_handler)(int, void *), void *mmc)
{
unsigned int gpio = MMC_CARD_DETECT_GPIO;
int irq, err;
err = gpio_request(gpio, dev_name(dev));
if (err)
return err;
err = gpio_direction_input(gpio);
if (err)
goto fail;
irq = gpio_to_irq(gpio);
if (irq < 0)
goto fail;
err = request_irq(irq, irq_handler, IRQF_TRIGGER_FALLING,
"MMC card detect", mmc);
if (err)
goto fail;
printk(KERN_INFO "%s: using irq %d for MMC card detection\n",
dev_name(dev), irq);
return 0;
fail:
gpio_free(gpio);
return err;
}
static void simone_mmc_spi_exit(struct device *dev, void *mmc)
{
unsigned int gpio = MMC_CARD_DETECT_GPIO;
free_irq(gpio_to_irq(gpio), mmc);
gpio_free(gpio);
}
static struct mmc_spi_platform_data simone_mmc_spi_data = {
.init = simone_mmc_spi_init,
.exit = simone_mmc_spi_exit,
.detect_delay = 500,
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
};
static struct spi_board_info simone_spi_devices[] __initdata = {
{
.modalias = "mmc_spi",
.controller_data = &simone_mmc_spi_ops,
.platform_data = &simone_mmc_spi_data,
/*
* We use 10 MHz even though the maximum is 3.7 MHz. The driver
* will limit it automatically to max. frequency.
*/
.max_speed_hz = 10 * 1000 * 1000,
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_3,
},
};
static struct ep93xx_spi_info simone_spi_info __initdata = {
.num_chipselect = ARRAY_SIZE(simone_spi_devices),
};
static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = {
.sda_pin = EP93XX_GPIO_LINE_EEDAT,
.sda_is_open_drain = 0,
@ -74,6 +205,8 @@ static void __init simone_init_machine(void)
ep93xx_register_fb(&simone_fb_info);
ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
ARRAY_SIZE(simone_i2c_board_info));
ep93xx_register_spi(&simone_spi_info, simone_spi_devices,
ARRAY_SIZE(simone_spi_devices));
simone_register_audio();
}

View File

@ -163,7 +163,9 @@ extern void exynos_set_delayed_reset_assertion(bool enable);
extern void s5p_init_cpu(void __iomem *cpuid_addr);
extern unsigned int samsung_rev(void);
extern void __iomem *cpu_boot_reg_base(void);
extern void exynos_core_restart(u32 core_id);
extern int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr);
extern int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr);
static inline void pmu_raw_writel(u32 val, u32 offset)
{

View File

@ -234,7 +234,8 @@ static void __init exynos_dt_machine_init(void)
exynos_sysram_init();
#if defined(CONFIG_SMP) && defined(CONFIG_ARM_EXYNOS_CPUIDLE)
if (of_machine_is_compatible("samsung,exynos4210"))
if (of_machine_is_compatible("samsung,exynos4210") ||
of_machine_is_compatible("samsung,exynos3250"))
exynos_cpuidle.dev.platform_data = &cpuidle_coupled_exynos_data;
#endif
if (of_machine_is_compatible("samsung,exynos4210") ||

View File

@ -49,6 +49,7 @@ static int exynos_do_idle(unsigned long mode)
sysram_ns_base_addr + 0x24);
__raw_writel(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
if (soc_is_exynos3250()) {
flush_cache_all();
exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
SMC_POWERSTATE_IDLE, 0);
exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
@ -104,6 +105,22 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
return 0;
}
static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr)
{
void __iomem *boot_reg;
if (!sysram_ns_base_addr)
return -ENODEV;
boot_reg = sysram_ns_base_addr + 0x1c;
if (soc_is_exynos4412())
boot_reg += 4 * cpu;
*boot_addr = __raw_readl(boot_reg);
return 0;
}
static int exynos_cpu_suspend(unsigned long arg)
{
flush_cache_all();
@ -138,6 +155,7 @@ static int exynos_resume(void)
static const struct firmware_ops exynos_firmware_ops = {
.do_idle = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL,
.set_cpu_boot_addr = exynos_set_cpu_boot_addr,
.get_cpu_boot_addr = exynos_get_cpu_boot_addr,
.cpu_boot = exynos_cpu_boot,
.suspend = IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL,
.resume = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,

View File

@ -169,7 +169,7 @@ int exynos_cluster_power_state(int cluster)
S5P_CORE_LOCAL_PWR_EN);
}
void __iomem *cpu_boot_reg_base(void)
static void __iomem *cpu_boot_reg_base(void)
{
if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
return pmu_base_addr + S5P_INFORM5;
@ -195,7 +195,7 @@ static inline void __iomem *cpu_boot_reg(int cpu)
*
* Currently this is needed only when booting secondary CPU on Exynos3250.
*/
static void exynos_core_restart(u32 core_id)
void exynos_core_restart(u32 core_id)
{
u32 val;
@ -210,7 +210,6 @@ static void exynos_core_restart(u32 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);
}
@ -248,6 +247,56 @@ static void exynos_secondary_init(unsigned int cpu)
spin_unlock(&boot_lock);
}
int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr)
{
int ret;
/*
* Try to set boot address using firmware first
* and fall back to boot register if it fails.
*/
ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
if (ret && ret != -ENOSYS)
goto fail;
if (ret == -ENOSYS) {
void __iomem *boot_reg = cpu_boot_reg(core_id);
if (IS_ERR(boot_reg)) {
ret = PTR_ERR(boot_reg);
goto fail;
}
__raw_writel(boot_addr, boot_reg);
ret = 0;
}
fail:
return ret;
}
int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr)
{
int ret;
/*
* Try to get boot address using firmware first
* and fall back to boot register if it fails.
*/
ret = call_firmware_op(get_cpu_boot_addr, core_id, boot_addr);
if (ret && ret != -ENOSYS)
goto fail;
if (ret == -ENOSYS) {
void __iomem *boot_reg = cpu_boot_reg(core_id);
if (IS_ERR(boot_reg)) {
ret = PTR_ERR(boot_reg);
goto fail;
}
*boot_addr = __raw_readl(boot_reg);
ret = 0;
}
fail:
return ret;
}
static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
@ -307,22 +356,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
boot_addr = virt_to_phys(exynos4_secondary_startup);
/*
* Try to set boot address using firmware first
* and fall back to boot register if it fails.
*/
ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
if (ret && ret != -ENOSYS)
ret = exynos_set_boot_addr(core_id, boot_addr);
if (ret)
goto fail;
if (ret == -ENOSYS) {
void __iomem *boot_reg = cpu_boot_reg(core_id);
if (IS_ERR(boot_reg)) {
ret = PTR_ERR(boot_reg);
goto fail;
}
__raw_writel(boot_addr, boot_reg);
}
call_firmware_op(cpu_boot, core_id);
@ -337,6 +373,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
udelay(10);
}
if (pen_release != -1)
ret = -ETIMEDOUT;
/*
* now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
@ -407,16 +446,9 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
boot_addr = virt_to_phys(exynos4_secondary_startup);
ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
if (ret && ret != -ENOSYS)
ret = exynos_set_boot_addr(core_id, boot_addr);
if (ret)
break;
if (ret == -ENOSYS) {
void __iomem *boot_reg = cpu_boot_reg(core_id);
if (IS_ERR(boot_reg))
break;
__raw_writel(boot_addr, boot_reg);
}
}
}

View File

@ -22,6 +22,7 @@
#include <asm/firmware.h>
#include <asm/smp_scu.h>
#include <asm/suspend.h>
#include <asm/cacheflush.h>
#include <mach/map.h>
@ -209,6 +210,8 @@ static int exynos_cpu0_enter_aftr(void)
* sequence, let's wait for one of these to happen
*/
while (exynos_cpu_power_state(1)) {
unsigned long boot_addr;
/*
* The other cpu may skip idle and boot back
* up again
@ -221,7 +224,11 @@ static int exynos_cpu0_enter_aftr(void)
* boot back up again, getting stuck in the
* boot rom code
*/
if (__raw_readl(cpu_boot_reg_base()) == 0)
ret = exynos_get_boot_addr(1, &boot_addr);
if (ret)
goto fail;
ret = -1;
if (boot_addr == 0)
goto abort;
cpu_relax();
@ -233,11 +240,14 @@ static int exynos_cpu0_enter_aftr(void)
abort:
if (cpu_online(1)) {
unsigned long boot_addr = virt_to_phys(exynos_cpu_resume);
/*
* Set the boot vector to something non-zero
*/
__raw_writel(virt_to_phys(exynos_cpu_resume),
cpu_boot_reg_base());
ret = exynos_set_boot_addr(1, boot_addr);
if (ret)
goto fail;
dsb();
/*
@ -247,22 +257,42 @@ abort:
while (exynos_cpu_power_state(1) != S5P_CORE_LOCAL_PWR_EN)
cpu_relax();
if (soc_is_exynos3250()) {
while (!pmu_raw_readl(S5P_PMU_SPARE2) &&
!atomic_read(&cpu1_wakeup))
cpu_relax();
if (!atomic_read(&cpu1_wakeup))
exynos_core_restart(1);
}
while (!atomic_read(&cpu1_wakeup)) {
smp_rmb();
/*
* Poke cpu1 out of the boot rom
*/
__raw_writel(virt_to_phys(exynos_cpu_resume),
cpu_boot_reg_base());
arch_send_wakeup_ipi_mask(cpumask_of(1));
ret = exynos_set_boot_addr(1, boot_addr);
if (ret)
goto fail;
call_firmware_op(cpu_boot, 1);
if (soc_is_exynos3250())
dsb_sev();
else
arch_send_wakeup_ipi_mask(cpumask_of(1));
}
}
fail:
return ret;
}
static int exynos_wfi_finisher(unsigned long flags)
{
if (soc_is_exynos3250())
flush_cache_all();
cpu_do_idle();
return -1;
@ -283,6 +313,9 @@ static int exynos_cpu1_powerdown(void)
*/
exynos_cpu_power_down(1);
if (soc_is_exynos3250())
pmu_raw_writel(0, S5P_PMU_SPARE2);
ret = cpu_suspend(0, exynos_wfi_finisher);
cpu_pm_exit();
@ -299,7 +332,9 @@ cpu1_aborted:
static void exynos_pre_enter_aftr(void)
{
__raw_writel(virt_to_phys(exynos_cpu_resume), cpu_boot_reg_base());
unsigned long boot_addr = virt_to_phys(exynos_cpu_resume);
(void)exynos_set_boot_addr(1, boot_addr);
}
static void exynos_post_enter_aftr(void)

View File

@ -62,6 +62,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
if (IS_ERR(pd->clk[i]))
break;
pd->pclk[i] = clk_get_parent(pd->clk[i]);
if (clk_set_parent(pd->clk[i], pd->oscclk))
pr_err("%s: error setting oscclk as parent to clock %d\n",
pd->name, i);
@ -90,6 +91,9 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
if (IS_ERR(pd->clk[i]))
break;
if (IS_ERR(pd->clk[i]))
continue; /* Skip on first power up */
if (clk_set_parent(pd->clk[i], pd->pclk[i]))
pr_err("%s: error setting parent to clock%d\n",
pd->name, i);
@ -117,27 +121,37 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain)
static __init int exynos4_pm_init_power_domain(void)
{
struct platform_device *pdev;
struct device_node *np;
for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
struct exynos_pm_domain *pd;
int on, i;
struct device *dev;
pdev = of_find_device_by_node(np);
dev = &pdev->dev;
pd = kzalloc(sizeof(*pd), GFP_KERNEL);
if (!pd) {
pr_err("%s: failed to allocate memory for domain\n",
__func__);
of_node_put(np);
return -ENOMEM;
}
pd->pd.name = kstrdup_const(strrchr(np->full_name, '/') + 1,
GFP_KERNEL);
if (!pd->pd.name) {
kfree(pd);
of_node_put(np);
return -ENOMEM;
}
pd->pd.name = kstrdup(dev_name(dev), GFP_KERNEL);
pd->name = pd->pd.name;
pd->base = of_iomap(np, 0);
if (!pd->base) {
pr_warn("%s: failed to map memory\n", __func__);
kfree(pd->pd.name);
kfree(pd);
of_node_put(np);
continue;
}
pd->pd.power_off = exynos_pd_power_off;
pd->pd.power_on = exynos_pd_power_on;
@ -145,12 +159,12 @@ static __init int exynos4_pm_init_power_domain(void)
char clk_name[8];
snprintf(clk_name, sizeof(clk_name), "asb%d", i);
pd->asb_clk[i] = clk_get(dev, clk_name);
pd->asb_clk[i] = of_clk_get_by_name(np, clk_name);
if (IS_ERR(pd->asb_clk[i]))
break;
}
pd->oscclk = clk_get(dev, "oscclk");
pd->oscclk = of_clk_get_by_name(np, "oscclk");
if (IS_ERR(pd->oscclk))
goto no_clk;
@ -158,16 +172,14 @@ static __init int exynos4_pm_init_power_domain(void)
char clk_name[8];
snprintf(clk_name, sizeof(clk_name), "clk%d", i);
pd->clk[i] = clk_get(dev, clk_name);
pd->clk[i] = of_clk_get_by_name(np, clk_name);
if (IS_ERR(pd->clk[i]))
break;
snprintf(clk_name, sizeof(clk_name), "pclk%d", i);
pd->pclk[i] = clk_get(dev, clk_name);
if (IS_ERR(pd->pclk[i])) {
clk_put(pd->clk[i]);
pd->clk[i] = ERR_PTR(-EINVAL);
break;
}
/*
* Skip setting parent on first power up.
* The parent at this time may not be useful at all.
*/
pd->pclk[i] = ERR_PTR(-EINVAL);
}
if (IS_ERR(pd->clk[0]))
@ -189,15 +201,15 @@ no_clk:
args.args_count = 0;
child_domain = of_genpd_get_from_provider(&args);
if (IS_ERR(child_domain))
continue;
goto next_pd;
if (of_parse_phandle_with_args(np, "power-domains",
"#power-domain-cells", 0, &args) != 0)
continue;
goto next_pd;
parent_domain = of_genpd_get_from_provider(&args);
if (IS_ERR(parent_domain))
continue;
goto next_pd;
if (pm_genpd_add_subdomain(parent_domain, child_domain))
pr_warn("%s failed to add subdomain: %s\n",
@ -205,9 +217,10 @@ no_clk:
else
pr_info("%s has as child subdomain: %s.\n",
parent_domain->name, child_domain->name);
next_pd:
of_node_put(np);
}
return 0;
}
arch_initcall(exynos4_pm_init_power_domain);
core_initcall(exynos4_pm_init_power_domain);

View File

@ -681,7 +681,7 @@ static unsigned int const exynos5420_list_disable_pmu_reg[] = {
EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG,
};
static void exynos5_power_off(void)
static void exynos_power_off(void)
{
unsigned int tmp;
@ -872,8 +872,6 @@ static void exynos5420_pmu_init(void)
EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI);
pmu_raw_writel(0x1, EXYNOS5420_UP_SCHEDULER);
pm_power_off = exynos5_power_off;
pr_info("EXYNOS5420 PMU initialized\n");
}
@ -984,6 +982,8 @@ static int exynos_pmu_probe(struct platform_device *pdev)
if (ret)
dev_warn(dev, "can't register restart handler err=%d\n", ret);
pm_power_off = exynos_power_off;
dev_dbg(dev, "Exynos PMU Driver probe done\n");
return 0;
}

View File

@ -223,7 +223,7 @@ static int exynos_pmu_domain_alloc(struct irq_domain *domain,
return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args);
}
static struct irq_domain_ops exynos_pmu_domain_ops = {
static const struct irq_domain_ops exynos_pmu_domain_ops = {
.xlate = exynos_pmu_domain_xlate,
.alloc = exynos_pmu_domain_alloc,
.free = irq_domain_free_irqs_common,

View File

@ -1,8 +1,8 @@
menuconfig ARCH_MXC
bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7
bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M
select ARCH_REQUIRE_GPIOLIB
select ARM_CPU_SUSPEND if PM
select CLKSRC_MMIO
select CLKSRC_IMX_GPT
select GENERIC_IRQ_CHIP
select PINCTRL
select PM_OPP if PM
@ -462,10 +462,10 @@ config MACH_VPR200
endif
if ARCH_MULTI_V5
comment "Device tree only"
if ARCH_MULTI_V5
config SOC_IMX25
bool "i.MX25 support"
select ARCH_MXC_IOMUX_V3
@ -478,7 +478,7 @@ endif
if ARCH_MULTI_V7
comment "Device tree only"
comment "Cortex-A platforms"
config SOC_IMX5
bool
@ -548,10 +548,33 @@ config SOC_IMX6SX
help
This enables support for Freescale i.MX6 SoloX processor.
config SOC_IMX7D
bool "i.MX7 Dual support"
select PINCTRL_IMX7D
select ARM_GIC
select HAVE_IMX_ANATOP
select HAVE_IMX_MMDC
help
This enables support for Freescale i.MX7 Dual processor.
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 enables support for Freescale LS1021A processor.
endif
comment "Cortex-A/Cortex-M asymmetric multiprocessing platforms"
if ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M
config SOC_VF610
bool "Vybrid Family VF610 support"
select IRQ_DOMAIN_HIERARCHY
select ARM_GIC
select ARM_GIC if ARCH_MULTI_V7
select PINCTRL_VF610
select PL310_ERRATA_769419 if CACHE_L2X0
select SMP_ON_UP if SMP
@ -565,7 +588,7 @@ choice
default VF_USE_ARM_GLOBAL_TIMER
config VF_USE_ARM_GLOBAL_TIMER
bool "Use ARM Global Timer"
bool "Use ARM Global Timer" if ARCH_MULTI_V7
select ARM_GLOBAL_TIMER
select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
help
@ -579,16 +602,6 @@ choice
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 enables support for Freescale LS1021A processor.
endif
source "arch/arm/mach-imx/devices/Kconfig"

View File

@ -1,23 +1,18 @@
obj-y := time.o cpu.o system.o irq-common.o
obj-y := cpu.o system.o irq-common.o
obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o
obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o
obj-$(CONFIG_SOC_IMX1) += mm-imx1.o
obj-$(CONFIG_SOC_IMX21) += mm-imx21.o
obj-$(CONFIG_SOC_IMX25) += clk-imx25.o cpu-imx25.o mach-imx25.o
obj-$(CONFIG_SOC_IMX25) += cpu-imx25.o mach-imx25.o
obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o
obj-$(CONFIG_SOC_IMX27) += mm-imx27.o ehci-imx27.o
obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o
obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o ehci-imx35.o pm-imx3.o
imx5-pm-$(CONFIG_PM) += pm-imx5.o
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 \
clk-pfd.o clk-busy.o clk.o \
clk-fixup-div.o clk-fixup-mux.o \
clk-gate-exclusive.o
obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o $(imx5-pm-y)
obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
@ -85,13 +80,15 @@ AFLAGS_headsmp.o :=-Wa,-march=armv7-a
obj-$(CONFIG_SMP) += headsmp.o platsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
endif
obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o mach-imx6sx.o
obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o
obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o
obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o
obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o
ifeq ($(CONFIG_SUSPEND),y)
AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o
endif
obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
@ -99,7 +96,7 @@ obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
obj-$(CONFIG_SOC_IMX51) += mach-imx51.o
obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o
obj-$(CONFIG_SOC_VF610) += mach-vf610.o
obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o

View File

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013 Freescale Semiconductor, Inc.
* Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@ -28,6 +28,7 @@
#define ANADIG_USB2_CHRG_DETECT 0x210
#define ANADIG_DIGPROG 0x260
#define ANADIG_DIGPROG_IMX6SL 0x280
#define ANADIG_DIGPROG_IMX7D 0x800
#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000
#define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN 0x8
@ -121,6 +122,8 @@ void __init imx_init_revision_from_anatop(void)
WARN_ON(!anatop_base);
if (of_device_is_compatible(np, "fsl,imx6sl-anatop"))
offset = ANADIG_DIGPROG_IMX6SL;
if (of_device_is_compatible(np, "fsl,imx7d-anatop"))
offset = ANADIG_DIGPROG_IMX7D;
digprog = readl_relaxed(anatop_base + offset);
iounmap(anatop_base);

View File

@ -44,7 +44,6 @@ void imx27_soc_init(void);
void imx31_soc_init(void);
void imx35_soc_init(void);
void epit_timer_init(void __iomem *base, int irq);
void mxc_timer_init(void __iomem *, int);
int mx1_clocks_init(unsigned long fref);
int mx21_clocks_init(unsigned long lref, unsigned long fref);
int mx27_clocks_init(unsigned long fref);
@ -56,13 +55,10 @@ struct platform_device *mxc_register_gpio(char *name, int id,
void mxc_set_cpu_type(unsigned int type);
void mxc_restart(enum reboot_mode, const char *);
void mxc_arch_reset_init(void __iomem *);
int mx51_revision(void);
int mx53_revision(void);
void imx_set_aips(void __iomem *);
void imx_aips_allow_unprivileged_access(const char *compat);
int mxc_device_init(void);
void imx_set_soc_revision(unsigned int rev);
unsigned int imx_get_soc_revision(void);
void imx_init_revision_from_anatop(void);
struct device *imx_soc_device_init(void);
void imx6_enable_rbc(bool enable);
@ -87,7 +83,6 @@ enum mx3_cpu_pwr_mode {
};
void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
void imx_print_silicon_rev(const char *cpu, int srev);
void imx_enable_cpu(int cpu, bool enable);
void imx_set_cpu_jump(int cpu, void *jump_addr);
@ -111,7 +106,7 @@ void imx_gpc_hwirq_unmask(unsigned int hwirq);
void imx_anatop_init(void);
void imx_anatop_pre_suspend(void);
void imx_anatop_post_resume(void);
int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
int imx6_set_lpm(enum mxc_cpu_pwr_mode mode);
void imx6q_set_int_mem_clk_lpm(bool enable);
void imx6sl_set_wait_clk(bool enter);
int imx_mmdc_get_ddr_type(void);
@ -121,26 +116,28 @@ int imx_cpu_kill(unsigned int cpu);
#ifdef CONFIG_SUSPEND
void v7_cpu_resume(void);
void imx53_suspend(void __iomem *ocram_vbase);
extern const u32 imx53_suspend_sz;
void imx6_suspend(void __iomem *ocram_vbase);
#else
static inline void v7_cpu_resume(void) {}
static inline void imx53_suspend(void __iomem *ocram_vbase) {}
static const u32 imx53_suspend_sz;
static inline void imx6_suspend(void __iomem *ocram_vbase) {}
#endif
void imx6_pm_ccm_init(const char *ccm_compat);
void imx6q_pm_init(void);
void imx6dl_pm_init(void);
void imx6sl_pm_init(void);
void imx6sx_pm_init(void);
void imx6q_pm_set_ccm_base(void __iomem *base);
#ifdef CONFIG_PM
void imx51_pm_init(void);
void imx53_pm_init(void);
void imx5_pm_set_ccm_base(void __iomem *base);
#else
static inline void imx51_pm_init(void) {}
static inline void imx53_pm_init(void) {}
static inline void imx5_pm_set_ccm_base(void __iomem *base) {}
#endif
#ifdef CONFIG_NEON

View File

@ -130,6 +130,9 @@ struct device * __init imx_soc_device_init(void)
case MXC_CPU_IMX6Q:
soc_id = "i.MX6Q";
break;
case MXC_CPU_IMX7D:
soc_id = "i.MX7D";
break;
default:
soc_id = "Unknown";
}

View File

@ -27,9 +27,9 @@ static int imx6q_enter_wait(struct cpuidle_device *dev,
*/
if (!spin_trylock(&master_lock))
goto idle;
imx6q_set_lpm(WAIT_UNCLOCKED);
imx6_set_lpm(WAIT_UNCLOCKED);
cpu_do_idle();
imx6q_set_lpm(WAIT_CLOCKED);
imx6_set_lpm(WAIT_CLOCKED);
spin_unlock(&master_lock);
goto done;
}

View File

@ -16,7 +16,7 @@
static int imx6sl_enter_wait(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index)
{
imx6q_set_lpm(WAIT_UNCLOCKED);
imx6_set_lpm(WAIT_UNCLOCKED);
/*
* Software workaround for ERR005311, see function
* description for details.
@ -24,7 +24,7 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev,
imx6sl_set_wait_clk(true);
cpu_do_idle();
imx6sl_set_wait_clk(false);
imx6q_set_lpm(WAIT_CLOCKED);
imx6_set_lpm(WAIT_CLOCKED);
return index;
}

View File

@ -25,7 +25,7 @@ static int imx6sx_idle_finish(unsigned long val)
static int imx6sx_enter_wait(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index)
{
imx6q_set_lpm(WAIT_UNCLOCKED);
imx6_set_lpm(WAIT_UNCLOCKED);
switch (index) {
case 1:
@ -50,7 +50,7 @@ static int imx6sx_enter_wait(struct cpuidle_device *dev,
break;
}
imx6q_set_lpm(WAIT_CLOCKED);
imx6_set_lpm(WAIT_CLOCKED);
return index;
}

View File

@ -227,7 +227,7 @@ static int imx_gpc_domain_alloc(struct irq_domain *domain,
return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args);
}
static struct irq_domain_ops imx_gpc_domain_ops = {
static const struct irq_domain_ops imx_gpc_domain_ops = {
.xlate = imx_gpc_domain_xlate,
.alloc = imx_gpc_domain_alloc,
.free = irq_domain_free_irqs_common,

View File

@ -22,6 +22,7 @@
#ifndef __ASSEMBLY__
#include <asm/io.h>
#include <soc/imx/revision.h>
#endif
#include <asm/sizes.h>

View File

@ -40,7 +40,7 @@ static DEFINE_SPINLOCK(gpio_mux_lock);
#define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3)
static unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
static DECLARE_BITMAP(mxc_pin_alloc_map, NB_PORTS * 32);
/*
* set the mode for a IOMUX pin.
*/

View File

@ -393,6 +393,7 @@ static void __init imx6q_init_irq(void)
imx_init_l2cache();
imx_src_init();
irqchip_init();
imx6_pm_ccm_init("fsl,imx6q-ccm");
}
static const char * const imx6q_dt_compat[] __initconst = {

View File

@ -66,6 +66,7 @@ static void __init imx6sl_init_irq(void)
imx_init_l2cache();
imx_src_init();
irqchip_init();
imx6_pm_ccm_init("fsl,imx6sl-ccm");
}
static const char * const imx6sl_dt_compat[] __initconst = {

View File

@ -86,6 +86,7 @@ static void __init imx6sx_init_irq(void)
imx_init_l2cache();
imx_src_init();
irqchip_init();
imx6_pm_ccm_init("fsl,imx6sx-ccm");
}
static void __init imx6sx_init_late(void)

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2015 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 version 2 as
* published by the Free Software Foundation.
*/
#include <linux/irqchip.h>
#include <linux/of_platform.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include "common.h"
static void __init imx7d_init_machine(void)
{
struct device *parent;
parent = imx_soc_device_init();
if (parent == NULL)
pr_warn("failed to initialize soc device\n");
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
imx_anatop_init();
}
static void __init imx7d_init_irq(void)
{
imx_init_revision_from_anatop();
imx_src_init();
irqchip_init();
}
static const char *imx7d_dt_compat[] __initconst = {
"fsl,imx7d",
NULL,
};
DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)")
.init_irq = imx7d_init_irq,
.init_machine = imx7d_init_machine,
.dt_compat = imx7d_dt_compat,
MACHINE_END

View File

@ -17,6 +17,7 @@ static const char * const vf610_dt_compat[] __initconst = {
"fsl,vf510",
"fsl,vf600",
"fsl,vf610",
"fsl,vf610m4",
NULL,
};

View File

@ -17,6 +17,8 @@
#include <linux/of_address.h>
#include <linux/of_device.h>
#include "common.h"
#define MMDC_MAPSR 0x404
#define BP_MMDC_MAPSR_PSD 0
#define BP_MMDC_MAPSR_PSS 4

View File

@ -231,8 +231,4 @@
#define MX27_DMA_REQ_SDHC3 36
#define MX27_DMA_REQ_NFC 37
#ifndef __ASSEMBLY__
extern int mx27_revision(void);
#endif
#endif /* ifndef __MACH_MX27_H__ */

View File

@ -185,11 +185,4 @@
#define MX3x_PROD_SIGNATURE 0x1 /* For MX31 */
/* Mandatory defines used globally */
#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
extern int mx35_revision(void);
extern int mx31_revision(void);
#endif
#endif /* ifndef __MACH_MX3x_H__ */

View File

@ -1,5 +1,5 @@
/*
* Copyright 2004-2007, 2010 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2004-2007, 2010-2015 Freescale Semiconductor, Inc.
* Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
*
* This program is free software; you can redistribute it and/or
@ -38,22 +38,7 @@
#define MXC_CPU_IMX6DL 0x61
#define MXC_CPU_IMX6SX 0x62
#define MXC_CPU_IMX6Q 0x63
#define IMX_CHIP_REVISION_1_0 0x10
#define IMX_CHIP_REVISION_1_1 0x11
#define IMX_CHIP_REVISION_1_2 0x12
#define IMX_CHIP_REVISION_1_3 0x13
#define IMX_CHIP_REVISION_1_4 0x14
#define IMX_CHIP_REVISION_1_5 0x15
#define IMX_CHIP_REVISION_2_0 0x20
#define IMX_CHIP_REVISION_2_1 0x21
#define IMX_CHIP_REVISION_2_2 0x22
#define IMX_CHIP_REVISION_2_3 0x23
#define IMX_CHIP_REVISION_3_0 0x30
#define IMX_CHIP_REVISION_3_1 0x31
#define IMX_CHIP_REVISION_3_2 0x32
#define IMX_CHIP_REVISION_3_3 0x33
#define IMX_CHIP_REVISION_UNKNOWN 0xff
#define MXC_CPU_IMX7D 0x72
#define IMX_DDR_TYPE_LPDDR2 1
@ -185,6 +170,11 @@ static inline bool cpu_is_imx6q(void)
return __mxc_cpu_type == MXC_CPU_IMX6Q;
}
static inline bool cpu_is_imx7d(void)
{
return __mxc_cpu_type == MXC_CPU_IMX7D;
}
struct cpu_op {
u32 cpu_rate;
};

View File

@ -13,7 +13,14 @@
#include <linux/io.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/genalloc.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <asm/cacheflush.h>
#include <asm/fncpy.h>
#include <asm/system_misc.h>
#include <asm/tlbflush.h>
@ -49,29 +56,91 @@
*/
#define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF
struct imx5_suspend_io_state {
u32 offset;
u32 clear;
u32 set;
u32 saved_value;
};
struct imx5_pm_data {
phys_addr_t ccm_addr;
phys_addr_t cortex_addr;
phys_addr_t gpc_addr;
phys_addr_t m4if_addr;
phys_addr_t iomuxc_addr;
void (*suspend_asm)(void __iomem *ocram_vbase);
const u32 *suspend_asm_sz;
const struct imx5_suspend_io_state *suspend_io_config;
int suspend_io_count;
};
static const struct imx5_suspend_io_state imx53_suspend_io_config[] = {
#define MX53_DSE_HIGHZ_MASK (0x7 << 19)
{.offset = 0x584, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM0 */
{.offset = 0x594, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM1 */
{.offset = 0x560, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM2 */
{.offset = 0x554, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM3 */
{.offset = 0x574, .clear = MX53_DSE_HIGHZ_MASK}, /* CAS */
{.offset = 0x588, .clear = MX53_DSE_HIGHZ_MASK}, /* RAS */
{.offset = 0x578, .clear = MX53_DSE_HIGHZ_MASK}, /* SDCLK_0 */
{.offset = 0x570, .clear = MX53_DSE_HIGHZ_MASK}, /* SDCLK_1 */
{.offset = 0x580, .clear = MX53_DSE_HIGHZ_MASK}, /* SDODT0 */
{.offset = 0x564, .clear = MX53_DSE_HIGHZ_MASK}, /* SDODT1 */
{.offset = 0x57c, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS0 */
{.offset = 0x590, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS1 */
{.offset = 0x568, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS2 */
{.offset = 0x558, .clear = MX53_DSE_HIGHZ_MASK}, /* SDSQ3 */
{.offset = 0x6f0, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_ADDS */
{.offset = 0x718, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_BODS */
{.offset = 0x71c, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B1DS */
{.offset = 0x728, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B2DS */
{.offset = 0x72c, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B3DS */
/* Controls the CKE signal which is required to leave self refresh */
{.offset = 0x720, .clear = MX53_DSE_HIGHZ_MASK, .set = 1 << 19}, /* CTLDS */
};
static const struct imx5_pm_data imx51_pm_data __initconst = {
.ccm_addr = 0x73fd4000,
.cortex_addr = 0x83fa0000,
.gpc_addr = 0x73fd8000,
};
static const struct imx5_pm_data imx53_pm_data __initconst = {
.ccm_addr = 0x53fd4000,
.cortex_addr = 0x63fa0000,
.gpc_addr = 0x53fd8000,
.m4if_addr = 0x63fd8000,
.iomuxc_addr = 0x53fa8000,
.suspend_asm = &imx53_suspend,
.suspend_asm_sz = &imx53_suspend_sz,
.suspend_io_config = imx53_suspend_io_config,
.suspend_io_count = ARRAY_SIZE(imx53_suspend_io_config),
};
#define MX5_MAX_SUSPEND_IOSTATE ARRAY_SIZE(imx53_suspend_io_config)
/*
* This structure is for passing necessary data for low level ocram
* suspend code(arch/arm/mach-imx/suspend-imx53.S), if this struct
* definition is changed, the offset definition in that file
* must be also changed accordingly otherwise, the suspend to ocram
* function will be broken!
*/
struct imx5_cpu_suspend_info {
void __iomem *m4if_base;
void __iomem *iomuxc_base;
u32 io_count;
struct imx5_suspend_io_state io_state[MX5_MAX_SUSPEND_IOSTATE];
} __aligned(8);
static void __iomem *ccm_base;
static void __iomem *cortex_base;
static void __iomem *gpc_base;
void __init imx5_pm_set_ccm_base(void __iomem *base)
{
ccm_base = base;
}
static void __iomem *suspend_ocram_base;
static void (*imx5_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
/*
* set cpu low power mode before WFI instruction. This function is called
@ -161,8 +230,15 @@ static int mx5_suspend_enter(suspend_state_t state)
/*clear the EMPGC0/1 bits */
__raw_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR);
__raw_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR);
if (imx5_suspend_in_ocram_fn)
imx5_suspend_in_ocram_fn(suspend_ocram_base);
else
cpu_do_idle();
} else {
cpu_do_idle();
}
cpu_do_idle();
/* return registers to default idle state */
mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE);
@ -194,6 +270,111 @@ static void imx5_pm_idle(void)
imx5_cpu_do_idle();
}
static int __init imx_suspend_alloc_ocram(
size_t size,
void __iomem **virt_out,
phys_addr_t *phys_out)
{
struct device_node *node;
struct platform_device *pdev;
struct gen_pool *ocram_pool;
unsigned long ocram_base;
void __iomem *virt;
phys_addr_t phys;
int ret = 0;
/* Copied from imx6: TODO factorize */
node = of_find_compatible_node(NULL, NULL, "mmio-sram");
if (!node) {
pr_warn("%s: failed to find ocram node!\n", __func__);
return -ENODEV;
}
pdev = of_find_device_by_node(node);
if (!pdev) {
pr_warn("%s: failed to find ocram device!\n", __func__);
ret = -ENODEV;
goto put_node;
}
ocram_pool = dev_get_gen_pool(&pdev->dev);
if (!ocram_pool) {
pr_warn("%s: ocram pool unavailable!\n", __func__);
ret = -ENODEV;
goto put_node;
}
ocram_base = gen_pool_alloc(ocram_pool, size);
if (!ocram_base) {
pr_warn("%s: unable to alloc ocram!\n", __func__);
ret = -ENOMEM;
goto put_node;
}
phys = gen_pool_virt_to_phys(ocram_pool, ocram_base);
virt = __arm_ioremap_exec(phys, size, false);
if (phys_out)
*phys_out = phys;
if (virt_out)
*virt_out = virt;
put_node:
of_node_put(node);
return ret;
}
static int __init imx5_suspend_init(const struct imx5_pm_data *soc_data)
{
struct imx5_cpu_suspend_info *suspend_info;
int ret;
/* Need this to avoid compile error due to const typeof in fncpy.h */
void (*suspend_asm)(void __iomem *) = soc_data->suspend_asm;
if (!suspend_asm)
return 0;
if (!soc_data->suspend_asm_sz || !*soc_data->suspend_asm_sz)
return -EINVAL;
ret = imx_suspend_alloc_ocram(
*soc_data->suspend_asm_sz + sizeof(*suspend_info),
&suspend_ocram_base, NULL);
if (ret)
return ret;
suspend_info = suspend_ocram_base;
suspend_info->io_count = soc_data->suspend_io_count;
memcpy(suspend_info->io_state, soc_data->suspend_io_config,
sizeof(*suspend_info->io_state) * soc_data->suspend_io_count);
suspend_info->m4if_base = ioremap(soc_data->m4if_addr, SZ_16K);
if (!suspend_info->m4if_base) {
ret = -ENOMEM;
goto failed_map_m4if;
}
suspend_info->iomuxc_base = ioremap(soc_data->iomuxc_addr, SZ_16K);
if (!suspend_info->iomuxc_base) {
ret = -ENOMEM;
goto failed_map_iomuxc;
}
imx5_suspend_in_ocram_fn = fncpy(
suspend_ocram_base + sizeof(*suspend_info),
suspend_asm,
*soc_data->suspend_asm_sz);
return 0;
failed_map_iomuxc:
iounmap(suspend_info->m4if_base);
failed_map_m4if:
return ret;
}
static int __init imx5_pm_common_init(const struct imx5_pm_data *data)
{
int ret;
@ -208,6 +389,7 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data)
arm_pm_idle = imx5_pm_idle;
ccm_base = ioremap(data->ccm_addr, SZ_16K);
cortex_base = ioremap(data->cortex_addr, SZ_16K);
gpc_base = ioremap(data->gpc_addr, SZ_16K);
WARN_ON(!ccm_base || !cortex_base || !gpc_base);
@ -219,6 +401,11 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data)
if (ret)
pr_warn("%s: cpuidle init failed %d\n", __func__, ret);
ret = imx5_suspend_init(data);
if (ret)
pr_warn("%s: No DDR LPM support with suspend %d!\n",
__func__, ret);
suspend_set_ops(&mx5_suspend_ops);
return 0;
@ -226,10 +413,12 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data)
void __init imx51_pm_init(void)
{
imx5_pm_common_init(&imx51_pm_data);
if (IS_ENABLED(CONFIG_SOC_IMX51))
imx5_pm_common_init(&imx51_pm_data);
}
void __init imx53_pm_init(void)
{
imx5_pm_common_init(&imx53_pm_data);
if (IS_ENABLED(CONFIG_SOC_IMX53))
imx5_pm_common_init(&imx53_pm_data);
}

View File

@ -255,7 +255,7 @@ static void imx6q_enable_wb(bool enable)
writel_relaxed(val, ccm_base + CCR);
}
int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
{
u32 val = readl_relaxed(ccm_base + CLPCR);
@ -340,7 +340,7 @@ static int imx6q_pm_enter(suspend_state_t state)
{
switch (state) {
case PM_SUSPEND_STANDBY:
imx6q_set_lpm(STOP_POWER_ON);
imx6_set_lpm(STOP_POWER_ON);
imx6q_set_int_mem_clk_lpm(true);
imx_gpc_pre_suspend(false);
if (cpu_is_imx6sl())
@ -350,10 +350,10 @@ static int imx6q_pm_enter(suspend_state_t state)
if (cpu_is_imx6sl())
imx6sl_set_wait_clk(false);
imx_gpc_post_resume();
imx6q_set_lpm(WAIT_CLOCKED);
imx6_set_lpm(WAIT_CLOCKED);
break;
case PM_SUSPEND_MEM:
imx6q_set_lpm(STOP_POWER_OFF);
imx6_set_lpm(STOP_POWER_OFF);
imx6q_set_int_mem_clk_lpm(false);
imx6q_enable_wb(true);
/*
@ -373,7 +373,7 @@ static int imx6q_pm_enter(suspend_state_t state)
imx6_enable_rbc(false);
imx6q_enable_wb(false);
imx6q_set_int_mem_clk_lpm(true);
imx6q_set_lpm(WAIT_CLOCKED);
imx6_set_lpm(WAIT_CLOCKED);
break;
default:
return -EINVAL;
@ -392,11 +392,6 @@ static const struct platform_suspend_ops imx6q_pm_ops = {
.valid = imx6q_pm_valid,
};
void __init imx6q_pm_set_ccm_base(void __iomem *base)
{
ccm_base = base;
}
static int __init imx6_pm_get_base(struct imx6_pm_base *base,
const char *compat)
{
@ -482,8 +477,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
/*
* ccm physical address is not used by asm code currently,
* so get ccm virtual address directly, as we already have
* it from ccm driver.
* so get ccm virtual address directly.
*/
pm_info->ccm_base.vbase = ccm_base;
@ -568,7 +562,7 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata
/*
* This is for SW workaround step #1 of ERR007265, see comments
* in imx6q_set_lpm for details of this errata.
* in imx6_set_lpm for details of this errata.
* Force IOMUXC irq pending, so that the interrupt to GPC can be
* used to deassert dsm_request signal when the signal gets
* asserted unexpectedly.
@ -579,6 +573,24 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata
IMX6Q_GPR1_GINT);
}
void __init imx6_pm_ccm_init(const char *ccm_compat)
{
struct device_node *np;
u32 val;
np = of_find_compatible_node(NULL, NULL, ccm_compat);
ccm_base = of_iomap(np, 0);
BUG_ON(!ccm_base);
/*
* Initialize CCM_CLPCR_LPM into RUN mode to avoid ARM core
* clock being shut down unexpectedly by WAIT mode.
*/
val = readl_relaxed(ccm_base + CLPCR);
val &= ~BM_CLPCR_LPM;
writel_relaxed(val, ccm_base + CLPCR);
}
void __init imx6q_pm_init(void)
{
imx6_pm_common_init(&imx6q_pm_data);

View File

@ -0,0 +1,139 @@
/*
* Copyright (C) 2008-2011 Freescale Semiconductor, Inc.
*/
/*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <linux/linkage.h>
#define M4IF_MCR0_OFFSET (0x008C)
#define M4IF_MCR0_FDVFS (0x1 << 11)
#define M4IF_MCR0_FDVACK (0x1 << 27)
.align 3
/*
* ==================== low level suspend ====================
*
* On entry
* r0: pm_info structure address;
*
* suspend ocram space layout:
* ======================== high address ======================
* .
* .
* .
* ^
* ^
* ^
* imx53_suspend code
* PM_INFO structure(imx53_suspend_info)
* ======================== low address =======================
*/
/* Offsets of members of struct imx53_suspend_info */
#define SUSPEND_INFO_MX53_M4IF_V_OFFSET 0x0
#define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET 0x4
#define SUSPEND_INFO_MX53_IO_COUNT_OFFSET 0x8
#define SUSPEND_INFO_MX53_IO_STATE_OFFSET 0xc
ENTRY(imx53_suspend)
stmfd sp!, {r4,r5,r6,r7}
/* Save pad config */
ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET]
cmp r1, #0
beq skip_pad_conf_1
add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET
ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET]
1:
ldr r5, [r2], #12 /* IOMUXC register offset */
ldr r6, [r3, r5] /* current value */
str r6, [r2], #4 /* save area */
subs r1, r1, #1
bne 1b
skip_pad_conf_1:
/* Set FDVFS bit of M4IF_MCR0 to request DDR to enter self-refresh */
ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET]
ldr r2,[r1, #M4IF_MCR0_OFFSET]
orr r2, r2, #M4IF_MCR0_FDVFS
str r2,[r1, #M4IF_MCR0_OFFSET]
/* Poll FDVACK bit of M4IF_MCR to wait for DDR to enter self-refresh */
wait_sr_ack:
ldr r2,[r1, #M4IF_MCR0_OFFSET]
ands r2, r2, #M4IF_MCR0_FDVACK
beq wait_sr_ack
/* Set pad config */
ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET]
cmp r1, #0
beq skip_pad_conf_2
add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET
ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET]
2:
ldr r5, [r2], #4 /* IOMUXC register offset */
ldr r6, [r2], #4 /* clear */
ldr r7, [r3, r5]
bic r7, r7, r6
ldr r6, [r2], #8 /* set */
orr r7, r7, r6
str r7, [r3, r5]
subs r1, r1, #1
bne 2b
skip_pad_conf_2:
/* Zzz, enter stop mode */
wfi
nop
nop
nop
nop
/* Restore pad config */
ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET]
cmp r1, #0
beq skip_pad_conf_3
add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET
ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET]
3:
ldr r5, [r2], #12 /* IOMUXC register offset */
ldr r6, [r2], #4 /* saved value */
str r6, [r3, r5]
subs r1, r1, #1
bne 3b
skip_pad_conf_3:
/* Clear FDVFS bit of M4IF_MCR0 to request DDR to exit self-refresh */
ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET]
ldr r2,[r1, #M4IF_MCR0_OFFSET]
bic r2, r2, #M4IF_MCR0_FDVFS
str r2,[r1, #M4IF_MCR0_OFFSET]
/* Poll FDVACK bit of M4IF_MCR to wait for DDR to exit self-refresh */
wait_ar_ack:
ldr r2,[r1, #M4IF_MCR0_OFFSET]
ands r2, r2, #M4IF_MCR0_FDVACK
bne wait_ar_ack
/* Restore registers */
ldmfd sp!, {r4,r5,r6,r7}
mov pc, lr
ENDPROC(imx53_suspend)
ENTRY(imx53_suspend_sz)
.word . - imx53_suspend

View File

@ -1,385 +0,0 @@
/*
* linux/arch/arm/plat-mxc/time.c
*
* Copyright (C) 2000-2001 Deep Blue Solutions
* Copyright (C) 2002 Shane Nay (shane@minirl.com)
* Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
* Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/clockchips.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/sched_clock.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <asm/mach/time.h>
#include "common.h"
#include "hardware.h"
/*
* There are 2 versions of the timer hardware on Freescale MXC hardware.
* Version 1: MX1/MXL, MX21, MX27.
* Version 2: MX25, MX31, MX35, MX37, MX51
*/
/* defines common for all i.MX */
#define MXC_TCTL 0x00
#define MXC_TCTL_TEN (1 << 0) /* Enable module */
#define MXC_TPRER 0x04
/* MX1, MX21, MX27 */
#define MX1_2_TCTL_CLK_PCLK1 (1 << 1)
#define MX1_2_TCTL_IRQEN (1 << 4)
#define MX1_2_TCTL_FRR (1 << 8)
#define MX1_2_TCMP 0x08
#define MX1_2_TCN 0x10
#define MX1_2_TSTAT 0x14
/* MX21, MX27 */
#define MX2_TSTAT_CAPT (1 << 1)
#define MX2_TSTAT_COMP (1 << 0)
/* MX31, MX35, MX25, MX5, MX6 */
#define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */
#define V2_TCTL_CLK_IPG (1 << 6)
#define V2_TCTL_CLK_PER (2 << 6)
#define V2_TCTL_CLK_OSC_DIV8 (5 << 6)
#define V2_TCTL_FRR (1 << 9)
#define V2_TCTL_24MEN (1 << 10)
#define V2_TPRER_PRE24M 12
#define V2_IR 0x0c
#define V2_TSTAT 0x08
#define V2_TSTAT_OF1 (1 << 0)
#define V2_TCN 0x24
#define V2_TCMP 0x10
#define V2_TIMER_RATE_OSC_DIV8 3000000
#define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
#define timer_is_v2() (!timer_is_v1())
static struct clock_event_device clockevent_mxc;
static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
static void __iomem *timer_base;
static inline void gpt_irq_disable(void)
{
unsigned int tmp;
if (timer_is_v2())
__raw_writel(0, timer_base + V2_IR);
else {
tmp = __raw_readl(timer_base + MXC_TCTL);
__raw_writel(tmp & ~MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL);
}
}
static inline void gpt_irq_enable(void)
{
if (timer_is_v2())
__raw_writel(1<<0, timer_base + V2_IR);
else {
__raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
timer_base + MXC_TCTL);
}
}
static void gpt_irq_acknowledge(void)
{
if (timer_is_v1()) {
if (cpu_is_mx1())
__raw_writel(0, timer_base + MX1_2_TSTAT);
else
__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
timer_base + MX1_2_TSTAT);
} else if (timer_is_v2())
__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
}
static void __iomem *sched_clock_reg;
static u64 notrace mxc_read_sched_clock(void)
{
return sched_clock_reg ? __raw_readl(sched_clock_reg) : 0;
}
static struct delay_timer imx_delay_timer;
static unsigned long imx_read_current_timer(void)
{
return __raw_readl(sched_clock_reg);
}
static int __init mxc_clocksource_init(struct clk *timer_clk)
{
unsigned int c = clk_get_rate(timer_clk);
void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
imx_delay_timer.read_current_timer = &imx_read_current_timer;
imx_delay_timer.freq = c;
register_current_timer_delay(&imx_delay_timer);
sched_clock_reg = reg;
sched_clock_register(mxc_read_sched_clock, 32, c);
return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32,
clocksource_mmio_readl_up);
}
/* clock event */
static int mx1_2_set_next_event(unsigned long evt,
struct clock_event_device *unused)
{
unsigned long tcmp;
tcmp = __raw_readl(timer_base + MX1_2_TCN) + evt;
__raw_writel(tcmp, timer_base + MX1_2_TCMP);
return (int)(tcmp - __raw_readl(timer_base + MX1_2_TCN)) < 0 ?
-ETIME : 0;
}
static int v2_set_next_event(unsigned long evt,
struct clock_event_device *unused)
{
unsigned long tcmp;
tcmp = __raw_readl(timer_base + V2_TCN) + evt;
__raw_writel(tcmp, timer_base + V2_TCMP);
return evt < 0x7fffffff &&
(int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ?
-ETIME : 0;
}
#ifdef DEBUG
static const char *clock_event_mode_label[] = {
[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
[CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
[CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
[CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED",
[CLOCK_EVT_MODE_RESUME] = "CLOCK_EVT_MODE_RESUME",
};
#endif /* DEBUG */
static void mxc_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
unsigned long flags;
/*
* The timer interrupt generation is disabled at least
* for enough time to call mxc_set_next_event()
*/
local_irq_save(flags);
/* Disable interrupt in GPT module */
gpt_irq_disable();
if (mode != clockevent_mode) {
/* Set event time into far-far future */
if (timer_is_v2())
__raw_writel(__raw_readl(timer_base + V2_TCN) - 3,
timer_base + V2_TCMP);
else
__raw_writel(__raw_readl(timer_base + MX1_2_TCN) - 3,
timer_base + MX1_2_TCMP);
/* Clear pending interrupt */
gpt_irq_acknowledge();
}
#ifdef DEBUG
printk(KERN_INFO "mxc_set_mode: changing mode from %s to %s\n",
clock_event_mode_label[clockevent_mode],
clock_event_mode_label[mode]);
#endif /* DEBUG */
/* Remember timer mode */
clockevent_mode = mode;
local_irq_restore(flags);
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
printk(KERN_ERR"mxc_set_mode: Periodic mode is not "
"supported for i.MX\n");
break;
case CLOCK_EVT_MODE_ONESHOT:
/*
* Do not put overhead of interrupt enable/disable into
* mxc_set_next_event(), the core has about 4 minutes
* to call mxc_set_next_event() or shutdown clock after
* mode switching
*/
local_irq_save(flags);
gpt_irq_enable();
local_irq_restore(flags);
break;
case CLOCK_EVT_MODE_SHUTDOWN:
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_RESUME:
/* Left event sources disabled, no more interrupts appear */
break;
}
}
/*
* IRQ handler for the timer
*/
static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evt = &clockevent_mxc;
uint32_t tstat;
if (timer_is_v2())
tstat = __raw_readl(timer_base + V2_TSTAT);
else
tstat = __raw_readl(timer_base + MX1_2_TSTAT);
gpt_irq_acknowledge();
evt->event_handler(evt);
return IRQ_HANDLED;
}
static struct irqaction mxc_timer_irq = {
.name = "i.MX Timer Tick",
.flags = IRQF_TIMER | IRQF_IRQPOLL,
.handler = mxc_timer_interrupt,
};
static struct clock_event_device clockevent_mxc = {
.name = "mxc_timer1",
.features = CLOCK_EVT_FEAT_ONESHOT,
.set_mode = mxc_set_mode,
.set_next_event = mx1_2_set_next_event,
.rating = 200,
};
static int __init mxc_clockevent_init(struct clk *timer_clk)
{
if (timer_is_v2())
clockevent_mxc.set_next_event = v2_set_next_event;
clockevent_mxc.cpumask = cpumask_of(0);
clockevents_config_and_register(&clockevent_mxc,
clk_get_rate(timer_clk),
0xff, 0xfffffffe);
return 0;
}
static void __init _mxc_timer_init(int irq,
struct clk *clk_per, struct clk *clk_ipg)
{
uint32_t tctl_val;
if (IS_ERR(clk_per)) {
pr_err("i.MX timer: unable to get clk\n");
return;
}
if (!IS_ERR(clk_ipg))
clk_prepare_enable(clk_ipg);
clk_prepare_enable(clk_per);
/*
* Initialise to a known state (all timers off, and timing reset)
*/
__raw_writel(0, timer_base + MXC_TCTL);
__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
if (timer_is_v2()) {
tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8) {
tctl_val |= V2_TCTL_CLK_OSC_DIV8;
if (cpu_is_imx6dl() || cpu_is_imx6sx()) {
/* 24 / 8 = 3 MHz */
__raw_writel(7 << V2_TPRER_PRE24M,
timer_base + MXC_TPRER);
tctl_val |= V2_TCTL_24MEN;
}
} else {
tctl_val |= V2_TCTL_CLK_PER;
}
} else {
tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
}
__raw_writel(tctl_val, timer_base + MXC_TCTL);
/* init and register the timer to the framework */
mxc_clocksource_init(clk_per);
mxc_clockevent_init(clk_per);
/* Make irqs happen */
setup_irq(irq, &mxc_timer_irq);
}
void __init mxc_timer_init(void __iomem *base, int irq)
{
struct clk *clk_per = clk_get_sys("imx-gpt.0", "per");
struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
timer_base = base;
_mxc_timer_init(irq, clk_per, clk_ipg);
}
static void __init mxc_timer_init_dt(struct device_node *np)
{
struct clk *clk_per, *clk_ipg;
int irq;
if (timer_base)
return;
timer_base = of_iomap(np, 0);
WARN_ON(!timer_base);
irq = irq_of_parse_and_map(np, 0);
clk_ipg = of_clk_get_by_name(np, "ipg");
/* Try osc_per first, and fall back to per otherwise */
clk_per = of_clk_get_by_name(np, "osc_per");
if (IS_ERR(clk_per))
clk_per = of_clk_get_by_name(np, "per");
_mxc_timer_init(irq, clk_per, clk_ipg);
}
CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", mxc_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx50_timer, "fsl,imx50-gpt", mxc_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx51_timer, "fsl,imx51-gpt", mxc_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx53_timer, "fsl,imx53-gpt", mxc_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx6q_timer, "fsl,imx6q-gpt", mxc_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx6sl_timer, "fsl,imx6sl-gpt", mxc_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx6sx_timer, "fsl,imx6sx-gpt", mxc_timer_init_dt);

View File

@ -0,0 +1 @@
obj-y += board-dt.o

View File

@ -0,0 +1,3 @@
# Empty file waiting for deletion once Makefile.boot isn't needed any more.
# Patch waits for application at
# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 .

View File

@ -0,0 +1,22 @@
/*
* Device Tree board file for NXP LPC18xx/43xx
*
* Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <asm/mach/arch.h>
static const char *const lpc18xx_43xx_compat[] __initconst = {
"nxp,lpc1850",
"nxp,lpc4350",
"nxp,lpc4370",
NULL
};
DT_MACHINE_START(LPC18XXDT, "NXP LPC18xx/43xx (Device Tree)")
.dt_compat = lpc18xx_43xx_compat,
MACHINE_END

View File

@ -17,11 +17,10 @@
#include <asm/assembler.h>
#include <mach/board-ams-delta.h>
#include <mach/irqs.h>
#include <mach/ams-delta-fiq.h>
#include "iomap.h"
#include "soc.h"
/*
* GPIO related definitions, copied from arch/arm/plat-omap/gpio.c.

View File

@ -626,6 +626,7 @@ MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
.map_io = ams_delta_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = ams_delta_init,
.init_late = ams_delta_init_late,
.init_time = omap1_timer_init,

View File

@ -362,6 +362,7 @@ MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample")
.map_io = omap_fsample_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = omap_fsample_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -82,6 +82,7 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
.map_io = omap16xx_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = omap_generic_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -426,6 +426,7 @@ MACHINE_START(OMAP_H2, "TI-H2")
.map_io = omap16xx_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = h2_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -16,6 +16,7 @@
#include <linux/i2c/tps65010.h>
#include "common.h"
#include "board-h3.h"
#include "mmc.h"

View File

@ -452,6 +452,7 @@ MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
.map_io = omap16xx_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = h3_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -601,6 +601,7 @@ MACHINE_START(HERALD, "HTC Herald")
.map_io = htcherald_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = htcherald_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -456,6 +456,7 @@ MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
.map_io = innovator_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = innovator_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -294,6 +294,7 @@ MACHINE_START(NOKIA770, "Nokia 770")
.map_io = omap16xx_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = omap_nokia770_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -610,6 +610,7 @@ MACHINE_START(OMAP_OSK, "TI-OSK")
.map_io = omap16xx_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = osk_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -235,6 +235,7 @@ MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
.map_io = omap15xx_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = omap_palmte_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -282,6 +282,7 @@ MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T")
.map_io = omap15xx_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = omap_palmtt_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -297,6 +297,7 @@ MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71")
.map_io = omap15xx_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = omap_palmz71_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -324,6 +324,7 @@ MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
.map_io = omap_perseus2_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = omap_perseus2_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -343,6 +343,7 @@ MACHINE_START(SX1, "OMAP310 based Siemens SX1")
.map_io = omap15xx_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = omap_sx1_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -288,6 +288,7 @@ MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
.map_io = omap15xx_map_io,
.init_early = omap1_init_early,
.init_irq = omap1_init_irq,
.handle_irq = omap1_handle_irq,
.init_machine = voiceblue_init,
.init_late = omap1_init_late,
.init_time = omap1_timer_init,

View File

@ -30,10 +30,14 @@
#include <linux/i2c-omap.h>
#include <linux/reboot.h>
#include <asm/exception.h>
#include <plat/i2c.h>
#include <mach/irqs.h>
#include "soc.h"
#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
void omap7xx_map_io(void);
#else
@ -73,6 +77,7 @@ static inline int omap_serial_wakeup_init(void)
void omap1_init_early(void);
void omap1_init_irq(void);
void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs);
void omap1_init_late(void);
void omap1_restart(enum reboot_mode, const char *);
@ -91,8 +96,6 @@ static inline int __init omap_32k_timer_init(void)
}
#endif
extern u32 omap_irq_flags;
#ifdef CONFIG_ARCH_OMAP16XX
extern int ocpi_enable(void);
#else

View File

@ -28,7 +28,7 @@
#include <linux/omap-dma.h>
#include <mach/tc.h>
#include <mach/irqs.h>
#include "soc.h"
#define OMAP1_DMA_BASE (0xfffed800)
#define OMAP1_LOGICAL_DMA_CH_COUNT 17

View File

@ -21,6 +21,8 @@
#include <mach/irqs.h>
#include "soc.h"
#define OMAP1610_GPIO1_BASE 0xfffbe400
#define OMAP1610_GPIO2_BASE 0xfffbec00
#define OMAP1610_GPIO3_BASE 0xfffbb400

View File

@ -21,6 +21,8 @@
#include <mach/irqs.h>
#include "soc.h"
#define OMAP7XX_GPIO1_BASE 0xfffbc000
#define OMAP7XX_GPIO2_BASE 0xfffbc800
#define OMAP7XX_GPIO3_BASE 0xfffbd000

View File

@ -27,7 +27,6 @@
#define OMAP_I2C_SIZE 0x3f
#define OMAP1_I2C_BASE 0xfffb3800
#define OMAP1_INT_I2C (32 + 4)
static const char name[] = "omap_i2c";
@ -67,7 +66,7 @@ int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *pdata,
res[0].start = OMAP1_I2C_BASE;
res[0].end = res[0].start + OMAP_I2C_SIZE;
res[0].flags = IORESOURCE_MEM;
res[1].start = OMAP1_INT_I2C;
res[1].start = INT_I2C;
res[1].flags = IORESOURCE_IRQ;
pdev->resource = res;

View File

@ -1,39 +0,0 @@
/*
* arch/arm/mach-omap1/include/mach/entry-macro.S
*
* Low-level IRQ helper macros for OMAP-based platforms
*
* Copyright (C) 2009 Texas Instruments
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <mach/hardware.h>
#include <mach/irqs.h>
.macro get_irqnr_preamble, base, tmp
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \base, =OMAP1_IO_ADDRESS(OMAP_IH1_BASE)
ldr \irqnr, [\base, #IRQ_ITR_REG_OFFSET]
ldr \tmp, [\base, #IRQ_MIR_REG_OFFSET]
mov \irqstat, #0xffffffff
bic \tmp, \irqstat, \tmp
tst \irqnr, \tmp
beq 1510f
ldr \irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
ldr \tmp, =omap_irq_flags @ irq flags address
ldr \tmp, [\tmp, #0] @ irq flags value
cmp \irqnr, #0
ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
cmpeq \irqnr, \tmp
ldreq \base, =OMAP1_IO_ADDRESS(OMAP_IH2_BASE)
ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
addeqs \irqnr, \irqnr, #32
1510:
.endm

View File

@ -34,84 +34,84 @@
* NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
*
*/
#define INT_CAMERA 1
#define INT_FIQ 3
#define INT_RTDX 6
#define INT_DSP_MMU_ABORT 7
#define INT_HOST 8
#define INT_ABORT 9
#define INT_BRIDGE_PRIV 13
#define INT_GPIO_BANK1 14
#define INT_UART3 15
#define INT_TIMER3 16
#define INT_DMA_CH0_6 19
#define INT_DMA_CH1_7 20
#define INT_DMA_CH2_8 21
#define INT_DMA_CH3 22
#define INT_DMA_CH4 23
#define INT_DMA_CH5 24
#define INT_TIMER1 26
#define INT_WD_TIMER 27
#define INT_BRIDGE_PUB 28
#define INT_TIMER2 30
#define INT_LCD_CTRL 31
#define INT_CAMERA (NR_IRQS_LEGACY + 1)
#define INT_FIQ (NR_IRQS_LEGACY + 3)
#define INT_RTDX (NR_IRQS_LEGACY + 6)
#define INT_DSP_MMU_ABORT (NR_IRQS_LEGACY + 7)
#define INT_HOST (NR_IRQS_LEGACY + 8)
#define INT_ABORT (NR_IRQS_LEGACY + 9)
#define INT_BRIDGE_PRIV (NR_IRQS_LEGACY + 13)
#define INT_GPIO_BANK1 (NR_IRQS_LEGACY + 14)
#define INT_UART3 (NR_IRQS_LEGACY + 15)
#define INT_TIMER3 (NR_IRQS_LEGACY + 16)
#define INT_DMA_CH0_6 (NR_IRQS_LEGACY + 19)
#define INT_DMA_CH1_7 (NR_IRQS_LEGACY + 20)
#define INT_DMA_CH2_8 (NR_IRQS_LEGACY + 21)
#define INT_DMA_CH3 (NR_IRQS_LEGACY + 22)
#define INT_DMA_CH4 (NR_IRQS_LEGACY + 23)
#define INT_DMA_CH5 (NR_IRQS_LEGACY + 24)
#define INT_TIMER1 (NR_IRQS_LEGACY + 26)
#define INT_WD_TIMER (NR_IRQS_LEGACY + 27)
#define INT_BRIDGE_PUB (NR_IRQS_LEGACY + 28)
#define INT_TIMER2 (NR_IRQS_LEGACY + 30)
#define INT_LCD_CTRL (NR_IRQS_LEGACY + 31)
/*
* OMAP-1510 specific IRQ numbers for interrupt handler 1
*/
#define INT_1510_IH2_IRQ 0
#define INT_1510_RES2 2
#define INT_1510_SPI_TX 4
#define INT_1510_SPI_RX 5
#define INT_1510_DSP_MAILBOX1 10
#define INT_1510_DSP_MAILBOX2 11
#define INT_1510_RES12 12
#define INT_1510_LB_MMU 17
#define INT_1510_RES18 18
#define INT_1510_LOCAL_BUS 29
#define INT_1510_IH2_IRQ (NR_IRQS_LEGACY + 0)
#define INT_1510_RES2 (NR_IRQS_LEGACY + 2)
#define INT_1510_SPI_TX (NR_IRQS_LEGACY + 4)
#define INT_1510_SPI_RX (NR_IRQS_LEGACY + 5)
#define INT_1510_DSP_MAILBOX1 (NR_IRQS_LEGACY + 10)
#define INT_1510_DSP_MAILBOX2 (NR_IRQS_LEGACY + 11)
#define INT_1510_RES12 (NR_IRQS_LEGACY + 12)
#define INT_1510_LB_MMU (NR_IRQS_LEGACY + 17)
#define INT_1510_RES18 (NR_IRQS_LEGACY + 18)
#define INT_1510_LOCAL_BUS (NR_IRQS_LEGACY + 29)
/*
* OMAP-1610 specific IRQ numbers for interrupt handler 1
*/
#define INT_1610_IH2_IRQ INT_1510_IH2_IRQ
#define INT_1610_IH2_FIQ 2
#define INT_1610_McBSP2_TX 4
#define INT_1610_McBSP2_RX 5
#define INT_1610_DSP_MAILBOX1 10
#define INT_1610_DSP_MAILBOX2 11
#define INT_1610_LCD_LINE 12
#define INT_1610_GPTIMER1 17
#define INT_1610_GPTIMER2 18
#define INT_1610_SSR_FIFO_0 29
#define INT_1610_IH2_FIQ (NR_IRQS_LEGACY + 2)
#define INT_1610_McBSP2_TX (NR_IRQS_LEGACY + 4)
#define INT_1610_McBSP2_RX (NR_IRQS_LEGACY + 5)
#define INT_1610_DSP_MAILBOX1 (NR_IRQS_LEGACY + 10)
#define INT_1610_DSP_MAILBOX2 (NR_IRQS_LEGACY + 11)
#define INT_1610_LCD_LINE (NR_IRQS_LEGACY + 12)
#define INT_1610_GPTIMER1 (NR_IRQS_LEGACY + 17)
#define INT_1610_GPTIMER2 (NR_IRQS_LEGACY + 18)
#define INT_1610_SSR_FIFO_0 (NR_IRQS_LEGACY + 29)
/*
* OMAP-7xx specific IRQ numbers for interrupt handler 1
*/
#define INT_7XX_IH2_FIQ 0
#define INT_7XX_IH2_IRQ 1
#define INT_7XX_USB_NON_ISO 2
#define INT_7XX_USB_ISO 3
#define INT_7XX_ICR 4
#define INT_7XX_EAC 5
#define INT_7XX_GPIO_BANK1 6
#define INT_7XX_GPIO_BANK2 7
#define INT_7XX_GPIO_BANK3 8
#define INT_7XX_McBSP2TX 10
#define INT_7XX_McBSP2RX 11
#define INT_7XX_McBSP2RX_OVF 12
#define INT_7XX_LCD_LINE 14
#define INT_7XX_GSM_PROTECT 15
#define INT_7XX_TIMER3 16
#define INT_7XX_GPIO_BANK5 17
#define INT_7XX_GPIO_BANK6 18
#define INT_7XX_SPGIO_WR 29
#define INT_7XX_IH2_FIQ (NR_IRQS_LEGACY + 0)
#define INT_7XX_IH2_IRQ (NR_IRQS_LEGACY + 1)
#define INT_7XX_USB_NON_ISO (NR_IRQS_LEGACY + 2)
#define INT_7XX_USB_ISO (NR_IRQS_LEGACY + 3)
#define INT_7XX_ICR (NR_IRQS_LEGACY + 4)
#define INT_7XX_EAC (NR_IRQS_LEGACY + 5)
#define INT_7XX_GPIO_BANK1 (NR_IRQS_LEGACY + 6)
#define INT_7XX_GPIO_BANK2 (NR_IRQS_LEGACY + 7)
#define INT_7XX_GPIO_BANK3 (NR_IRQS_LEGACY + 8)
#define INT_7XX_McBSP2TX (NR_IRQS_LEGACY + 10)
#define INT_7XX_McBSP2RX (NR_IRQS_LEGACY + 11)
#define INT_7XX_McBSP2RX_OVF (NR_IRQS_LEGACY + 12)
#define INT_7XX_LCD_LINE (NR_IRQS_LEGACY + 14)
#define INT_7XX_GSM_PROTECT (NR_IRQS_LEGACY + 15)
#define INT_7XX_TIMER3 (NR_IRQS_LEGACY + 16)
#define INT_7XX_GPIO_BANK5 (NR_IRQS_LEGACY + 17)
#define INT_7XX_GPIO_BANK6 (NR_IRQS_LEGACY + 18)
#define INT_7XX_SPGIO_WR (NR_IRQS_LEGACY + 29)
/*
* IRQ numbers for interrupt handler 2
*
* NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
*/
#define IH2_BASE 32
#define IH2_BASE (NR_IRQS_LEGACY + 32)
#define INT_KEYBOARD (1 + IH2_BASE)
#define INT_uWireTX (2 + IH2_BASE)
@ -255,11 +255,7 @@
#endif
#define OMAP_FPGA_IRQ_END (OMAP_FPGA_IRQ_BASE + OMAP_FPGA_NR_IRQS)
#define NR_IRQS OMAP_FPGA_IRQ_END
#define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32))
#include <mach/hardware.h>
#define OMAP_IRQ_BIT(irq) (1 << ((irq - NR_IRQS_LEGACY) % 32))
#ifdef CONFIG_FIQ
#define FIQ_START 1024

View File

@ -5,6 +5,9 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
/* REVISIT: omap1 legacy drivers still rely on this */
#include <mach/soc.h>
/*
* Bus address is physical address, except for OMAP-1510 Local Bus.
* OMAP-1510 bus address is translated into a Local Bus address if the
@ -14,7 +17,6 @@
* because of the strncmp().
*/
#if defined(CONFIG_ARCH_OMAP15XX) && !defined(__ASSEMBLER__)
#include <mach/soc.h>
/*
* OMAP-1510 Local Bus address offset

View File

@ -27,11 +27,6 @@
*/
#define OMAP_UART_INFO_OFS 0x3ffc
/* OMAP1 serial ports */
#define OMAP1_UART1_BASE 0xfffb0000
#define OMAP1_UART2_BASE 0xfffb0800
#define OMAP1_UART3_BASE 0xfffb9800
#define OMAP_PORT_SHIFT 2
#define OMAP7XX_PORT_SHIFT 0

View File

@ -28,6 +28,10 @@
#ifndef __ASM_ARCH_OMAP_CPU_H
#define __ASM_ARCH_OMAP_CPU_H
#include <asm/irq.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#ifndef __ASSEMBLY__
#include <linux/bitops.h>

View File

@ -43,6 +43,7 @@
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/exception.h>
#include <asm/mach/irq.h>
#include "soc.h"
@ -56,66 +57,41 @@
struct omap_irq_bank {
unsigned long base_reg;
void __iomem *va;
unsigned long trigger_map;
unsigned long wake_enable;
};
u32 omap_irq_flags;
static u32 omap_l2_irq;
static unsigned int irq_bank_count;
static struct omap_irq_bank *irq_banks;
static struct irq_domain *domain;
static inline unsigned int irq_bank_readl(int bank, int offset)
{
return readl_relaxed(irq_banks[bank].va + offset);
}
static inline void irq_bank_writel(unsigned long value, int bank, int offset)
{
omap_writel(value, irq_banks[bank].base_reg + offset);
writel_relaxed(value, irq_banks[bank].va + offset);
}
static void omap_ack_irq(struct irq_data *d)
static void omap_ack_irq(int irq)
{
if (d->irq > 31)
omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG_OFFSET);
if (irq > 31)
writel_relaxed(0x1, irq_banks[1].va + IRQ_CONTROL_REG_OFFSET);
omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG_OFFSET);
}
static void omap_mask_irq(struct irq_data *d)
{
int bank = IRQ_BANK(d->irq);
u32 l;
l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
l |= 1 << IRQ_BIT(d->irq);
omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
}
static void omap_unmask_irq(struct irq_data *d)
{
int bank = IRQ_BANK(d->irq);
u32 l;
l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
l &= ~(1 << IRQ_BIT(d->irq));
omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
writel_relaxed(0x1, irq_banks[0].va + IRQ_CONTROL_REG_OFFSET);
}
static void omap_mask_ack_irq(struct irq_data *d)
{
omap_mask_irq(d);
omap_ack_irq(d);
struct irq_chip_type *ct = irq_data_get_chip_type(d);
ct->chip.irq_mask(d);
omap_ack_irq(d->irq);
}
static int omap_wake_irq(struct irq_data *d, unsigned int enable)
{
int bank = IRQ_BANK(d->irq);
if (enable)
irq_banks[bank].wake_enable |= IRQ_BIT(d->irq);
else
irq_banks[bank].wake_enable &= ~IRQ_BIT(d->irq);
return 0;
}
/*
* Allows tuning the IRQ type and priority
*
@ -165,46 +141,105 @@ static struct omap_irq_bank omap1610_irq_banks[] = {
};
#endif
static struct irq_chip omap_irq_chip = {
.name = "MPU",
.irq_ack = omap_mask_ack_irq,
.irq_mask = omap_mask_irq,
.irq_unmask = omap_unmask_irq,
.irq_set_wake = omap_wake_irq,
};
asmlinkage void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs)
{
void __iomem *l1 = irq_banks[0].va;
void __iomem *l2 = irq_banks[1].va;
u32 irqnr;
do {
irqnr = readl_relaxed(l1 + IRQ_ITR_REG_OFFSET);
irqnr &= ~(readl_relaxed(l1 + IRQ_MIR_REG_OFFSET) & 0xffffffff);
if (!irqnr)
break;
irqnr = readl_relaxed(l1 + IRQ_SIR_FIQ_REG_OFFSET);
if (irqnr)
goto irq;
irqnr = readl_relaxed(l1 + IRQ_SIR_IRQ_REG_OFFSET);
if (irqnr == omap_l2_irq) {
irqnr = readl_relaxed(l2 + IRQ_SIR_IRQ_REG_OFFSET);
if (irqnr)
irqnr += 32;
}
irq:
if (irqnr)
handle_domain_irq(domain, irqnr, regs);
else
break;
} while (irqnr);
}
static __init void
omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
{
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
gc = irq_alloc_generic_chip("MPU", 1, irq_start, base,
handle_level_irq);
ct = gc->chip_types;
ct->chip.irq_ack = omap_mask_ack_irq;
ct->chip.irq_mask = irq_gc_mask_set_bit;
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
ct->chip.irq_set_wake = irq_gc_set_wake;
ct->regs.mask = IRQ_MIR_REG_OFFSET;
irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
}
void __init omap1_init_irq(void)
{
int i, j;
struct irq_chip_type *ct;
struct irq_data *d = NULL;
int i, j, irq_base;
unsigned long nr_irqs;
#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
if (cpu_is_omap7xx()) {
omap_irq_flags = INT_7XX_IH2_IRQ;
irq_banks = omap7xx_irq_banks;
irq_bank_count = ARRAY_SIZE(omap7xx_irq_banks);
}
#endif
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
omap_irq_flags = INT_1510_IH2_IRQ;
irq_banks = omap1510_irq_banks;
irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
}
if (cpu_is_omap310()) {
omap_irq_flags = INT_1510_IH2_IRQ;
irq_banks = omap310_irq_banks;
irq_bank_count = ARRAY_SIZE(omap310_irq_banks);
}
#endif
#if defined(CONFIG_ARCH_OMAP16XX)
if (cpu_is_omap16xx()) {
omap_irq_flags = INT_1510_IH2_IRQ;
irq_banks = omap1610_irq_banks;
irq_bank_count = ARRAY_SIZE(omap1610_irq_banks);
}
#endif
printk("Total of %i interrupts in %i interrupt banks\n",
irq_bank_count * 32, irq_bank_count);
for (i = 0; i < irq_bank_count; i++) {
irq_banks[i].va = ioremap(irq_banks[i].base_reg, 0xff);
if (WARN_ON(!irq_banks[i].va))
return;
}
nr_irqs = irq_bank_count * 32;
irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
if (irq_base < 0) {
pr_warn("Couldn't allocate IRQ numbers\n");
irq_base = 0;
}
omap_l2_irq = cpu_is_omap7xx() ? irq_base + 1 : irq_base;
omap_l2_irq -= NR_IRQS_LEGACY;
domain = irq_domain_add_legacy(NULL, nr_irqs, irq_base, 0,
&irq_domain_simple_ops, NULL);
pr_info("Total of %lu interrupts in %i interrupt banks\n",
nr_irqs, irq_bank_count);
/* Mask and clear all interrupts */
for (i = 0; i < irq_bank_count; i++) {
@ -227,19 +262,15 @@ void __init omap1_init_irq(void)
irq_trigger = irq_banks[i].trigger_map >> IRQ_BIT(j);
omap_irq_set_cfg(j, 0, 0, irq_trigger);
irq_set_chip_and_handler(j, &omap_irq_chip,
handle_level_irq);
set_irq_flags(j, IRQF_VALID);
}
omap_alloc_gc(irq_banks[i].va, irq_base + i * 32, 32);
}
/* Unmask level 2 handler */
if (cpu_is_omap7xx())
omap_unmask_irq(irq_get_irq_data(INT_7XX_IH2_IRQ));
else if (cpu_is_omap15xx())
omap_unmask_irq(irq_get_irq_data(INT_1510_IH2_IRQ));
else if (cpu_is_omap16xx())
omap_unmask_irq(irq_get_irq_data(INT_1610_IH2_IRQ));
d = irq_get_irq_data(irq_find_mapping(domain, omap_l2_irq));
if (d) {
ct = irq_data_get_chip_type(d);
ct->chip.irq_unmask(d);
}
}

View File

@ -36,7 +36,7 @@
static struct omap_mux_cfg arch_mux_cfg;
#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
static struct pin_config __initdata_or_module omap7xx_pins[] = {
static struct pin_config omap7xx_pins[] = {
MUX_CFG_7XX("E2_7XX_KBR0", 12, 21, 0, 20, 1, 0)
MUX_CFG_7XX("J7_7XX_KBR1", 12, 25, 0, 24, 1, 0)
MUX_CFG_7XX("E1_7XX_KBR2", 12, 29, 0, 28, 1, 0)
@ -82,7 +82,7 @@ MUX_CFG_7XX("UART_7XX_2", 8, 1, 6, 0, 0, 0)
#endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */
#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
static struct pin_config __initdata_or_module omap1xxx_pins[] = {
static struct pin_config omap1xxx_pins[] = {
/*
* description mux mode mux pull pull pull pu_pd pu dbg
* reg offset mode reg bit ena reg
@ -343,7 +343,7 @@ MUX_CFG("Y14_1610_CCP_DATAM", 9, 21, 6, 2, 3, 1, 2, 0, 0)
#define OMAP1XXX_PINS_SZ 0
#endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */
static int __init_or_module omap1_cfg_reg(const struct pin_config *cfg)
static int omap1_cfg_reg(const struct pin_config *cfg)
{
static DEFINE_SPINLOCK(mux_spin_lock);
unsigned long flags;
@ -469,7 +469,7 @@ int __init omap_mux_register(struct omap_mux_cfg *arch_mux_cfg)
/*
* Sets the Omap MUX and PULL_DWN registers based on the table
*/
int __init_or_module omap_cfg_reg(const unsigned long index)
int omap_cfg_reg(const unsigned long index)
{
struct pin_config *reg;

View File

@ -62,6 +62,7 @@
#include "iomap.h"
#include "clock.h"
#include "pm.h"
#include "soc.h"
#include "sram.h"
static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];

Some files were not shown because too many files have changed in this diff Show More