Commit abc3f126 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge branch 'imx/imx6q' into next/soc

Conflicts:
	Documentation/devicetree/bindings/arm/fsl.txt
	arch/arm/Kconfig
	arch/arm/Kconfig.debug
	arch/arm/plat-mxc/include/mach/common.h
parents b8df0ea2 8bcb9765
Freescale i.MX Platforms Device Tree Bindings
-----------------------------------------------
i.MX51 Babbage Board i.MX51 Babbage Board
Required root node properties: Required root node properties:
- compatible = "fsl,imx51-babbage", "fsl,imx51"; - compatible = "fsl,imx51-babbage", "fsl,imx51";
...@@ -17,3 +20,7 @@ Required root node properties: ...@@ -17,3 +20,7 @@ Required root node properties:
i.MX53 Smart Mobile Reference Design Board i.MX53 Smart Mobile Reference Design Board
Required root node properties: Required root node properties:
- compatible = "fsl,imx53-smd", "fsl,imx53"; - compatible = "fsl,imx53-smd", "fsl,imx53";
i.MX6 Quad SABRE Automotive Board
Required root node properties:
- compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
...@@ -793,6 +793,13 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) ...@@ -793,6 +793,13 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained S: Maintained
F: arch/arm/mach-mx5/ F: arch/arm/mach-mx5/
ARM/FREESCALE IMX6
M: Shawn Guo <shawn.guo@linaro.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
T: git git://git.linaro.org/people/shawnguo/linux-2.6.git
F: arch/arm/mach-imx/*imx6*
ARM/GLOMATION GESBC9312SX MACHINE SUPPORT ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org> M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
......
...@@ -1435,7 +1435,7 @@ config SMP ...@@ -1435,7 +1435,7 @@ config SMP
depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \ depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \ ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || ARCH_HIGHBANK ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || ARCH_HIGHBANK || SOC_IMX6Q
select USE_GENERIC_SMP_HELPERS select USE_GENERIC_SMP_HELPERS
select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
help help
......
...@@ -135,6 +135,118 @@ choice ...@@ -135,6 +135,118 @@ choice
Say Y here if you want the debug print routines to direct Say Y here if you want the debug print routines to direct
their output to the UART on Highbank based devices. their output to the UART on Highbank based devices.
config DEBUG_IMX1_UART
bool "i.MX1 Debug UART"
depends on SOC_IMX1
help
Say Y here if you want kernel low-level debugging support
on i.MX1.
config DEBUG_IMX23_UART
bool "i.MX23 Debug UART"
depends on SOC_IMX23
help
Say Y here if you want kernel low-level debugging support
on i.MX23.
config DEBUG_IMX25_UART
bool "i.MX25 Debug UART"
depends on SOC_IMX25
help
Say Y here if you want kernel low-level debugging support
on i.MX25.
config DEBUG_IMX21_IMX27_UART
bool "i.MX21 and i.MX27 Debug UART"
depends on SOC_IMX21 || SOC_IMX27
help
Say Y here if you want kernel low-level debugging support
on i.MX21 or i.MX27.
config DEBUG_IMX28_UART
bool "i.MX28 Debug UART"
depends on SOC_IMX28
help
Say Y here if you want kernel low-level debugging support
on i.MX28.
config DEBUG_IMX31_IMX35_UART
bool "i.MX31 and i.MX35 Debug UART"
depends on SOC_IMX31 || SOC_IMX35
help
Say Y here if you want kernel low-level debugging support
on i.MX31 or i.MX35.
config DEBUG_IMX51_UART
bool "i.MX51 Debug UART"
depends on SOC_IMX51
help
Say Y here if you want kernel low-level debugging support
on i.MX51.
config DEBUG_IMX50_IMX53_UART
bool "i.MX50 and i.MX53 Debug UART"
depends on SOC_IMX50 || SOC_IMX53
help
Say Y here if you want kernel low-level debugging support
on i.MX50 or i.MX53.
config DEBUG_IMX6Q_UART
bool "i.MX6Q Debug UART"
depends on SOC_IMX6Q
help
Say Y here if you want kernel low-level debugging support
on i.MX6Q.
config DEBUG_S3C_UART0
depends on PLAT_SAMSUNG
bool "Use S3C UART 0 for low-level debug"
help
Say Y here if you want the debug print routines to direct
their output to UART 0. The port must have been initialised
by the boot-loader before use.
The uncompressor code port configuration is now handled
by CONFIG_S3C_LOWLEVEL_UART_PORT.
config DEBUG_S3C_UART1
depends on PLAT_SAMSUNG
bool "Use S3C UART 1 for low-level debug"
help
Say Y here if you want the debug print routines to direct
their output to UART 1. The port must have been initialised
by the boot-loader before use.
The uncompressor code port configuration is now handled
by CONFIG_S3C_LOWLEVEL_UART_PORT.
config DEBUG_S3C_UART2
depends on PLAT_SAMSUNG
bool "Use S3C UART 2 for low-level debug"
help
Say Y here if you want the debug print routines to direct
their output to UART 2. The port must have been initialised
by the boot-loader before use.
The uncompressor code port configuration is now handled
by CONFIG_S3C_LOWLEVEL_UART_PORT.
config DEBUG_REALVIEW_STD_PORT
bool "RealView Default UART"
depends on ARCH_REALVIEW
help
Say Y here if you want the debug print routines to direct
their output to the serial port on RealView EB, PB11MP, PBA8
and PBX platforms.
config DEBUG_REALVIEW_PB1176_PORT
bool "RealView PB1176 UART"
depends on MACH_REALVIEW_PB1176
help
Say Y here if you want the debug print routines to direct
their output to the standard serial port on the RealView
PB1176 platform.
endchoice endchoice
config EARLY_PRINTK config EARLY_PRINTK
...@@ -153,18 +265,6 @@ config OC_ETM ...@@ -153,18 +265,6 @@ config OC_ETM
buffer driver that will allow you to collect traces of the buffer driver that will allow you to collect traces of the
kernel code. kernel code.
config DEBUG_S3C_UART
depends on PLAT_SAMSUNG
int "S3C UART to use for low-level debug"
default "0"
help
Choice for UART for kernel low-level using S3C UARTS,
should be between zero and two. The port must have been
initialised by the boot-loader before use.
The uncompressor code port configuration is now handled
by CONFIG_S3C_LOWLEVEL_UART_PORT.
config ARM_KPROBES_TEST config ARM_KPROBES_TEST
tristate "Kprobes test module" tristate "Kprobes test module"
depends on KPROBES && MODULES depends on KPROBES && MODULES
......
...@@ -159,7 +159,7 @@ machine-$(CONFIG_ARCH_MMP) := mmp ...@@ -159,7 +159,7 @@ machine-$(CONFIG_ARCH_MMP) := mmp
machine-$(CONFIG_ARCH_MSM) := msm machine-$(CONFIG_ARCH_MSM) := msm
machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0 machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
machine-$(CONFIG_ARCH_IMX_V4_V5) := imx machine-$(CONFIG_ARCH_IMX_V4_V5) := imx
machine-$(CONFIG_ARCH_MX3) := imx machine-$(CONFIG_ARCH_IMX_V6_V7) := imx
machine-$(CONFIG_ARCH_MX5) := mx5 machine-$(CONFIG_ARCH_MX5) := mx5
machine-$(CONFIG_ARCH_MXS) := mxs machine-$(CONFIG_ARCH_MXS) := mxs
machine-$(CONFIG_ARCH_NETX) := netx machine-$(CONFIG_ARCH_NETX) := netx
......
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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
*/
/dts-v1/;
/include/ "imx6q.dtsi"
/ {
model = "Freescale i.MX6 Quad SABRE Automotive Board";
compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
chosen {
bootargs = "console=ttymxc0,115200 root=/dev/mmcblk3p3 rootwait";
};
memory {
reg = <0x10000000 0x80000000>;
};
soc {
aips-bus@02100000 { /* AIPS2 */
enet@02188000 {
phy-mode = "rgmii";
local-mac-address = [00 04 9F 01 1B 61];
status = "okay";
};
usdhc@02198000 { /* uSDHC3 */
cd-gpios = <&gpio5 11 0>; /* GPIO6_11 */
wp-gpios = <&gpio5 14 0>; /* GPIO6_14 */
status = "okay";
};
usdhc@0219c000 { /* uSDHC4 */
fsl,card-wired;
status = "okay";
};
uart3: uart@021f0000 { /* UART4 */
status = "okay";
};
};
};
leds {
compatible = "gpio-leds";
debug-led {
label = "Heartbeat";
gpios = <&gpio2 25 0>; /* GPIO3_25 */
linux,default-trigger = "heartbeat";
};
};
};
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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/ "skeleton.dtsi"
/ {
aliases {
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
serial3 = &uart3;
serial4 = &uart4;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = "arm,cortex-a9";
reg = <0>;
next-level-cache = <&L2>;
};
cpu@1 {
compatible = "arm,cortex-a9";
reg = <1>;
next-level-cache = <&L2>;
};
cpu@2 {
compatible = "arm,cortex-a9";
reg = <2>;
next-level-cache = <&L2>;
};
cpu@3 {
compatible = "arm,cortex-a9";
reg = <3>;
next-level-cache = <&L2>;
};
};
intc: interrupt-controller@00a01000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
#address-cells = <1>;
#size-cells = <1>;
interrupt-controller;
reg = <0x00a01000 0x1000>,
<0x00a00100 0x100>;
};
clocks {
#address-cells = <1>;
#size-cells = <0>;
ckil {
compatible = "fsl,imx-ckil", "fixed-clock";
clock-frequency = <32768>;
};
ckih1 {
compatible = "fsl,imx-ckih1", "fixed-clock";
clock-frequency = <0>;
};
osc {
compatible = "fsl,imx-osc", "fixed-clock";
clock-frequency = <24000000>;
};
};
soc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
interrupt-parent = <&intc>;
ranges;
timer@00a00600 {
compatible = "arm,smp-twd";
reg = <0x00a00600 0x100>;
interrupts = <1 13 0xf4>;
};
L2: l2-cache@00a02000 {
compatible = "arm,pl310-cache";
reg = <0x00a02000 0x1000>;
interrupts = <0 92 0x04>;
cache-unified;
cache-level = <2>;
};
aips-bus@02000000 { /* AIPS1 */
compatible = "fsl,aips-bus", "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x02000000 0x100000>;
ranges;
spba-bus@02000000 {
compatible = "fsl,spba-bus", "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x02000000 0x40000>;
ranges;
spdif@02004000 {
reg = <0x02004000 0x4000>;
interrupts = <0 52 0x04>;
};
ecspi@02008000 { /* eCSPI1 */
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
reg = <0x02008000 0x4000>;
interrupts = <0 31 0x04>;
status = "disabled";
};
ecspi@0200c000 { /* eCSPI2 */
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
reg = <0x0200c000 0x4000>;
interrupts = <0 32 0x04>;
status = "disabled";
};
ecspi@02010000 { /* eCSPI3 */
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
reg = <0x02010000 0x4000>;
interrupts = <0 33 0x04>;
status = "disabled";
};
ecspi@02014000 { /* eCSPI4 */
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
reg = <0x02014000 0x4000>;
interrupts = <0 34 0x04>;
status = "disabled";
};
ecspi@02018000 { /* eCSPI5 */
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
reg = <0x02018000 0x4000>;
interrupts = <0 35 0x04>;
status = "disabled";
};
uart0: uart@02020000 { /* UART1 */
compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x02020000 0x4000>;
interrupts = <0 26 0x04>;
status = "disabled";
};
esai@02024000 {
reg = <0x02024000 0x4000>;
interrupts = <0 51 0x04>;
};
ssi@02028000 { /* SSI1 */
reg = <0x02028000 0x4000>;
interrupts = <0 46 0x04>;
};
ssi@0202c000 { /* SSI2 */
reg = <0x0202c000 0x4000>;
interrupts = <0 47 0x04>;
};
ssi@02030000 { /* SSI3 */
reg = <0x02030000 0x4000>;
interrupts = <0 48 0x04>;
};
asrc@02034000 {
reg = <0x02034000 0x4000>;
interrupts = <0 50 0x04>;
};
spba@0203c000 {
reg = <0x0203c000 0x4000>;
};
};
vpu@02040000 {
reg = <0x02040000 0x3c000>;
interrupts = <0 3 0x04 0 12 0x04>;
};
aipstz@0207c000 { /* AIPSTZ1 */
reg = <0x0207c000 0x4000>;
};
pwm@02080000 { /* PWM1 */
reg = <0x02080000 0x4000>;
interrupts = <0 83 0x04>;
};
pwm@02084000 { /* PWM2 */
reg = <0x02084000 0x4000>;
interrupts = <0 84 0x04>;
};
pwm@02088000 { /* PWM3 */
reg = <0x02088000 0x4000>;
interrupts = <0 85 0x04>;
};
pwm@0208c000 { /* PWM4 */
reg = <0x0208c000 0x4000>;
interrupts = <0 86 0x04>;
};
flexcan@02090000 { /* CAN1 */
reg = <0x02090000 0x4000>;
interrupts = <0 110 0x04>;
};
flexcan@02094000 { /* CAN2 */
reg = <0x02094000 0x4000>;
interrupts = <0 111 0x04>;
};
gpt@02098000 {
compatible = "fsl,imx6q-gpt";
reg = <0x02098000 0x4000>;
interrupts = <0 55 0x04>;
};
gpio0: gpio@0209c000 { /* GPIO1 */
compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
reg = <0x0209c000 0x4000>;
interrupts = <0 66 0x04 0 67 0x04>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <1>;
};
gpio1: gpio@020a0000 { /* GPIO2 */
compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
reg = <0x020a0000 0x4000>;
interrupts = <0 68 0x04 0 69 0x04>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <1>;
};
gpio2: gpio@020a4000 { /* GPIO3 */
compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
reg = <0x020a4000 0x4000>;
interrupts = <0 70 0x04 0 71 0x04>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <1>;
};
gpio3: gpio@020a8000 { /* GPIO4 */
compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
reg = <0x020a8000 0x4000>;
interrupts = <0 72 0x04 0 73 0x04>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <1>;
};
gpio4: gpio@020ac000 { /* GPIO5 */
compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
reg = <0x020ac000 0x4000>;
interrupts = <0 74 0x04 0 75 0x04>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <1>;
};
gpio5: gpio@020b0000 { /* GPIO6 */
compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
reg = <0x020b0000 0x4000>;
interrupts = <0 76 0x04 0 77 0x04>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <1>;
};
gpio6: gpio@020b4000 { /* GPIO7 */
compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
reg = <0x020b4000 0x4000>;
interrupts = <0 78 0x04 0 79 0x04>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <1>;
};
kpp@020b8000 {
reg = <0x020b8000 0x4000>;
interrupts = <0 82 0x04>;
};
wdog@020bc000 { /* WDOG1 */
compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
reg = <0x020bc000 0x4000>;
interrupts = <0 80 0x04>;
status = "disabled";
};
wdog@020c0000 { /* WDOG2 */
compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
reg = <0x020c0000 0x4000>;
interrupts = <0 81 0x04>;
status = "disabled";
};
ccm@020c4000 {
compatible = "fsl,imx6q-ccm";
reg = <0x020c4000 0x4000>;
interrupts = <0 87 0x04 0 88 0x04>;
};
anatop@020c8000 {
compatible = "fsl,imx6q-anatop";
reg = <0x020c8000 0x1000>;
interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
};
usbphy@020c9000 { /* USBPHY1 */
reg = <0x020c9000 0x1000>;
interrupts = <0 44 0x04>;
};
usbphy@020ca000 { /* USBPHY2 */
reg = <0x020ca000 0x1000>;
interrupts = <0 45 0x04>;
};
snvs@020cc000 {
reg = <0x020cc000 0x4000>;
interrupts = <0 19 0x04 0 20 0x04>;
};
epit@020d0000 { /* EPIT1 */
reg = <0x020d0000 0x4000>;
interrupts = <0 56 0x04>;
};
epit@020d4000 { /* EPIT2 */
reg = <0x020d4000 0x4000>;
interrupts = <0 57 0x04>;
};
src@020d8000 {
compatible = "fsl,imx6q-src";
reg = <0x020d8000 0x4000>;
interrupts = <0 91 0x04 0 96 0x04>;
};
gpc@020dc000 {
compatible = "fsl,imx6q-gpc";
reg = <0x020dc000 0x4000>;
interrupts = <0 89 0x04 0 90 0x04>;
};
iomuxc@020e0000 {
reg = <0x020e0000 0x4000>;
};
dcic@020e4000 { /* DCIC1 */
reg = <0x020e4000 0x4000>;
interrupts = <0 124 0x04>;
};
dcic@020e8000 { /* DCIC2 */
reg = <0x020e8000 0x4000>;
interrupts = <0 125 0x04>;
};
sdma@020ec000 {
compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
reg = <0x020ec000 0x4000>;
interrupts = <0 2 0x04>;
};
};
aips-bus@02100000 { /* AIPS2 */
compatible = "fsl,aips-bus", "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x02100000 0x100000>;
ranges;
caam@02100000 {
reg = <0x02100000 0x40000>;
interrupts = <0 105 0x04 0 106 0x04>;
};
aipstz@0217c000 { /* AIPSTZ2 */
reg = <0x0217c000 0x4000>;
};
enet@02188000 {
compatible = "fsl,imx6q-fec";
reg = <0x02188000 0x4000>;
interrupts = <0 118 0x04 0 119 0x04>;
status = "disabled";
};
mlb@0218c000 {
reg = <0x0218c000 0x4000>;
interrupts = <0 53 0x04 0 117 0x04 0 126 0x04>;
};
usdhc@02190000 { /* uSDHC1 */
compatible = "fsl,imx6q-usdhc";
reg = <0x02190000 0x4000>;
interrupts = <0 22 0x04>;
status = "disabled";
};
usdhc@02194000 { /* uSDHC2 */
compatible = "fsl,imx6q-usdhc";
reg = <0x02194000 0x4000>;
interrupts = <0 23 0x04>;
status = "disabled";
};
usdhc@02198000 { /* uSDHC3 */
compatible = "fsl,imx6q-usdhc";
reg = <0x02198000 0x4000>;
interrupts = <0 24 0x04>;
status = "disabled";
};
usdhc@0219c000 { /* uSDHC4 */
compatible = "fsl,imx6q-usdhc";
reg = <0x0219c000 0x4000>;
interrupts = <0 25 0x04>;
status = "disabled";
};
i2c@021a0000 { /* I2C1 */
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-i2c", "fsl,imx1-i2c";
reg = <0x021a0000 0x4000>;
interrupts = <0 36 0x04>;
status = "disabled";
};
i2c@021a4000 { /* I2C2 */
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-i2c", "fsl,imx1-i2c";
reg = <0x021a4000 0x4000>;
interrupts = <0 37 0x04>;
status = "disabled";
};
i2c@021a8000 { /* I2C3 */
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-i2c", "fsl,imx1-i2c";
reg = <0x021a8000 0x4000>;
interrupts = <0 38 0x04>;
status = "disabled";
};
romcp@021ac000 {
reg = <0x021ac000 0x4000>;
};
mmdc@021b0000 { /* MMDC0 */
compatible = "fsl,imx6q-mmdc";
reg = <0x021b0000 0x4000>;
};
mmdc@021b4000 { /* MMDC1 */
reg = <0x021b4000 0x4000>;
};
weim@021b8000 {
reg = <0x021b8000 0x4000>;
interrupts = <0 14 0x04>;
};
ocotp@021bc000 {
reg = <0x021bc000 0x4000>;
};
ocotp@021c0000 {
reg = <0x021c0000 0x4000>;
interrupts = <0 21 0x04>;
};
tzasc@021d0000 { /* TZASC1 */
reg = <0x021d0000 0x4000>;
interrupts = <0 108 0x04>;
};
tzasc@021d4000 { /* TZASC2 */
reg = <0x021d4000 0x4000>;
interrupts = <0 109 0x04>;
};
audmux@021d8000 {
reg = <0x021d8000 0x4000>;
};
mipi@021dc000 { /* MIPI-CSI */
reg = <0x021dc000 0x4000>;
};
mipi@021e0000 { /* MIPI-DSI */
reg = <0x021e0000 0x4000>;
};
vdoa@021e4000 {
reg = <0x021e4000 0x4000>;
interrupts = <0 18 0x04>;
};
uart1: uart@021e8000 { /* UART2 */
compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021e8000 0x4000>;
interrupts = <0 27 0x04>;
status = "disabled";
};
uart2: uart@021ec000 { /* UART3 */
compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021ec000 0x4000>;
interrupts = <0 28 0x04>;
status = "disabled";
};
uart3: uart@021f0000 { /* UART4 */
compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021f0000 0x4000>;
interrupts = <0 29 0x04>;
status = "disabled";
};
uart4: uart@021f4000 { /* UART5 */
compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021f4000 0x4000>;
interrupts = <0 30 0x04>;
status = "disabled";
};
};
};
};
config IMX_HAVE_DMA_V1 config IMX_HAVE_DMA_V1
bool bool
config HAVE_IMX_GPC
bool
config HAVE_IMX_MMDC
bool
config HAVE_IMX_SRC
bool
# #
# ARCH_MX31 and ARCH_MX35 are left for compatibility # ARCH_MX31 and ARCH_MX35 are left for compatibility
# Some usages assume that having one of them implies not having (e.g.) ARCH_MX2. # Some usages assume that having one of them implies not having (e.g.) ARCH_MX2.
...@@ -64,6 +74,7 @@ config SOC_IMX31 ...@@ -64,6 +74,7 @@ config SOC_IMX31
select ARCH_MXC_AUDMUX_V2 select ARCH_MXC_AUDMUX_V2
select ARCH_MX31 select ARCH_MX31
select MXC_AVIC select MXC_AVIC
select SMP_ON_UP if SMP
config SOC_IMX35 config SOC_IMX35
bool bool
...@@ -73,6 +84,7 @@ config SOC_IMX35 ...@@ -73,6 +84,7 @@ config SOC_IMX35
select HAVE_EPIT select HAVE_EPIT
select ARCH_MX35 select ARCH_MX35
select MXC_AVIC select MXC_AVIC
select SMP_ON_UP if SMP
if ARCH_IMX_V4_V5 if ARCH_IMX_V4_V5
...@@ -341,7 +353,7 @@ config MACH_IMX27IPCAM ...@@ -341,7 +353,7 @@ config MACH_IMX27IPCAM
endif endif
if ARCH_MX3 if ARCH_IMX_V6_V7
comment "MX31 platforms:" comment "MX31 platforms:"
...@@ -591,4 +603,20 @@ config MACH_VPR200 ...@@ -591,4 +603,20 @@ config MACH_VPR200
Include support for VPR200 platform. This includes specific Include support for VPR200 platform. This includes specific
configurations for the board and its peripherals. configurations for the board and its peripherals.
comment "i.MX6 family:"
config SOC_IMX6Q
bool "i.MX6 Quad support"
select ARM_GIC
select CACHE_L2X0
select CPU_V7
select HAVE_ARM_SCU
select HAVE_IMX_GPC
select HAVE_IMX_MMDC
select HAVE_IMX_SRC
select USE_OF
help
This enables support for Freescale i.MX6 Quad processor.
endif endif
...@@ -60,3 +60,14 @@ obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o ...@@ -60,3 +60,14 @@ obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o
obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o
obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
obj-$(CONFIG_DEBUG_LL) += lluart.o
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
obj-$(CONFIG_HAVE_IMX_SRC) += src.o
obj-$(CONFIG_CPU_V7) += head-v7.o
AFLAGS_head-v7.o :=-Wa,-march=armv7-a
obj-$(CONFIG_SMP) += platsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o pm-imx6q.o
...@@ -17,3 +17,7 @@ initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000 ...@@ -17,3 +17,7 @@ initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000
zreladdr-$(CONFIG_ARCH_MX3) := 0x80008000 zreladdr-$(CONFIG_ARCH_MX3) := 0x80008000
params_phys-$(CONFIG_ARCH_MX3) := 0x80000100 params_phys-$(CONFIG_ARCH_MX3) := 0x80000100
initrd_phys-$(CONFIG_ARCH_MX3) := 0x80800000 initrd_phys-$(CONFIG_ARCH_MX3) := 0x80800000
zreladdr-$(CONFIG_SOC_IMX6Q) += 0x10008000
params_phys-$(CONFIG_SOC_IMX6Q) := 0x10000100
initrd_phys-$(CONFIG_SOC_IMX6Q) := 0x10800000
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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/init.h>
#include <linux/types.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <asm/div64.h>
#include <asm/mach/map.h>
#include <mach/clock.h>
#include <mach/common.h>
#include <mach/hardware.h>
#define PLL_BASE IMX_IO_ADDRESS(MX6Q_ANATOP_BASE_ADDR)
#define PLL1_SYS (PLL_BASE + 0x000)
#define PLL2_BUS (PLL_BASE + 0x030)
#define PLL3_USB_OTG (PLL_BASE + 0x010)
#define PLL4_AUDIO (PLL_BASE + 0x070)
#define PLL5_VIDEO (PLL_BASE + 0x0a0)
#define PLL6_MLB (PLL_BASE + 0x0d0)
#define PLL7_USB_HOST (PLL_BASE + 0x020)
#define PLL8_ENET (PLL_BASE + 0x0e0)
#define PFD_480 (PLL_BASE + 0x0f0)
#define PFD_528 (PLL_BASE + 0x100)
#define PLL_NUM_OFFSET 0x010
#define PLL_DENOM_OFFSET 0x020
#define PFD0 7
#define PFD1 15
#define PFD2 23
#define PFD3 31
#define PFD_FRAC_MASK 0x3f
#define BM_PLL_BYPASS (0x1 << 16)
#define BM_PLL_ENABLE (0x1 << 13)
#define BM_PLL_POWER_DOWN (0x1 << 12)
#define BM_PLL_LOCK (0x1 << 31)
#define BP_PLL_SYS_DIV_SELECT 0
#define BM_PLL_SYS_DIV_SELECT (0x7f << 0)
#define BP_PLL_BUS_DIV_SELECT 0
#define BM_PLL_BUS_DIV_SELECT (0x1 << 0)
#define BP_PLL_USB_DIV_SELECT 0
#define BM_PLL_USB_DIV_SELECT (0x3 << 0)
#define BP_PLL_AV_DIV_SELECT 0
#define BM_PLL_AV_DIV_SELECT (0x7f << 0)
#define BP_PLL_ENET_DIV_SELECT 0
#define BM_PLL_ENET_DIV_SELECT (0x3 << 0)
#define BM_PLL_ENET_EN_PCIE (0x1 << 19)
#define BM_PLL_ENET_EN_SATA (0x1 << 20)
#define CCM_BASE IMX_IO_ADDRESS(MX6Q_CCM_BASE_ADDR)
#define CCR (CCM_BASE + 0x00)
#define CCDR (CCM_BASE + 0x04)
#define CSR (CCM_BASE + 0x08)
#define CCSR (CCM_BASE + 0x0c)
#define CACRR (CCM_BASE + 0x10)
#define CBCDR (CCM_BASE + 0x14)
#define CBCMR (CCM_BASE + 0x18)
#define CSCMR1 (CCM_BASE + 0x1c)
#define CSCMR2 (CCM_BASE + 0x20)
#define CSCDR1 (CCM_BASE + 0x24)
#define CS1CDR (CCM_BASE + 0x28)
#define CS2CDR (CCM_BASE + 0x2c)
#define CDCDR (CCM_BASE + 0x30)
#define CHSCCDR (CCM_BASE + 0x34)
#define CSCDR2 (CCM_BASE + 0x38)
#define CSCDR3 (CCM_BASE + 0x3c)
#define CSCDR4 (CCM_BASE + 0x40)
#define CWDR (CCM_BASE + 0x44)
#define CDHIPR (CCM_BASE + 0x48)
#define CDCR (CCM_BASE + 0x4c)
#define CTOR (CCM_BASE + 0x50)
#define CLPCR (CCM_BASE + 0x54)
#define CISR (CCM_BASE + 0x58)
#define CIMR (CCM_BASE + 0x5c)
#define CCOSR (CCM_BASE + 0x60)
#define CGPR (CCM_BASE + 0x64)
#define CCGR0 (CCM_BASE + 0x68)
#define CCGR1 (CCM_BASE + 0x6c)
#define CCGR2 (CCM_BASE + 0x70)
#define CCGR3 (CCM_BASE + 0x74)
#define CCGR4 (CCM_BASE + 0x78)
#define CCGR5 (CCM_BASE + 0x7c)
#define CCGR6 (CCM_BASE + 0x80)
#define CCGR7 (CCM_BASE + 0x84)
#define CMEOR (CCM_BASE + 0x88)
#define CG0 0
#define CG1 2
#define CG2 4
#define CG3 6
#define CG4 8
#define CG5 10
#define CG6 12
#define CG7 14
#define CG8 16
#define CG9 18
#define CG10 20
#define CG11 22
#define CG12 24
#define CG13 26
#define CG14 28
#define CG15 30
#define BM_CCSR_PLL1_SW_SEL (0x1 << 2)
#define BM_CCSR_STEP_SEL (0x1 << 8)
#define BP_CACRR_ARM_PODF 0
#define BM_CACRR_ARM_PODF (0x7 << 0)
#define BP_CBCDR_PERIPH2_CLK2_PODF 0
#define BM_CBCDR_PERIPH2_CLK2_PODF (0x7 << 0)
#define BP_CBCDR_MMDC_CH1_AXI_PODF 3
#define BM_CBCDR_MMDC_CH1_AXI_PODF (0x7 << 3)
#define BP_CBCDR_AXI_SEL 6
#define BM_CBCDR_AXI_SEL (0x3 << 6)
#define BP_CBCDR_IPG_PODF 8
#define BM_CBCDR_IPG_PODF (0x3 << 8)
#define BP_CBCDR_AHB_PODF 10
#define BM_CBCDR_AHB_PODF (0x7 << 10)
#define BP_CBCDR_AXI_PODF 16
#define BM_CBCDR_AXI_PODF (0x7 << 16)
#define BP_CBCDR_MMDC_CH0_AXI_PODF 19
#define BM_CBCDR_MMDC_CH0_AXI_PODF (0x7 << 19)
#define BP_CBCDR_PERIPH_CLK_SEL 25
#define BM_CBCDR_PERIPH_CLK_SEL (0x1 << 25)
#define BP_CBCDR_PERIPH2_CLK_SEL 26
#define BM_CBCDR_PERIPH2_CLK_SEL (0x1 << 26)
#define BP_CBCDR_PERIPH_CLK2_PODF 27
#define BM_CBCDR_PERIPH_CLK2_PODF (0x7 << 27)
#define BP_CBCMR_GPU2D_AXI_SEL 0
#define BM_CBCMR_GPU2D_AXI_SEL (0x1 << 0)
#define BP_CBCMR_GPU3D_AXI_SEL 1
#define BM_CBCMR_GPU3D_AXI_SEL (0x1 << 1)
#define BP_CBCMR_GPU3D_CORE_SEL 4
#define BM_CBCMR_GPU3D_CORE_SEL (0x3 << 4)
#define BP_CBCMR_GPU3D_SHADER_SEL 8
#define BM_CBCMR_GPU3D_SHADER_SEL (0x3 << 8)
#define BP_CBCMR_PCIE_AXI_SEL 10
#define BM_CBCMR_PCIE_AXI_SEL (0x1 << 10)
#define BP_CBCMR_VDO_AXI_SEL 11
#define BM_CBCMR_VDO_AXI_SEL (0x1 << 11)
#define BP_CBCMR_PERIPH_CLK2_SEL 12
#define BM_CBCMR_PERIPH_CLK2_SEL (0x3 << 12)
#define BP_CBCMR_VPU_AXI_SEL 14
#define BM_CBCMR_VPU_AXI_SEL (0x3 << 14)
#define BP_CBCMR_GPU2D_CORE_SEL 16
#define BM_CBCMR_GPU2D_CORE_SEL (0x3 << 16)
#define BP_CBCMR_PRE_PERIPH_CLK_SEL 18
#define BM_CBCMR_PRE_PERIPH_CLK_SEL (0x3 << 18)
#define BP_CBCMR_PERIPH2_CLK2_SEL 20
#define BM_CBCMR_PERIPH2_CLK2_SEL (0x1 << 20)
#define BP_CBCMR_PRE_PERIPH2_CLK_SEL 21
#define BM_CBCMR_PRE_PERIPH2_CLK_SEL (0x3 << 21)
#define BP_CBCMR_GPU2D_CORE_PODF 23
#define BM_CBCMR_GPU2D_CORE_PODF (0x7 << 23)
#define BP_CBCMR_GPU3D_CORE_PODF 26
#define BM_CBCMR_GPU3D_CORE_PODF (0x7 << 26)
#define BP_CBCMR_GPU3D_SHADER_PODF 29
#define BM_CBCMR_GPU3D_SHADER_PODF (0x7 << 29)
#define BP_CSCMR1_PERCLK_PODF 0
#define BM_CSCMR1_PERCLK_PODF (0x3f << 0)
#define BP_CSCMR1_SSI1_SEL 10
#define BM_CSCMR1_SSI1_SEL (0x3 << 10)
#define BP_CSCMR1_SSI2_SEL 12
#define BM_CSCMR1_SSI2_SEL (0x3 << 12)
#define BP_CSCMR1_SSI3_SEL 14
#define BM_CSCMR1_SSI3_SEL (0x3 << 14)
#define BP_CSCMR1_USDHC1_SEL 16
#define BM_CSCMR1_USDHC1_SEL (0x1 << 16)
#define BP_CSCMR1_USDHC2_SEL 17
#define BM_CSCMR1_USDHC2_SEL (0x1 << 17)
#define BP_CSCMR1_USDHC3_SEL 18
#define BM_CSCMR1_USDHC3_SEL (0x1 << 18)
#define BP_CSCMR1_USDHC4_SEL 19
#define BM_CSCMR1_USDHC4_SEL (0x1 << 19)
#define BP_CSCMR1_EMI_PODF 20
#define BM_CSCMR1_EMI_PODF (0x7 << 20)
#define BP_CSCMR1_EMI_SLOW_PODF 23
#define BM_CSCMR1_EMI_SLOW_PODF (0x7 << 23)
#define BP_CSCMR1_EMI_SEL 27
#define BM_CSCMR1_EMI_SEL (0x3 << 27)
#define BP_CSCMR1_EMI_SLOW_SEL 29
#define BM_CSCMR1_EMI_SLOW_SEL (0x3 << 29)
#define BP_CSCMR2_CAN_PODF 2
#define BM_CSCMR2_CAN_PODF (0x3f << 2)
#define BM_CSCMR2_LDB_DI0_IPU_DIV (0x1 << 10)
#define BM_CSCMR2_LDB_DI1_IPU_DIV (0x1 << 11)
#define BP_CSCMR2_ESAI_SEL 19
#define BM_CSCMR2_ESAI_SEL (0x3 << 19)
#define BP_CSCDR1_UART_PODF 0
#define BM_CSCDR1_UART_PODF (0x3f << 0)
#define BP_CSCDR1_USDHC1_PODF 11
#define BM_CSCDR1_USDHC1_PODF (0x7 << 11)
#define BP_CSCDR1_USDHC2_PODF 16
#define BM_CSCDR1_USDHC2_PODF (0x7 << 16)
#define BP_CSCDR1_USDHC3_PODF 19
#define BM_CSCDR1_USDHC3_PODF (0x7 << 19)
#define BP_CSCDR1_USDHC4_PODF 22
#define BM_CSCDR1_USDHC4_PODF (0x7 << 22)
#define BP_CSCDR1_VPU_AXI_PODF 25
#define BM_CSCDR1_VPU_AXI_PODF (0x7 << 25)
#define BP_CS1CDR_SSI1_PODF 0
#define BM_CS1CDR_SSI1_PODF (0x3f << 0)
#define BP_CS1CDR_SSI1_PRED 6
#define BM_CS1CDR_SSI1_PRED (0x7 << 6)
#define BP_CS1CDR_ESAI_PRED 9
#define BM_CS1CDR_ESAI_PRED (0x7 << 9)
#define BP_CS1CDR_SSI3_PODF 16
#define BM_CS1CDR_SSI3_PODF (0x3f << 16)
#define BP_CS1CDR_SSI3_PRED 22
#define BM_CS1CDR_SSI3_PRED (0x7 << 22)
#define BP_CS1CDR_ESAI_PODF 25
#define BM_CS1CDR_ESAI_PODF (0x7 << 25)
#define BP_CS2CDR_SSI2_PODF 0
#define BM_CS2CDR_SSI2_PODF (0x3f << 0)
#define BP_CS2CDR_SSI2_PRED 6
#define BM_CS2CDR_SSI2_PRED (0x7 << 6)
#define BP_CS2CDR_LDB_DI0_SEL 9
#define BM_CS2CDR_LDB_DI0_SEL (0x7 << 9)
#define BP_CS2CDR_LDB_DI1_SEL 12
#define BM_CS2CDR_LDB_DI1_SEL (0x7 << 12)
#define BP_CS2CDR_ENFC_SEL 16
#define BM_CS2CDR_ENFC_SEL (0x3 << 16)
#define BP_CS2CDR_ENFC_PRED 18
#define BM_CS2CDR_ENFC_PRED (0x7 << 18)
#define BP_CS2CDR_ENFC_PODF 21
#define BM_CS2CDR_ENFC_PODF (0x3f << 21)
#define BP_CDCDR_ASRC_SERIAL_SEL 7
#define BM_CDCDR_ASRC_SERIAL_SEL (0x3 << 7)
#define BP_CDCDR_ASRC_SERIAL_PODF 9
#define BM_CDCDR_ASRC_SERIAL_PODF (0x7 << 9)
#define BP_CDCDR_ASRC_SERIAL_PRED 12
#define BM_CDCDR_ASRC_SERIAL_PRED (0x7 << 12)
#define BP_CDCDR_SPDIF_SEL 20
#define BM_CDCDR_SPDIF_SEL (0x3 << 20)
#define BP_CDCDR_SPDIF_PODF 22
#define BM_CDCDR_SPDIF_PODF (0x7 << 22)
#define BP_CDCDR_SPDIF_PRED 25
#define BM_CDCDR_SPDIF_PRED (0x7 << 25)
#define BP_CDCDR_HSI_TX_PODF 29
#define BM_CDCDR_HSI_TX_PODF (0x7 << 29)
#define BP_CDCDR_HSI_TX_SEL 28
#define BM_CDCDR_HSI_TX_SEL (0x1 << 28)
#define BP_CHSCCDR_IPU1_DI0_SEL 0
#define BM_CHSCCDR_IPU1_DI0_SEL (0x7 << 0)
#define BP_CHSCCDR_IPU1_DI0_PRE_PODF 3
#define BM_CHSCCDR_IPU1_DI0_PRE_PODF (0x7 << 3)
#define BP_CHSCCDR_IPU1_DI0_PRE_SEL 6
#define BM_CHSCCDR_IPU1_DI0_PRE_SEL (0x7 << 6)
#define BP_CHSCCDR_IPU1_DI1_SEL 9
#define BM_CHSCCDR_IPU1_DI1_SEL (0x7 << 9)
#define BP_CHSCCDR_IPU1_DI1_PRE_PODF 12
#define BM_CHSCCDR_IPU1_DI1_PRE_PODF (0x7 << 12)
#define BP_CHSCCDR_IPU1_DI1_PRE_SEL 15
#define BM_CHSCCDR_IPU1_DI1_PRE_SEL (0x7 << 15)
#define BP_CSCDR2_IPU2_DI0_SEL 0
#define BM_CSCDR2_IPU2_DI0_SEL (0x7)
#define BP_CSCDR2_IPU2_DI0_PRE_PODF 3
#define BM_CSCDR2_IPU2_DI0_PRE_PODF (0x7 << 3)
#define BP_CSCDR2_IPU2_DI0_PRE_SEL 6
#define BM_CSCDR2_IPU2_DI0_PRE_SEL (0x7 << 6)
#define BP_CSCDR2_IPU2_DI1_SEL 9
#define BM_CSCDR2_IPU2_DI1_SEL (0x7 << 9)
#define BP_CSCDR2_IPU2_DI1_PRE_PODF 12
#define BM_CSCDR2_IPU2_DI1_PRE_PODF (0x7 << 12)
#define BP_CSCDR2_IPU2_DI1_PRE_SEL 15
#define BM_CSCDR2_IPU2_DI1_PRE_SEL (0x7 << 15)
#define BP_CSCDR2_ECSPI_CLK_PODF 19
#define BM_CSCDR2_ECSPI_CLK_PODF (0x3f << 19)
#define BP_CSCDR3_IPU1_HSP_SEL 9
#define BM_CSCDR3_IPU1_HSP_SEL (0x3 << 9)
#define BP_CSCDR3_IPU1_HSP_PODF 11
#define BM_CSCDR3_IPU1_HSP_PODF (0x7 << 11)
#define BP_CSCDR3_IPU2_HSP_SEL 14
#define BM_CSCDR3_IPU2_HSP_SEL (0x3 << 14)
#define BP_CSCDR3_IPU2_HSP_PODF 16
#define BM_CSCDR3_IPU2_HSP_PODF (0x7 << 16)
#define BM_CDHIPR_AXI_PODF_BUSY (0x1 << 0)
#define BM_CDHIPR_AHB_PODF_BUSY (0x1 << 1)
#define BM_CDHIPR_MMDC_CH1_PODF_BUSY (0x1 << 2)
#define BM_CDHIPR_PERIPH2_SEL_BUSY (0x1 << 3)
#define BM_CDHIPR_MMDC_CH0_PODF_BUSY (0x1 << 4)
#define BM_CDHIPR_PERIPH_SEL_BUSY (0x1 << 5)
#define BM_CDHIPR_ARM_PODF_BUSY (0x1 << 16)
#define BP_CLPCR_LPM 0
#define BM_CLPCR_LPM (0x3 << 0)
#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
#define BM_CLPCR_SBYOS (0x1 << 6)
#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
#define BM_CLPCR_VSTBY (0x1 << 8)
#define BP_CLPCR_STBY_COUNT 9
#define BM_CLPCR_STBY_COUNT (0x3 << 9)
#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
#define FREQ_480M 480000000
#define FREQ_528M 528000000
#define FREQ_594M 594000000
#define FREQ_650M 650000000
#define FREQ_1300M 1300000000
static struct clk pll1_sys;
static struct clk pll2_bus;
static struct clk pll3_usb_otg;
static struct clk pll4_audio;
static struct clk pll5_video;
static struct clk pll6_mlb;
static struct clk pll7_usb_host;
static struct clk pll8_enet;
static struct clk apbh_dma_clk;
static struct clk arm_clk;
static struct clk ipg_clk;
static struct clk ahb_clk;
static struct clk axi_clk;
static struct clk mmdc_ch0_axi_clk;
static struct clk mmdc_ch1_axi_clk;
static struct clk periph_clk;
static struct clk periph_pre_clk;
static struct clk periph_clk2_clk;
static struct clk periph2_clk;
static struct clk periph2_pre_clk;
static struct clk periph2_clk2_clk;
static struct clk gpu2d_core_clk;
static struct clk gpu3d_core_clk;
static struct clk gpu3d_shader_clk;
static struct clk ipg_perclk;
static struct clk emi_clk;
static struct clk emi_slow_clk;
static struct clk can1_clk;
static struct clk uart_clk;
static struct clk usdhc1_clk;
static struct clk usdhc2_clk;
static struct clk usdhc3_clk;
static struct clk usdhc4_clk;
static struct clk vpu_clk;
static struct clk hsi_tx_clk;
static struct clk ipu1_di0_pre_clk;
static struct clk ipu1_di1_pre_clk;
static struct clk ipu2_di0_pre_clk;
static struct clk ipu2_di1_pre_clk;
static struct clk ipu1_clk;
static struct clk ipu2_clk;
static struct clk ssi1_clk;
static struct clk ssi3_clk;
static struct clk esai_clk;
static struct clk ssi2_clk;
static struct clk spdif_clk;
static struct clk asrc_serial_clk;
static struct clk gpu2d_axi_clk;
static struct clk gpu3d_axi_clk;
static struct clk pcie_clk;
static struct clk vdo_axi_clk;
static struct clk ldb_di0_clk;
static struct clk ldb_di1_clk;
static struct clk ipu1_di0_clk;
static struct clk ipu1_di1_clk;
static struct clk ipu2_di0_clk;
static struct clk ipu2_di1_clk;
static struct clk enfc_clk;
static struct clk dummy_clk = {};
static unsigned long external_high_reference;
static unsigned long external_low_reference;
static unsigned long oscillator_reference;
static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
{
return oscillator_reference;
}
static unsigned long get_high_reference_clock_rate(struct clk *clk)
{
return external_high_reference;
}
static unsigned long get_low_reference_clock_rate(struct clk *clk)
{
return external_low_reference;
}
static struct clk ckil_clk = {
.get_rate = get_low_reference_clock_rate,
};
static struct clk ckih_clk = {
.get_rate = get_high_reference_clock_rate,
};
static struct clk osc_clk = {
.get_rate = get_oscillator_reference_clock_rate,
};
static inline void __iomem *pll_get_reg_addr(struct clk *pll)
{
if (pll == &pll1_sys)
return PLL1_SYS;
else if (pll == &pll2_bus)
return PLL2_BUS;
else if (pll == &pll3_usb_otg)
return PLL3_USB_OTG;
else if (pll == &pll4_audio)
return PLL4_AUDIO;
else if (pll == &pll5_video)
return PLL5_VIDEO;
else if (pll == &pll6_mlb)
return PLL6_MLB;
else if (pll == &pll7_usb_host)
return PLL7_USB_HOST;
else if (pll == &pll8_enet)
return PLL8_ENET;
else
BUG();
return NULL;
}
static int pll_enable(struct clk *clk)
{
int timeout = 0x100000;
void __iomem *reg;
u32 val;
reg = pll_get_reg_addr(clk);
val = readl_relaxed(reg);
val &= ~BM_PLL_BYPASS;
val &= ~BM_PLL_POWER_DOWN;
/* 480MHz PLLs have the opposite definition for power bit */
if (clk == &pll3_usb_otg || clk == &pll7_usb_host)
val |= BM_PLL_POWER_DOWN;
writel_relaxed(val, reg);
/* Wait for PLL to lock */
while (!(readl_relaxed(reg) & BM_PLL_LOCK) && --timeout)
cpu_relax();
if (unlikely(!timeout))
return -EBUSY;
/* Enable the PLL output now */
val = readl_relaxed(reg);
val |= BM_PLL_ENABLE;
writel_relaxed(val, reg);
return 0;
}
static void pll_disable(struct clk *clk)
{
void __iomem *reg;
u32 val;
reg = pll_get_reg_addr(clk);
val = readl_relaxed(reg);
val &= ~BM_PLL_ENABLE;
val |= BM_PLL_BYPASS;
val |= BM_PLL_POWER_DOWN;
if (clk == &pll3_usb_otg || clk == &pll7_usb_host)
val &= ~BM_PLL_POWER_DOWN;
writel_relaxed(val, reg);
}
static unsigned long pll1_sys_get_rate(struct clk *clk)
{
u32 div = (readl_relaxed(PLL1_SYS) & BM_PLL_SYS_DIV_SELECT) >>
BP_PLL_SYS_DIV_SELECT;
return clk_get_rate(clk->parent) * div / 2;
}
static int pll1_sys_set_rate(struct clk *clk, unsigned long rate)
{
u32 val, div;
if (rate < FREQ_650M || rate > FREQ_1300M)
return -EINVAL;
div = rate * 2 / clk_get_rate(clk->parent);
val = readl_relaxed(PLL1_SYS);
val &= ~BM_PLL_SYS_DIV_SELECT;
val |= div << BP_PLL_SYS_DIV_SELECT;
writel_relaxed(val, PLL1_SYS);
return 0;
}
static unsigned long pll8_enet_get_rate(struct clk *clk)
{
u32 div = (readl_relaxed(PLL8_ENET) & BM_PLL_ENET_DIV_SELECT) >>
BP_PLL_ENET_DIV_SELECT;
switch (div) {
case 0:
return 25000000;
case 1:
return 50000000;
case 2:
return 100000000;
case 3:
return 125000000;
}
return 0;
}
static int pll8_enet_set_rate(struct clk *clk, unsigned long rate)
{
u32 val, div;
switch (rate) {
case 25000000:
div = 0;
break;
case 50000000:
div = 1;
break;
case 100000000:
div = 2;
break;
case 125000000:
div = 3;
break;
default:
return -EINVAL;
}
val = readl_relaxed(PLL8_ENET);
val &= ~BM_PLL_ENET_DIV_SELECT;
val |= div << BP_PLL_ENET_DIV_SELECT;
writel_relaxed(val, PLL8_ENET);
return 0;
}
static unsigned long pll_av_get_rate(struct clk *clk)
{
void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO;
unsigned long parent_rate = clk_get_rate(clk->parent);
u32 mfn = readl_relaxed(reg + PLL_NUM_OFFSET);
u32 mfd = readl_relaxed(reg + PLL_DENOM_OFFSET);
u32 div = (readl_relaxed(reg) & BM_PLL_AV_DIV_SELECT) >>
BP_PLL_AV_DIV_SELECT;
return (parent_rate * div) + ((parent_rate / mfd) * mfn);
}
static int pll_av_set_rate(struct clk *clk, unsigned long rate)
{
void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO;
unsigned int parent_rate = clk_get_rate(clk->parent);
u32 val, div;
u32 mfn, mfd = 1000000;
s64 temp64;
if (rate < FREQ_650M || rate > FREQ_1300M)
return -EINVAL;
div = rate / parent_rate;
temp64 = (u64) (rate - div * parent_rate);
temp64 *= mfd;
do_div(temp64, parent_rate);
mfn = temp64;
val = readl_relaxed(reg);
val &= ~BM_PLL_AV_DIV_SELECT;
val |= div << BP_PLL_AV_DIV_SELECT;
writel_relaxed(val, reg);
writel_relaxed(mfn, reg + PLL_NUM_OFFSET);
writel_relaxed(mfd, reg + PLL_DENOM_OFFSET);
return 0;
}
static void __iomem *pll_get_div_reg_bit(struct clk *clk, u32 *bp, u32 *bm)
{
void __iomem *reg;
if (clk == &pll2_bus) {
reg = PLL2_BUS;
*bp = BP_PLL_BUS_DIV_SELECT;
*bm = BM_PLL_BUS_DIV_SELECT;
} else if (clk == &pll3_usb_otg) {
reg = PLL3_USB_OTG;
*bp = BP_PLL_USB_DIV_SELECT;
*bm = BM_PLL_USB_DIV_SELECT;
} else if (clk == &pll7_usb_host) {
reg = PLL7_USB_HOST;
*bp = BP_PLL_USB_DIV_SELECT;
*bm = BM_PLL_USB_DIV_SELECT;
} else {
BUG();
}
return reg;
}
static unsigned long pll_get_rate(struct clk *clk)
{
void __iomem *reg;
u32 div, bp, bm;
reg = pll_get_div_reg_bit(clk, &bp, &bm);
div = (readl_relaxed(reg) & bm) >> bp;
return (div == 1) ? clk_get_rate(clk->parent) * 22 :
clk_get_rate(clk->parent) * 20;
}
static int pll_set_rate(struct clk *clk, unsigned long rate)
{
void __iomem *reg;
u32 val, div, bp, bm;
if (rate == FREQ_528M)
div = 1;
else if (rate == FREQ_480M)
div = 0;
else
return -EINVAL;
reg = pll_get_div_reg_bit(clk, &bp, &bm);
val = readl_relaxed(reg);
val &= ~bm;
val |= div << bp;
writel_relaxed(val, reg);
return 0;
}
#define pll2_bus_get_rate pll_get_rate
#define pll2_bus_set_rate pll_set_rate
#define pll3_usb_otg_get_rate pll_get_rate
#define pll3_usb_otg_set_rate pll_set_rate
#define pll7_usb_host_get_rate pll_get_rate
#define pll7_usb_host_set_rate pll_set_rate
#define pll4_audio_get_rate pll_av_get_rate
#define pll4_audio_set_rate pll_av_set_rate
#define pll5_video_get_rate pll_av_get_rate
#define pll5_video_set_rate pll_av_set_rate
#define pll6_mlb_get_rate NULL
#define pll6_mlb_set_rate NULL
#define DEF_PLL(name) \
static struct clk name = { \
.enable = pll_enable, \
.disable = pll_disable, \
.get_rate = name##_get_rate, \
.set_rate = name##_set_rate, \
.parent = &osc_clk, \
}
DEF_PLL(pll1_sys);
DEF_PLL(pll2_bus);
DEF_PLL(pll3_usb_otg);
DEF_PLL(pll4_audio);
DEF_PLL(pll5_video);
DEF_PLL(pll6_mlb);
DEF_PLL(pll7_usb_host);
DEF_PLL(pll8_enet);
static unsigned long pfd_get_rate(struct clk *clk)
{
u64 tmp = (u64) clk_get_rate(clk->parent) * 18;
u32 frac, bp_frac;
if (apbh_dma_clk.usecount == 0)
apbh_dma_clk.enable(&apbh_dma_clk);
bp_frac = clk->enable_shift - 7;
frac = readl_relaxed(clk->enable_reg) >> bp_frac & PFD_FRAC_MASK;
do_div(tmp, frac);
return tmp;
}
static int pfd_set_rate(struct clk *clk, unsigned long rate)
{
u32 val, frac, bp_frac;
u64 tmp = (u64) clk_get_rate(clk->parent) * 18;
if (apbh_dma_clk.usecount == 0)
apbh_dma_clk.enable(&apbh_dma_clk);
/*
* Round up the divider so that we don't set a rate
* higher than what is requested
*/
tmp += rate / 2;
do_div(tmp, rate);
frac = tmp;
frac = (frac < 12) ? 12 : frac;
frac = (frac > 35) ? 35 : frac;
/*
* The frac field always starts from 7 bits lower
* position of enable bit
*/
bp_frac = clk->enable_shift - 7;
val = readl_relaxed(clk->enable_reg);
val &= ~(PFD_FRAC_MASK << bp_frac);
val |= frac << bp_frac;
writel_relaxed(val, clk->enable_reg);
tmp = (u64) clk_get_rate(clk->parent) * 18;
do_div(tmp, frac);
if (apbh_dma_clk.usecount == 0)
apbh_dma_clk.disable(&apbh_dma_clk);
return 0;
}
static unsigned long pfd_round_rate(struct clk *clk, unsigned long rate)
{
u32 frac;
u64 tmp;
tmp = (u64) clk_get_rate(clk->parent) * 18;
tmp += rate / 2;
do_div(tmp, rate);
frac = tmp;
frac = (frac < 12) ? 12 : frac;
frac = (frac > 35) ? 35 : frac;
tmp = (u64) clk_get_rate(clk->parent) * 18;
do_div(tmp, frac);
return tmp;
}
static int pfd_enable(struct clk *clk)
{
u32 val;
if (apbh_dma_clk.usecount == 0)
apbh_dma_clk.enable(&apbh_dma_clk);
val = readl_relaxed(clk->enable_reg);
val &= ~(1 << clk->enable_shift);
writel_relaxed(val, clk->enable_reg);
if (apbh_dma_clk.usecount == 0)
apbh_dma_clk.disable(&apbh_dma_clk);
return 0;
}
static void pfd_disable(struct clk *clk)
{
u32 val;
if (apbh_dma_clk.usecount == 0)
apbh_dma_clk.enable(&apbh_dma_clk);
val = readl_relaxed(clk->enable_reg);
val |= 1 << clk->enable_shift;
writel_relaxed(val, clk->enable_reg);
if (apbh_dma_clk.usecount == 0)
apbh_dma_clk.disable(&apbh_dma_clk);
}
#define DEF_PFD(name, er, es, p) \
static struct clk name = { \
.enable_reg = er, \
.enable_shift = es, \
.enable = pfd_enable, \
.disable = pfd_disable, \
.get_rate = pfd_get_rate, \
.set_rate = pfd_set_rate, \
.round_rate = pfd_round_rate, \
.parent = p, \
}
DEF_PFD(pll2_pfd_352m, PFD_528, PFD0, &pll2_bus);
DEF_PFD(pll2_pfd_594m, PFD_528, PFD1, &pll2_bus);
DEF_PFD(pll2_pfd_400m, PFD_528, PFD2, &pll2_bus);
DEF_PFD(pll3_pfd_720m, PFD_480, PFD0, &pll3_usb_otg);
DEF_PFD(pll3_pfd_540m, PFD_480, PFD1, &pll3_usb_otg);
DEF_PFD(pll3_pfd_508m, PFD_480, PFD2, &pll3_usb_otg);
DEF_PFD(pll3_pfd_454m, PFD_480, PFD3, &pll3_usb_otg);
static unsigned long pll2_200m_get_rate(struct clk *clk)
{
return clk_get_rate(clk->parent) / 2;
}
static struct clk pll2_200m = {
.parent = &pll2_pfd_400m,
.get_rate = pll2_200m_get_rate,
};
static unsigned long pll3_120m_get_rate(struct clk *clk)
{
return clk_get_rate(clk->parent) / 4;
}
static struct clk pll3_120m = {
.parent = &pll3_usb_otg,
.get_rate = pll3_120m_get_rate,
};
static unsigned long pll3_80m_get_rate(struct clk *clk)
{
return clk_get_rate(clk->parent) / 6;
}
static struct clk pll3_80m = {
.parent = &pll3_usb_otg,
.get_rate = pll3_80m_get_rate,
};
static unsigned long pll3_60m_get_rate(struct clk *clk)
{
return clk_get_rate(clk->parent) / 8;
}
static struct clk pll3_60m = {
.parent = &pll3_usb_otg,
.get_rate = pll3_60m_get_rate,
};
static int pll1_sw_clk_set_parent(struct clk *clk, struct clk *parent)
{
u32 val = readl_relaxed(CCSR);
if (parent == &pll1_sys) {
val &= ~BM_CCSR_PLL1_SW_SEL;
val &= ~BM_CCSR_STEP_SEL;
} else if (parent == &osc_clk) {
val |= BM_CCSR_PLL1_SW_SEL;
val &= ~BM_CCSR_STEP_SEL;
} else if (parent == &pll2_pfd_400m) {
val |= BM_CCSR_PLL1_SW_SEL;
val |= BM_CCSR_STEP_SEL;
} else {
return -EINVAL;
}
writel_relaxed(val, CCSR);
return 0;
}
static struct clk pll1_sw_clk = {
.parent = &pll1_sys,
.set_parent = pll1_sw_clk_set_parent,
};
static void calc_pred_podf_dividers(u32 div, u32 *pred, u32 *podf)
{
u32 min_pred, temp_pred, old_err, err;
if (div >= 512) {
*pred = 8;
*podf = 64;
} else if (div >= 8) {
min_pred = (div - 1) / 64 + 1;
old_err = 8;
for (temp_pred = 8; temp_pred >= min_pred; temp_pred--) {
err = div % temp_pred;
if (err == 0) {
*pred = temp_pred;
break;
}
err = temp_pred - err;
if (err < old_err) {
old_err = err;
*pred = temp_pred;
}
}
*podf = (div + *pred - 1) / *pred;
} else if (div < 8) {
*pred = div;
*podf = 1;
}
}
static int _clk_enable(struct clk *clk)
{
u32 reg;
reg = readl_relaxed(clk->enable_reg);
reg |= 0x3 << clk->enable_shift;
writel_relaxed(reg, clk->enable_reg);
return 0;
}
static void _clk_disable(struct clk *clk)
{
u32 reg;
reg = readl_relaxed(clk->enable_reg);
reg &= ~(0x3 << clk->enable_shift);
writel_relaxed(reg, clk->enable_reg);
}
struct divider {
struct clk *clk;
void __iomem *reg;
u32 bp_pred;
u32 bm_pred;
u32 bp_podf;
u32 bm_podf;
};
#define DEF_CLK_DIV1(d, c, r, b) \
static struct divider d = { \
.clk = c, \
.reg = r, \
.bp_podf = BP_##r##_##b##_PODF, \
.bm_podf = BM_##r##_##b##_PODF, \
}
DEF_CLK_DIV1(arm_div, &arm_clk, CACRR, ARM);
DEF_CLK_DIV1(ipg_div, &ipg_clk, CBCDR, IPG);
DEF_CLK_DIV1(ahb_div, &ahb_clk, CBCDR, AHB);
DEF_CLK_DIV1(axi_div, &axi_clk, CBCDR, AXI);
DEF_CLK_DIV1(mmdc_ch0_axi_div, &mmdc_ch0_axi_clk, CBCDR, MMDC_CH0_AXI);
DEF_CLK_DIV1(mmdc_ch1_axi_div, &mmdc_ch1_axi_clk, CBCDR, MMDC_CH1_AXI);
DEF_CLK_DIV1(periph_clk2_div, &periph_clk2_clk, CBCDR, PERIPH_CLK2);
DEF_CLK_DIV1(periph2_clk2_div, &periph2_clk2_clk, CBCDR, PERIPH2_CLK2);
DEF_CLK_DIV1(gpu2d_core_div, &gpu2d_core_clk, CBCMR, GPU2D_CORE);
DEF_CLK_DIV1(gpu3d_core_div, &gpu3d_core_clk, CBCMR, GPU3D_CORE);
DEF_CLK_DIV1(gpu3d_shader_div, &gpu3d_shader_clk, CBCMR, GPU3D_SHADER);
DEF_CLK_DIV1(ipg_perclk_div, &ipg_perclk, CSCMR1, PERCLK);
DEF_CLK_DIV1(emi_div, &emi_clk, CSCMR1, EMI);
DEF_CLK_DIV1(emi_slow_div, &emi_slow_clk, CSCMR1, EMI_SLOW);
DEF_CLK_DIV1(can_div, &can1_clk, CSCMR2, CAN);
DEF_CLK_DIV1(uart_div, &uart_clk, CSCDR1, UART);
DEF_CLK_DIV1(usdhc1_div, &usdhc1_clk, CSCDR1, USDHC1);
DEF_CLK_DIV1(usdhc2_div, &usdhc2_clk, CSCDR1, USDHC2);
DEF_CLK_DIV1(usdhc3_div, &usdhc3_clk, CSCDR1, USDHC3);
DEF_CLK_DIV1(usdhc4_div, &usdhc4_clk, CSCDR1, USDHC4);
DEF_CLK_DIV1(vpu_div, &vpu_clk, CSCDR1, VPU_AXI);
DEF_CLK_DIV1(hsi_tx_div, &hsi_tx_clk, CDCDR, HSI_TX);
DEF_CLK_DIV1(ipu1_di0_pre_div, &ipu1_di0_pre_clk, CHSCCDR, IPU1_DI0_PRE);
DEF_CLK_DIV1(ipu1_di1_pre_div, &ipu1_di1_pre_clk, CHSCCDR, IPU1_DI1_PRE);
DEF_CLK_DIV1(ipu2_di0_pre_div, &ipu2_di0_pre_clk, CSCDR2, IPU2_DI0_PRE);
DEF_CLK_DIV1(ipu2_di1_pre_div, &ipu2_di1_pre_clk, CSCDR2, IPU2_DI1_PRE);
DEF_CLK_DIV1(ipu1_div, &ipu1_clk, CSCDR3, IPU1_HSP);
DEF_CLK_DIV1(ipu2_div, &ipu2_clk, CSCDR3, IPU2_HSP);
#define DEF_CLK_DIV2(d, c, r, b) \
static struct divider d = { \
.clk = c, \
.reg = r, \
.bp_pred = BP_##r##_##b##_PRED, \
.bm_pred = BM_##r##_##b##_PRED, \
.bp_podf = BP_##r##_##b##_PODF, \
.bm_podf = BM_##r##_##b##_PODF, \
}
DEF_CLK_DIV2(ssi1_div, &ssi1_clk, CS1CDR, SSI1);
DEF_CLK_DIV2(ssi3_div, &ssi3_clk, CS1CDR, SSI3);
DEF_CLK_DIV2(esai_div, &esai_clk, CS1CDR, ESAI);
DEF_CLK_DIV2(ssi2_div, &ssi2_clk, CS2CDR, SSI2);
DEF_CLK_DIV2(enfc_div, &enfc_clk, CS2CDR, ENFC);
DEF_CLK_DIV2(spdif_div, &spdif_clk, CDCDR, SPDIF);
DEF_CLK_DIV2(asrc_serial_div, &asrc_serial_clk, CDCDR, ASRC_SERIAL);
static struct divider *dividers[] = {
&arm_div,
&ipg_div,
&ahb_div,
&axi_div,
&mmdc_ch0_axi_div,
&mmdc_ch1_axi_div,
&periph_clk2_div,
&periph2_clk2_div,
&gpu2d_core_div,
&gpu3d_core_div,
&gpu3d_shader_div,
&ipg_perclk_div,
&emi_div,
&emi_slow_div,
&can_div,
&uart_div,
&usdhc1_div,
&usdhc2_div,
&usdhc3_div,
&usdhc4_div,
&vpu_div,
&hsi_tx_div,
&ipu1_di0_pre_div,
&ipu1_di1_pre_div,
&ipu2_di0_pre_div,
&ipu2_di1_pre_div,
&ipu1_div,
&ipu2_div,
&ssi1_div,
&ssi3_div,
&esai_div,
&ssi2_div,
&enfc_div,
&spdif_div,
&asrc_serial_div,
};
static unsigned long ldb_di_clk_get_rate(struct clk *clk)
{
u32 val = readl_relaxed(CSCMR2);
val &= (clk == &ldb_di0_clk) ? BM_CSCMR2_LDB_DI0_IPU_DIV :
BM_CSCMR2_LDB_DI1_IPU_DIV;
if (val)
return clk_get_rate(clk->parent) / 7;
else
return clk_get_rate(clk->parent) * 2 / 7;
}
static int ldb_di_clk_set_rate(struct clk *clk, unsigned long rate)
{
unsigned long parent_rate = clk_get_rate(clk->parent);
u32 val = readl_relaxed(CSCMR2);
if (rate * 7 <= parent_rate + parent_rate / 20)
val |= BM_CSCMR2_LDB_DI0_IPU_DIV;
else
val &= ~BM_CSCMR2_LDB_DI0_IPU_DIV;
writel_relaxed(val, CSCMR2);
return 0;
}
static unsigned long ldb_di_clk_round_rate(struct clk *clk, unsigned long rate)
{
unsigned long parent_rate = clk_get_rate(clk->parent);
if (rate * 7 <= parent_rate + parent_rate / 20)
return parent_rate / 7;
else
return 2 * parent_rate / 7;
}
static unsigned long _clk_get_rate(struct clk *clk)
{
struct divider *d;
u32 val, pred, podf;
int i, num;
if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
return ldb_di_clk_get_rate(clk);
num = ARRAY_SIZE(dividers);
for (i = 0; i < num; i++)
if (dividers[i]->clk == clk) {
d = dividers[i];
break;
}
if (i == num)
return clk_get_rate(clk->parent);
val = readl_relaxed(d->reg);
pred = ((val & d->bm_pred) >> d->bp_pred) + 1;
podf = ((val & d->bm_podf) >> d->bp_podf) + 1;
return clk_get_rate(clk->parent) / (pred * podf);
}
static int clk_busy_wait(struct clk *clk)
{
int timeout = 0x100000;
u32 bm;
if (clk == &axi_clk)
bm = BM_CDHIPR_AXI_PODF_BUSY;
else if (clk == &ahb_clk)
bm = BM_CDHIPR_AHB_PODF_BUSY;
else if (clk == &mmdc_ch0_axi_clk)
bm = BM_CDHIPR_MMDC_CH0_PODF_BUSY;
else if (clk == &periph_clk)
bm = BM_CDHIPR_PERIPH_SEL_BUSY;
else if (clk == &arm_clk)
bm = BM_CDHIPR_ARM_PODF_BUSY;
else
return -EINVAL;
while ((readl_relaxed(CDHIPR) & bm) && --timeout)
cpu_relax();
if (unlikely(!timeout))
return -EBUSY;
return 0;
}
static int _clk_set_rate(struct clk *clk, unsigned long rate)
{
unsigned long parent_rate = clk_get_rate(clk->parent);
struct divider *d;
u32 val, div, max_div, pred = 0, podf;
int i, num;
if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
return ldb_di_clk_set_rate(clk, rate);
num = ARRAY_SIZE(dividers);
for (i = 0; i < num; i++)
if (dividers[i]->clk == clk) {
d = dividers[i];
break;
}
if (i == num)
return -EINVAL;
max_div = ((d->bm_pred >> d->bp_pred) + 1) *
((d->bm_pred >> d->bp_pred) + 1);
div = parent_rate / rate;
if (div == 0)
div++;
if ((parent_rate / div != rate) || div > max_div)
return -EINVAL;
if (d->bm_pred) {
calc_pred_podf_dividers(div, &pred, &podf);
} else {
pred = 1;
podf = div;
}
val = readl_relaxed(d->reg);
val &= ~(d->bm_pred | d->bm_podf);
val |= (pred - 1) << d->bp_pred | (podf - 1) << d->bp_podf;
writel_relaxed(val, d->reg);
if (clk == &axi_clk || clk == &ahb_clk ||
clk == &mmdc_ch0_axi_clk || clk == &arm_clk)
return clk_busy_wait(clk);
return 0;
}
static unsigned long _clk_round_rate(struct clk *clk, unsigned long rate)
{
unsigned long parent_rate = clk_get_rate(clk->parent);
u32 div = parent_rate / rate;
u32 div_max, pred = 0, podf;
struct divider *d;
int i, num;
if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
return ldb_di_clk_round_rate(clk, rate);
num = ARRAY_SIZE(dividers);
for (i = 0; i < num; i++)
if (dividers[i]->clk == clk) {
d = dividers[i];
break;
}
if (i == num)
return -EINVAL;
if (div == 0 || parent_rate % rate)
div++;
if (d->bm_pred) {
calc_pred_podf_dividers(div, &pred, &podf);
div = pred * podf;
} else {
div_max = (d->bm_podf >> d->bp_podf) + 1;
if (div > div_max)
div = div_max;
}
return parent_rate / div;
}
struct multiplexer {
struct clk *clk;
void __iomem *reg;
u32 bp;
u32 bm;
int pnum;
struct clk *parents[];
};
static struct multiplexer axi_mux = {
.clk = &axi_clk,
.reg = CBCDR,
.bp = BP_CBCDR_AXI_SEL,
.bm = BM_CBCDR_AXI_SEL,
.parents = {
&periph_clk,
&pll2_pfd_400m,
&pll3_pfd_540m,
NULL
},
};
static struct multiplexer periph_mux = {
.clk = &periph_clk,
.reg = CBCDR,
.bp = BP_CBCDR_PERIPH_CLK_SEL,
.bm = BM_CBCDR_PERIPH_CLK_SEL,
.parents = {
&periph_pre_clk,
&periph_clk2_clk,
NULL
},
};
static struct multiplexer periph_pre_mux = {
.clk = &periph_pre_clk,
.reg = CBCMR,
.bp = BP_CBCMR_PRE_PERIPH_CLK_SEL,
.bm = BM_CBCMR_PRE_PERIPH_CLK_SEL,
.parents = {
&pll2_bus,
&pll2_pfd_400m,
&pll2_pfd_352m,
&pll2_200m,
NULL
},
};
static struct multiplexer periph_clk2_mux = {
.clk = &periph_clk2_clk,
.reg = CBCMR,
.bp = BP_CBCMR_PERIPH_CLK2_SEL,
.bm = BM_CBCMR_PERIPH_CLK2_SEL,
.parents = {
&pll3_usb_otg,
&osc_clk,
NULL
},
};
static struct multiplexer periph2_mux = {
.clk = &periph2_clk,
.reg = CBCDR,
.bp = BP_CBCDR_PERIPH2_CLK_SEL,
.bm = BM_CBCDR_PERIPH2_CLK_SEL,
.parents = {
&periph2_pre_clk,
&periph2_clk2_clk,
NULL
},
};
static struct multiplexer periph2_pre_mux = {
.clk = &periph2_pre_clk,
.reg = CBCMR,
.bp = BP_CBCMR_PRE_PERIPH2_CLK_SEL,
.bm = BM_CBCMR_PRE_PERIPH2_CLK_SEL,
.parents = {
&pll2_bus,
&pll2_pfd_400m,
&pll2_pfd_352m,
&pll2_200m,
NULL
},
};
static struct multiplexer periph2_clk2_mux = {
.clk = &periph2_clk2_clk,
.reg = CBCMR,
.bp = BP_CBCMR_PERIPH2_CLK2_SEL,
.bm = BM_CBCMR_PERIPH2_CLK2_SEL,
.parents = {
&pll3_usb_otg,
&osc_clk,
NULL
},
};
static struct multiplexer gpu2d_axi_mux = {
.clk = &gpu2d_axi_clk,
.reg = CBCMR,
.bp = BP_CBCMR_GPU2D_AXI_SEL,
.bm = BM_CBCMR_GPU2D_AXI_SEL,
.parents = {
&axi_clk,
&ahb_clk,
NULL
},
};
static struct multiplexer gpu3d_axi_mux = {
.clk = &gpu3d_axi_clk,
.reg = CBCMR,
.bp = BP_CBCMR_GPU3D_AXI_SEL,
.bm = BM_CBCMR_GPU3D_AXI_SEL,
.parents = {
&axi_clk,
&ahb_clk,
NULL
},
};
static struct multiplexer gpu3d_core_mux = {
.clk = &gpu3d_core_clk,
.reg = CBCMR,
.bp = BP_CBCMR_GPU3D_CORE_SEL,
.bm = BM_CBCMR_GPU3D_CORE_SEL,
.parents = {
&mmdc_ch0_axi_clk,
&pll3_usb_otg,
&pll2_pfd_594m,
&pll2_pfd_400m,
NULL
},
};
static struct multiplexer gpu3d_shader_mux = {
.clk = &gpu3d_shader_clk,
.reg = CBCMR,
.bp = BP_CBCMR_GPU3D_SHADER_SEL,
.bm = BM_CBCMR_GPU3D_SHADER_SEL,
.parents = {
&mmdc_ch0_axi_clk,
&pll3_usb_otg,
&pll2_pfd_594m,
&pll3_pfd_720m,
NULL
},
};
static struct multiplexer pcie_axi_mux = {
.clk = &pcie_clk,
.reg = CBCMR,
.bp = BP_CBCMR_PCIE_AXI_SEL,
.bm = BM_CBCMR_PCIE_AXI_SEL,
.parents = {
&axi_clk,
&ahb_clk,
NULL
},
};
static struct multiplexer vdo_axi_mux = {
.clk = &vdo_axi_clk,
.reg = CBCMR,
.bp = BP_CBCMR_VDO_AXI_SEL,
.bm = BM_CBCMR_VDO_AXI_SEL,
.parents = {
&axi_clk,
&ahb_clk,
NULL
},
};
static struct multiplexer vpu_axi_mux = {
.clk = &vpu_clk,
.reg = CBCMR,
.bp = BP_CBCMR_VPU_AXI_SEL,
.bm = BM_CBCMR_VPU_AXI_SEL,
.parents = {
&axi_clk,
&pll2_pfd_400m,
&pll2_pfd_352m,
NULL
},
};
static struct multiplexer gpu2d_core_mux = {
.clk = &gpu2d_core_clk,
.reg = CBCMR,
.bp = BP_CBCMR_GPU2D_CORE_SEL,
.bm = BM_CBCMR_GPU2D_CORE_SEL,
.parents = {
&axi_clk,
&pll3_usb_otg,
&pll2_pfd_352m,
&pll2_pfd_400m,
NULL
},
};
#define DEF_SSI_MUX(id) \
static struct multiplexer ssi##id##_mux = { \
.clk = &ssi##id##_clk, \
.reg = CSCMR1, \
.bp = BP_CSCMR1_SSI##id##_SEL, \
.bm = BM_CSCMR1_SSI##id##_SEL, \
.parents = { \
&pll3_pfd_508m, \
&pll3_pfd_454m, \
&pll4_audio, \
NULL \
}, \
}
DEF_SSI_MUX(1);
DEF_SSI_MUX(2);
DEF_SSI_MUX(3);
#define DEF_USDHC_MUX(id) \
static struct multiplexer usdhc##id##_mux = { \
.clk = &usdhc##id##_clk, \
.reg = CSCMR1, \
.bp = BP_CSCMR1_USDHC##id##_SEL, \
.bm = BM_CSCMR1_USDHC##id##_SEL, \
.parents = { \
&pll2_pfd_400m, \
&pll2_pfd_352m, \
NULL \
}, \
}
DEF_USDHC_MUX(1);
DEF_USDHC_MUX(2);
DEF_USDHC_MUX(3);
DEF_USDHC_MUX(4);
static struct multiplexer emi_mux = {
.clk = &emi_clk,
.reg = CSCMR1,
.bp = BP_CSCMR1_EMI_SEL,
.bm = BM_CSCMR1_EMI_SEL,
.parents = {
&axi_clk,
&pll3_usb_otg,
&pll2_pfd_400m,
&pll2_pfd_352m,
NULL
},
};
static struct multiplexer emi_slow_mux = {
.clk = &emi_slow_clk,
.reg = CSCMR1,
.bp = BP_CSCMR1_EMI_SLOW_SEL,
.bm = BM_CSCMR1_EMI_SLOW_SEL,
.parents = {
&axi_clk,
&pll3_usb_otg,
&pll2_pfd_400m,
&pll2_pfd_352m,
NULL
},
};
static struct multiplexer esai_mux = {
.clk = &esai_clk,
.reg = CSCMR2,
.bp = BP_CSCMR2_ESAI_SEL,
.bm = BM_CSCMR2_ESAI_SEL,
.parents = {
&pll4_audio,
&pll3_pfd_508m,
&pll3_pfd_454m,
&pll3_usb_otg,
NULL
},
};
#define DEF_LDB_DI_MUX(id) \
static struct multiplexer ldb_di##id##_mux = { \
.clk = &ldb_di##id##_clk, \
.reg = CS2CDR, \
.bp = BP_CS2CDR_LDB_DI##id##_SEL, \
.bm = BM_CS2CDR_LDB_DI##id##_SEL, \
.parents = { \
&pll5_video, \
&pll2_pfd_352m, \
&pll2_pfd_400m, \
&pll3_pfd_540m, \
&pll3_usb_otg, \
NULL \
}, \
}
DEF_LDB_DI_MUX(0);
DEF_LDB_DI_MUX(1);
static struct multiplexer enfc_mux = {
.clk = &enfc_clk,
.reg = CS2CDR,
.bp = BP_CS2CDR_ENFC_SEL,
.bm = BM_CS2CDR_ENFC_SEL,
.parents = {
&pll2_pfd_352m,
&pll2_bus,
&pll3_usb_otg,
&pll2_pfd_400m,
NULL
},
};
static struct multiplexer spdif_mux = {
.clk = &spdif_clk,
.reg = CDCDR,
.bp = BP_CDCDR_SPDIF_SEL,
.bm = BM_CDCDR_SPDIF_SEL,
.parents = {
&pll4_audio,
&pll3_pfd_508m,
&pll3_pfd_454m,
&pll3_usb_otg,
NULL
},
};
static struct multiplexer asrc_serial_mux = {
.clk = &asrc_serial_clk,
.reg = CDCDR,
.bp = BP_CDCDR_ASRC_SERIAL_SEL,
.bm = BM_CDCDR_ASRC_SERIAL_SEL,
.parents = {
&pll4_audio,
&pll3_pfd_508m,
&pll3_pfd_454m,
&pll3_usb_otg,
NULL
},
};
static struct multiplexer hsi_tx_mux = {
.clk = &hsi_tx_clk,
.reg = CDCDR,
.bp = BP_CDCDR_HSI_TX_SEL,
.bm = BM_CDCDR_HSI_TX_SEL,
.parents = {
&pll3_120m,
&pll2_pfd_400m,
NULL
},
};
#define DEF_IPU_DI_PRE_MUX(r, i, d) \
static struct multiplexer ipu##i##_di##d##_pre_mux = { \
.clk = &ipu##i##_di##d##_pre_clk, \
.reg = r, \
.bp = BP_##r##_IPU##i##_DI##d##_PRE_SEL, \
.bm = BM_##r##_IPU##i##_DI##d##_PRE_SEL, \
.parents = { \
&mmdc_ch0_axi_clk, \
&pll3_usb_otg, \
&pll5_video, \
&pll2_pfd_352m, \
&pll2_pfd_400m, \
&pll3_pfd_540m, \
NULL \
}, \
}
DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 0);
DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 1);
DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 0);
DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 1);
#define DEF_IPU_DI_MUX(r, i, d) \
static struct multiplexer ipu##i##_di##d##_mux = { \
.clk = &ipu##i##_di##d##_clk, \
.reg = r, \
.bp = BP_##r##_IPU##i##_DI##d##_SEL, \
.bm = BM_##r##_IPU##i##_DI##d##_SEL, \
.parents = { \
&ipu##i##_di##d##_pre_clk, \
&dummy_clk, \
&dummy_clk, \
&ldb_di0_clk, \
&ldb_di1_clk, \
NULL \
}, \
}
DEF_IPU_DI_MUX(CHSCCDR, 1, 0);
DEF_IPU_DI_MUX(CHSCCDR, 1, 1);
DEF_IPU_DI_MUX(CSCDR2, 2, 0);
DEF_IPU_DI_MUX(CSCDR2, 2, 1);
#define DEF_IPU_MUX(id) \
static struct multiplexer ipu##id##_mux = { \
.clk = &ipu##id##_clk, \
.reg = CSCDR3, \
.bp = BP_CSCDR3_IPU##id##_HSP_SEL, \
.bm = BM_CSCDR3_IPU##id##_HSP_SEL, \
.parents = { \
&mmdc_ch0_axi_clk, \
&pll2_pfd_400m, \
&pll3_120m, \
&pll3_pfd_540m, \
NULL \
}, \
}
DEF_IPU_MUX(1);
DEF_IPU_MUX(2);
static struct multiplexer *multiplexers[] = {
&axi_mux,
&periph_mux,
&periph_pre_mux,
&periph_clk2_mux,
&periph2_mux,
&periph2_pre_mux,
&periph2_clk2_mux,
&gpu2d_axi_mux,
&gpu3d_axi_mux,
&gpu3d_core_mux,
&gpu3d_shader_mux,
&pcie_axi_mux,
&vdo_axi_mux,
&vpu_axi_mux,
&gpu2d_core_mux,
&ssi1_mux,
&ssi2_mux,
&ssi3_mux,
&usdhc1_mux,
&usdhc2_mux,
&usdhc3_mux,
&usdhc4_mux,
&emi_mux,
&emi_slow_mux,
&esai_mux,
&ldb_di0_mux,
&ldb_di1_mux,
&enfc_mux,
&spdif_mux,
&asrc_serial_mux,
&hsi_tx_mux,
&ipu1_di0_pre_mux,
&ipu1_di0_mux,
&ipu1_di1_pre_mux,
&ipu1_di1_mux,
&ipu2_di0_pre_mux,
&ipu2_di0_mux,
&ipu2_di1_pre_mux,
&ipu2_di1_mux,
&ipu1_mux,
&ipu2_mux,
};
static int _clk_set_parent(struct clk *clk, struct clk *parent)
{
struct multiplexer *m;
int i, num;
u32 val;
num = ARRAY_SIZE(multiplexers);
for (i = 0; i < num; i++)
if (multiplexers[i]->clk == clk) {
m = multiplexers[i];
break;
}
if (i == num)
return -EINVAL;
i = 0;
while (m->parents[i]) {
if (parent == m->parents[i])
break;
i++;
}
if (!m->parents[i])
return -EINVAL;
val = readl_relaxed(m->reg);
val &= ~m->bm;
val |= i << m->bp;
writel_relaxed(val, m->reg);
if (clk == &periph_clk)
return clk_busy_wait(clk);
return 0;
}
#define DEF_NG_CLK(name, p) \
static struct clk name = { \
.get_rate = _clk_get_rate, \
.set_rate = _clk_set_rate, \
.round_rate = _clk_round_rate, \
.set_parent = _clk_set_parent, \
.parent = p, \
}
DEF_NG_CLK(periph_clk2_clk, &osc_clk);
DEF_NG_CLK(periph_pre_clk, &pll2_bus);
DEF_NG_CLK(periph_clk, &periph_pre_clk);
DEF_NG_CLK(periph2_clk2_clk, &osc_clk);
DEF_NG_CLK(periph2_pre_clk, &pll2_bus);
DEF_NG_CLK(periph2_clk, &periph2_pre_clk);
DEF_NG_CLK(axi_clk, &periph_clk);
DEF_NG_CLK(emi_clk, &axi_clk);
DEF_NG_CLK(arm_clk, &pll1_sw_clk);
DEF_NG_CLK(ahb_clk, &periph_clk);
DEF_NG_CLK(ipg_clk, &ahb_clk);
DEF_NG_CLK(ipg_perclk, &ipg_clk);
DEF_NG_CLK(ipu1_di0_pre_clk, &pll3_pfd_540m);
DEF_NG_CLK(ipu1_di1_pre_clk, &pll3_pfd_540m);
DEF_NG_CLK(ipu2_di0_pre_clk, &pll3_pfd_540m);
DEF_NG_CLK(ipu2_di1_pre_clk, &pll3_pfd_540m);
DEF_NG_CLK(asrc_serial_clk, &pll3_usb_otg);
#define DEF_CLK(name, er, es, p, s) \
static struct clk name = { \
.enable_reg = er, \
.enable_shift = es, \
.enable = _clk_enable, \
.disable = _clk_disable, \
.get_rate = _clk_get_rate, \
.set_rate = _clk_set_rate, \
.round_rate = _clk_round_rate, \
.set_parent = _clk_set_parent, \
.parent = p, \
.secondary = s, \
}
DEF_CLK(aips_tz1_clk, CCGR0, CG0, &ahb_clk, NULL);
DEF_CLK(aips_tz2_clk, CCGR0, CG1, &ahb_clk, NULL);
DEF_CLK(apbh_dma_clk, CCGR0, CG2, &ahb_clk, NULL);
DEF_CLK(asrc_clk, CCGR0, CG3, &pll4_audio, NULL);
DEF_CLK(can1_serial_clk, CCGR0, CG8, &pll3_usb_otg, NULL);
DEF_CLK(can1_clk, CCGR0, CG7, &pll3_usb_otg, &can1_serial_clk);
DEF_CLK(can2_serial_clk, CCGR0, CG10, &pll3_usb_otg, NULL);
DEF_CLK(can2_clk, CCGR0, CG9, &pll3_usb_otg, &can2_serial_clk);
DEF_CLK(ecspi1_clk, CCGR1, CG0, &pll3_60m, NULL);
DEF_CLK(ecspi2_clk, CCGR1, CG1, &pll3_60m, NULL);
DEF_CLK(ecspi3_clk, CCGR1, CG2, &pll3_60m, NULL);
DEF_CLK(ecspi4_clk, CCGR1, CG3, &pll3_60m, NULL);
DEF_CLK(ecspi5_clk, CCGR1, CG4, &pll3_60m, NULL);
DEF_CLK(enet_clk, CCGR1, CG5, &ipg_clk, NULL);
DEF_CLK(esai_clk, CCGR1, CG8, &pll3_usb_otg, NULL);
DEF_CLK(gpt_serial_clk, CCGR1, CG11, &ipg_perclk, NULL);
DEF_CLK(gpt_clk, CCGR1, CG10, &ipg_perclk, &gpt_serial_clk);
DEF_CLK(gpu2d_core_clk, CCGR1, CG12, &pll2_pfd_352m, &gpu2d_axi_clk);
DEF_CLK(gpu3d_core_clk, CCGR1, CG13, &pll2_pfd_594m, &gpu3d_axi_clk);
DEF_CLK(gpu3d_shader_clk, CCGR1, CG13, &pll3_pfd_720m, &gpu3d_axi_clk);
DEF_CLK(hdmi_iahb_clk, CCGR2, CG0, &ahb_clk, NULL);
DEF_CLK(hdmi_isfr_clk, CCGR2, CG2, &pll3_pfd_540m, &hdmi_iahb_clk);
DEF_CLK(i2c1_clk, CCGR2, CG3, &ipg_perclk, NULL);
DEF_CLK(i2c2_clk, CCGR2, CG4, &ipg_perclk, NULL);
DEF_CLK(i2c3_clk, CCGR2, CG5, &ipg_perclk, NULL);
DEF_CLK(iim_clk, CCGR2, CG6, &ipg_clk, NULL);
DEF_CLK(enfc_clk, CCGR2, CG7, &pll2_pfd_352m, NULL);
DEF_CLK(ipu1_clk, CCGR3, CG0, &mmdc_ch0_axi_clk, NULL);
DEF_CLK(ipu1_di0_clk, CCGR3, CG1, &ipu1_di0_pre_clk, NULL);
DEF_CLK(ipu1_di1_clk, CCGR3, CG2, &ipu1_di1_pre_clk, NULL);
DEF_CLK(ipu2_clk, CCGR3, CG3, &mmdc_ch0_axi_clk, NULL);
DEF_CLK(ipu2_di0_clk, CCGR3, CG4, &ipu2_di0_pre_clk, NULL);
DEF_CLK(ipu2_di1_clk, CCGR3, CG5, &ipu2_di1_pre_clk, NULL);
DEF_CLK(ldb_di0_clk, CCGR3, CG6, &pll3_pfd_540m, NULL);
DEF_CLK(ldb_di1_clk, CCGR3, CG7, &pll3_pfd_540m, NULL);
DEF_CLK(hsi_tx_clk, CCGR3, CG8, &pll2_pfd_400m, NULL);
DEF_CLK(mlb_clk, CCGR3, CG9, &pll6_mlb, NULL);
DEF_CLK(mmdc_ch0_ipg_clk, CCGR3, CG12, &ipg_clk, NULL);
DEF_CLK(mmdc_ch0_axi_clk, CCGR3, CG10, &periph_clk, &mmdc_ch0_ipg_clk);
DEF_CLK(mmdc_ch1_ipg_clk, CCGR3, CG13, &ipg_clk, NULL);
DEF_CLK(mmdc_ch1_axi_clk, CCGR3, CG11, &periph2_clk, &mmdc_ch1_ipg_clk);
DEF_CLK(openvg_axi_clk, CCGR3, CG13, &axi_clk, NULL);
DEF_CLK(pwm1_clk, CCGR4, CG8, &ipg_perclk, NULL);
DEF_CLK(pwm2_clk, CCGR4, CG9, &ipg_perclk, NULL);
DEF_CLK(pwm3_clk, CCGR4, CG10, &ipg_perclk, NULL);
DEF_CLK(pwm4_clk, CCGR4, CG11, &ipg_perclk, NULL);
DEF_CLK(gpmi_bch_apb_clk, CCGR4, CG12, &usdhc3_clk, NULL);
DEF_CLK(gpmi_bch_clk, CCGR4, CG13, &usdhc4_clk, &gpmi_bch_apb_clk);
DEF_CLK(gpmi_apb_clk, CCGR4, CG15, &usdhc3_clk, &gpmi_bch_clk);
DEF_CLK(gpmi_io_clk, CCGR4, CG14, &enfc_clk, &gpmi_apb_clk);
DEF_CLK(sdma_clk, CCGR5, CG3, &ahb_clk, NULL);
DEF_CLK(spba_clk, CCGR5, CG6, &ipg_clk, NULL);
DEF_CLK(spdif_clk, CCGR5, CG7, &pll3_usb_otg, &spba_clk);
DEF_CLK(ssi1_clk, CCGR5, CG9, &pll3_pfd_508m, NULL);
DEF_CLK(ssi2_clk, CCGR5, CG10, &pll3_pfd_508m, NULL);
DEF_CLK(ssi3_clk, CCGR5, CG11, &pll3_pfd_508m, NULL);
DEF_CLK(uart_serial_clk, CCGR5, CG13, &pll3_usb_otg, NULL);
DEF_CLK(uart_clk, CCGR5, CG12, &pll3_80m, &uart_serial_clk);
DEF_CLK(usboh3_clk, CCGR6, CG0, &ipg_clk, NULL);
DEF_CLK(usdhc1_clk, CCGR6, CG1, &pll2_pfd_400m, NULL);
DEF_CLK(usdhc2_clk, CCGR6, CG2, &pll2_pfd_400m, NULL);
DEF_CLK(usdhc3_clk, CCGR6, CG3, &pll2_pfd_400m, NULL);
DEF_CLK(usdhc4_clk, CCGR6, CG4, &pll2_pfd_400m, NULL);
DEF_CLK(emi_slow_clk, CCGR6, CG5, &axi_clk, NULL);
DEF_CLK(vdo_axi_clk, CCGR6, CG6, &axi_clk, NULL);
DEF_CLK(vpu_clk, CCGR6, CG7, &axi_clk, NULL);
static int pcie_clk_enable(struct clk *clk)
{
u32 val;
val = readl_relaxed(PLL8_ENET);
val |= BM_PLL_ENET_EN_PCIE;
writel_relaxed(val, PLL8_ENET);
return _clk_enable(clk);
}
static void pcie_clk_disable(struct clk *clk)
{
u32 val;
_clk_disable(clk);
val = readl_relaxed(PLL8_ENET);
val &= BM_PLL_ENET_EN_PCIE;
writel_relaxed(val, PLL8_ENET);
}
static struct clk pcie_clk = {
.enable_reg = CCGR4,
.enable_shift = CG0,
.enable = pcie_clk_enable,
.disable = pcie_clk_disable,
.set_parent = _clk_set_parent,
.parent = &axi_clk,
.secondary = &pll8_enet,
};
static int sata_clk_enable(struct clk *clk)
{
u32 val;
val = readl_relaxed(PLL8_ENET);
val |= BM_PLL_ENET_EN_SATA;
writel_relaxed(val, PLL8_ENET);
return _clk_enable(clk);
}
static void sata_clk_disable(struct clk *clk)
{
u32 val;
_clk_disable(clk);
val = readl_relaxed(PLL8_ENET);
val &= BM_PLL_ENET_EN_SATA;
writel_relaxed(val, PLL8_ENET);
}
static struct clk sata_clk = {
.enable_reg = CCGR5,
.enable_shift = CG2,
.enable = sata_clk_enable,
.disable = sata_clk_disable,
.parent = &ipg_clk,
.secondary = &pll8_enet,
};
#define _REGISTER_CLOCK(d, n, c) \
{ \
.dev_id = d, \
.con_id = n, \
.clk = &c, \
}
static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("2020000.uart", NULL, uart_clk),
_REGISTER_CLOCK("21e8000.uart", NULL, uart_clk),
_REGISTER_CLOCK("21ec000.uart", NULL, uart_clk),
_REGISTER_CLOCK("21f0000.uart", NULL, uart_clk),
_REGISTER_CLOCK("21f4000.uart", NULL, uart_clk),
_REGISTER_CLOCK("2188000.enet", NULL, enet_clk),
_REGISTER_CLOCK("2190000.usdhc", NULL, usdhc1_clk),
_REGISTER_CLOCK("2194000.usdhc", NULL, usdhc2_clk),
_REGISTER_CLOCK("2198000.usdhc", NULL, usdhc3_clk),
_REGISTER_CLOCK("219c000.usdhc", NULL, usdhc4_clk),
_REGISTER_CLOCK("21a0000.i2c", NULL, i2c1_clk),
_REGISTER_CLOCK("21a4000.i2c", NULL, i2c2_clk),
_REGISTER_CLOCK("21a8000.i2c", NULL, i2c3_clk),
_REGISTER_CLOCK("2008000.ecspi", NULL, ecspi1_clk),
_REGISTER_CLOCK("200c000.ecspi", NULL, ecspi2_clk),
_REGISTER_CLOCK("2010000.ecspi", NULL, ecspi3_clk),
_REGISTER_CLOCK("2014000.ecspi", NULL, ecspi4_clk),
_REGISTER_CLOCK("2018000.ecspi", NULL, ecspi5_clk),
_REGISTER_CLOCK("20ec000.sdma", NULL, sdma_clk),
_REGISTER_CLOCK("20bc000.wdog", NULL, dummy_clk),
_REGISTER_CLOCK("20c0000.wdog", NULL, dummy_clk),
_REGISTER_CLOCK(NULL, "ckih", ckih_clk),
_REGISTER_CLOCK(NULL, "ckil_clk", ckil_clk),
_REGISTER_CLOCK(NULL, "aips_tz1_clk", aips_tz1_clk),
_REGISTER_CLOCK(NULL, "aips_tz2_clk", aips_tz2_clk),
_REGISTER_CLOCK(NULL, "asrc_clk", asrc_clk),
_REGISTER_CLOCK(NULL, "can2_clk", can2_clk),
_REGISTER_CLOCK(NULL, "hdmi_isfr_clk", hdmi_isfr_clk),
_REGISTER_CLOCK(NULL, "iim_clk", iim_clk),
_REGISTER_CLOCK(NULL, "mlb_clk", mlb_clk),
_REGISTER_CLOCK(NULL, "openvg_axi_clk", openvg_axi_clk),
_REGISTER_CLOCK(NULL, "pwm1_clk", pwm1_clk),
_REGISTER_CLOCK(NULL, "pwm2_clk", pwm2_clk),
_REGISTER_CLOCK(NULL, "pwm3_clk", pwm3_clk),
_REGISTER_CLOCK(NULL, "pwm4_clk", pwm4_clk),
_REGISTER_CLOCK(NULL, "gpmi_io_clk", gpmi_io_clk),
_REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk),
_REGISTER_CLOCK(NULL, "sata_clk", sata_clk),
};
int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
{
u32 val = readl_relaxed(CLPCR);
val &= ~BM_CLPCR_LPM;
switch (mode) {
case WAIT_CLOCKED:
break;
case WAIT_UNCLOCKED:
val |= 0x1 << BP_CLPCR_LPM;
break;
case STOP_POWER_ON:
val |= 0x2 << BP_CLPCR_LPM;
break;
case WAIT_UNCLOCKED_POWER_OFF:
val |= 0x1 << BP_CLPCR_LPM;
val &= ~BM_CLPCR_VSTBY;
val &= ~BM_CLPCR_SBYOS;
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
break;
case STOP_POWER_OFF:
val |= 0x2 << BP_CLPCR_LPM;
val |= 0x3 << BP_CLPCR_STBY_COUNT;
val |= BM_CLPCR_VSTBY;
val |= BM_CLPCR_SBYOS;
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
break;
default:
return -EINVAL;
}
writel_relaxed(val, CLPCR);
return 0;
}
static struct map_desc imx6q_clock_desc[] = {
imx_map_entry(MX6Q, CCM, MT_DEVICE),
imx_map_entry(MX6Q, ANATOP, MT_DEVICE),
};
int __init mx6q_clocks_init(void)
{
struct device_node *np;
void __iomem *base;
int i, irq;
iotable_init(imx6q_clock_desc, ARRAY_SIZE(imx6q_clock_desc));
/* retrieve the freqency of fixed clocks from device tree */
for_each_compatible_node(np, NULL, "fixed-clock") {
u32 rate;
if (of_property_read_u32(np, "clock-frequency", &rate))
continue;
if (of_device_is_compatible(np, "fsl,imx-ckil"))
external_low_reference = rate;
else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
external_high_reference = rate;
else if (of_device_is_compatible(np, "fsl,imx-osc"))
oscillator_reference = rate;
}
for (i = 0; i < ARRAY_SIZE(lookups); i++)
clkdev_add(&lookups[i]);
/* only keep necessary clocks on */
writel_relaxed(0x3 << CG0 | 0x3 << CG1 | 0x3 << CG2, CCGR0);
writel_relaxed(0x3 << CG8 | 0x3 << CG9 | 0x3 << CG10, CCGR2);
writel_relaxed(0x3 << CG10 | 0x3 << CG12, CCGR3);
writel_relaxed(0x3 << CG4 | 0x3 << CG6 | 0x3 << CG7, CCGR4);
writel_relaxed(0x3 << CG0, CCGR5);
writel_relaxed(0, CCGR6);
writel_relaxed(0, CCGR7);
clk_enable(&uart_clk);
clk_enable(&mmdc_ch0_axi_clk);
clk_set_rate(&pll4_audio, FREQ_650M);
clk_set_rate(&pll5_video, FREQ_650M);
clk_set_parent(&ipu1_di0_clk, &ipu1_di0_pre_clk);
clk_set_parent(&ipu1_di0_pre_clk, &pll5_video);
clk_set_parent(&gpu3d_shader_clk, &pll2_pfd_594m);
clk_set_rate(&gpu3d_shader_clk, FREQ_594M);
clk_set_parent(&gpu3d_core_clk, &mmdc_ch0_axi_clk);
clk_set_rate(&gpu3d_core_clk, FREQ_528M);
clk_set_parent(&asrc_serial_clk, &pll3_usb_otg);
clk_set_rate(&asrc_serial_clk, 1500000);
clk_set_rate(&enfc_clk, 11000000);
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
base = of_iomap(np, 0);
WARN_ON(!base);
irq = irq_of_parse_and_map(np, 0);
mxc_timer_init(&gpt_clk, base, irq);
return 0;
}
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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/io.h>
#include <linux/irq.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <asm/hardware/gic.h>
#define GPC_IMR1 0x008
#define GPC_PGC_CPU_PDN 0x2a0
#define IMR_NUM 4
static void __iomem *gpc_base;
static u32 gpc_wake_irqs[IMR_NUM];
static u32 gpc_saved_imrs[IMR_NUM];
void imx_gpc_pre_suspend(void)
{
void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
int i;
/* Tell GPC to power off ARM core when suspend */
writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
for (i = 0; i < IMR_NUM; i++) {
gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
writel_relaxed(~gpc_wake_irqs[i], reg_imr1 + i * 4);
}
}
void imx_gpc_post_resume(void)
{
void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
int i;
/* Keep ARM core powered on for other low-power modes */
writel_relaxed(0x0, gpc_base + GPC_PGC_CPU_PDN);
for (i = 0; i < IMR_NUM; i++)
writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
}
static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on)
{
unsigned int idx = d->irq / 32 - 1;
u32 mask;
/* Sanity check for SPI irq */
if (d->irq < 32)
return -EINVAL;
mask = 1 << d->irq % 32;
gpc_wake_irqs[idx] = on ? gpc_wake_irqs[idx] | mask :
gpc_wake_irqs[idx] & ~mask;
return 0;
}
static void imx_gpc_irq_unmask(struct irq_data *d)
{
void __iomem *reg;
u32 val;
/* Sanity check for SPI irq */
if (d->irq < 32)
return;
reg = gpc_base + GPC_IMR1 + (d->irq / 32 - 1) * 4;
val = readl_relaxed(reg);
val &= ~(1 << d->irq % 32);
writel_relaxed(val, reg);
}
static void imx_gpc_irq_mask(struct irq_data *d)
{
void __iomem *reg;
u32 val;
/* Sanity check for SPI irq */
if (d->irq < 32)
return;
reg = gpc_base + GPC_IMR1 + (d->irq / 32 - 1) * 4;
val = readl_relaxed(reg);
val |= 1 << (d->irq % 32);
writel_relaxed(val, reg);
}
void __init imx_gpc_init(void)
{
struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
gpc_base = of_iomap(np, 0);
WARN_ON(!gpc_base);
/* Register GPC as the secondary interrupt controller behind GIC */
gic_arch_extn.irq_mask = imx_gpc_irq_mask;
gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake;
}
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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>
#include <linux/init.h>
#include <asm/asm-offsets.h>
#include <asm/hardware/cache-l2x0.h>
.section ".text.head", "ax"
__CPUINIT
/*
* The secondary kernel init calls v7_flush_dcache_all before it enables
* the L1; however, the L1 comes out of reset in an undefined state, so
* the clean + invalidate performed by v7_flush_dcache_all causes a bunch
* of cache lines with uninitialized data and uninitialized tags to get
* written out to memory, which does really unpleasant things to the main
* processor. We fix this by performing an invalidate, rather than a
* clean + invalidate, before jumping into the kernel.
*
* This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
* to be called for both secondary cores startup and primary core resume
* procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S.
*/
ENTRY(v7_invalidate_l1)
mov r0, #0
mcr p15, 2, r0, c0, c0, 0
mrc p15, 1, r0, c0, c0, 0
ldr r1, =0x7fff
and r2, r1, r0, lsr #13
ldr r1, =0x3ff
and r3, r1, r0, lsr #3 @ NumWays - 1
add r2, r2, #1 @ NumSets
and r0, r0, #0x7
add r0, r0, #4 @ SetShift
clz r1, r3 @ WayShift
add r4, r3, #1 @ NumWays
1: sub r2, r2, #1 @ NumSets--
mov r3, r4 @ Temp = NumWays
2: subs r3, r3, #1 @ Temp--
mov r5, r3, lsl r1
mov r6, r2, lsl r0
orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
mcr p15, 0, r5, c7, c6, 2
bgt 2b
cmp r2, #0
bgt 1b
dsb
isb
mov pc, lr
ENDPROC(v7_invalidate_l1)
#ifdef CONFIG_SMP
ENTRY(v7_secondary_startup)
bl v7_invalidate_l1
b secondary_startup
ENDPROC(v7_secondary_startup)
#endif
/*
* The following code is located into the .data section. This is to
* allow phys_l2x0_saved_regs to be accessed with a relative load
* as we are running on physical address here.
*/
.data
.align
.macro pl310_resume
ldr r2, phys_l2x0_saved_regs
ldr r0, [r2, #L2X0_R_PHY_BASE] @ get physical base of l2x0
ldr r1, [r2, #L2X0_R_AUX_CTRL] @ get aux_ctrl value
str r1, [r0, #L2X0_AUX_CTRL] @ restore aux_ctrl
mov r1, #0x1
str r1, [r0, #L2X0_CTRL] @ re-enable L2
.endm
ENTRY(v7_cpu_resume)
bl v7_invalidate_l1
pl310_resume
b cpu_resume
ENDPROC(v7_cpu_resume)
.globl phys_l2x0_saved_regs
phys_l2x0_saved_regs:
.long 0
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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/errno.h>
#include <asm/cacheflush.h>
#include <mach/common.h>
int platform_cpu_kill(unsigned int cpu)
{
return 1;
}
/*
* platform-specific code to shutdown a CPU
*
* Called with IRQs disabled
*/
void platform_cpu_die(unsigned int cpu)
{
flush_cache_all();
imx_enable_cpu(cpu, false);
cpu_do_idle();
/* We should never return from idle */
panic("cpu %d unexpectedly exit from shutdown\n", cpu);
}
int platform_cpu_disable(unsigned int cpu)
{
/*
* we don't allow CPU 0 to be shutdown (it is still too special
* e.g. clock tick interrupts)
*/
return cpu == 0 ? -EPERM : 0;
}
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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/init.h>
#include <asm/page.h>
#include <asm/sizes.h>
#include <asm/mach/map.h>
#include <mach/hardware.h>
static struct map_desc imx_lluart_desc = {
#ifdef CONFIG_DEBUG_IMX6Q_UART
.virtual = MX6Q_IO_P2V(MX6Q_UART4_BASE_ADDR),
.pfn = __phys_to_pfn(MX6Q_UART4_BASE_ADDR),
.length = MX6Q_UART4_SIZE,
.type = MT_DEVICE,
#endif
};
void __init imx_lluart_map_io(void)
{
if (imx_lluart_desc.virtual)
iotable_init(&imx_lluart_desc, 1);
}
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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/init.h>
#include <linux/clockchips.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <asm/smp_twd.h>
/*
* Setup the local clock events for a CPU.
*/
int __cpuinit local_timer_setup(struct clock_event_device *evt)
{
struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "arm,smp-twd");
if (!twd_base) {
twd_base = of_iomap(np, 0);
WARN_ON(!twd_base);
}
evt->irq = irq_of_parse_and_map(np, 0);
twd_timer_setup(evt);
return 0;
}
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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/init.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/gic.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <mach/common.h>
#include <mach/hardware.h>
static void __init imx6q_init_machine(void)
{
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
imx6q_pm_init();
}
static void __init imx6q_map_io(void)
{
imx_lluart_map_io();
imx_scu_map_io();
}
static void __init imx6q_gpio_add_irq_domain(struct device_node *np,
struct device_node *interrupt_parent)
{
static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS -
32 * 7; /* imx6q gets 7 gpio ports */
irq_domain_add_simple(np, gpio_irq_base);
gpio_irq_base += 32;
}
static const struct of_device_id imx6q_irq_match[] __initconst = {
{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
{ .compatible = "fsl,imx6q-gpio", .data = imx6q_gpio_add_irq_domain, },
{ /* sentinel */ }
};
static void __init imx6q_init_irq(void)
{
l2x0_of_init(0, ~0UL);
imx_src_init();
imx_gpc_init();
of_irq_init(imx6q_irq_match);
}
static void __init imx6q_timer_init(void)
{
mx6q_clocks_init();
}
static struct sys_timer imx6q_timer = {
.init = imx6q_timer_init,
};
static const char *imx6q_dt_compat[] __initdata = {
"fsl,imx6q-sabreauto",
NULL,
};
DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)")
.map_io = imx6q_map_io,
.init_irq = imx6q_init_irq,
.handle_irq = imx6q_handle_irq,
.timer = &imx6q_timer,
.init_machine = imx6q_init_machine,
.dt_compat = imx6q_dt_compat,
MACHINE_END
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#define MMDC_MAPSR 0x404
#define BP_MMDC_MAPSR_PSD 0
#define BP_MMDC_MAPSR_PSS 4
static int __devinit imx_mmdc_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
void __iomem *mmdc_base, *reg;
u32 val;
int timeout = 0x400;
mmdc_base = of_iomap(np, 0);
WARN_ON(!mmdc_base);
reg = mmdc_base + MMDC_MAPSR;
/* Enable automatic power saving */
val = readl_relaxed(reg);
val &= ~(1 << BP_MMDC_MAPSR_PSD);
writel_relaxed(val, reg);
/* Ensure it's successfully enabled */
while (!(readl_relaxed(reg) & 1 << BP_MMDC_MAPSR_PSS) && --timeout)
cpu_relax();
if (unlikely(!timeout)) {
pr_warn("%s: failed to enable automatic power saving\n",
__func__);
return -EBUSY;
}
return 0;
}
static struct of_device_id imx_mmdc_dt_ids[] = {
{ .compatible = "fsl,imx6q-mmdc", },
{ /* sentinel */ }
};
static struct platform_driver imx_mmdc_driver = {
.driver = {
.name = "imx-mmdc",
.owner = THIS_MODULE,
.of_match_table = imx_mmdc_dt_ids,
},
.probe = imx_mmdc_probe,
};
static int __init imx_mmdc_init(void)
{
return platform_driver_register(&imx_mmdc_driver);
}
postcore_initcall(imx_mmdc_init);
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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/init.h>
#include <linux/smp.h>
#include <asm/page.h>
#include <asm/smp_scu.h>
#include <asm/hardware/gic.h>
#include <asm/mach/map.h>
#include <mach/common.h>
#include <mach/hardware.h>
static void __iomem *scu_base;
static struct map_desc scu_io_desc __initdata = {
/* .virtual and .pfn are run-time assigned */
.length = SZ_4K,
.type = MT_DEVICE,
};
void __init imx_scu_map_io(void)
{
unsigned long base;
/* Get SCU base */
asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
scu_io_desc.virtual = IMX_IO_P2V(base);
scu_io_desc.pfn = __phys_to_pfn(base);
iotable_init(&scu_io_desc, 1);
scu_base = IMX_IO_ADDRESS(base);
}
void __cpuinit platform_secondary_init(unsigned int cpu)
{
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
gic_secondary_init(0);
}
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
imx_set_cpu_jump(cpu, v7_secondary_startup);
imx_enable_cpu(cpu, true);
return 0;
}
/*
* Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system.
*/
void __init smp_init_cpus(void)
{
int i, ncores;
ncores = scu_get_core_count(scu_base);
for (i = 0; i < ncores; i++)
set_cpu_possible(i, true);
set_smp_cross_call(gic_raise_softirq);
}
void imx_smp_prepare(void)
{
scu_enable(scu_base);
}
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
imx_smp_prepare();
}
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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/init.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/suspend.h>
#include <asm/cacheflush.h>
#include <asm/proc-fns.h>
#include <asm/suspend.h>
#include <asm/hardware/cache-l2x0.h>
#include <mach/common.h>
#include <mach/hardware.h>
extern unsigned long phys_l2x0_saved_regs;
static int imx6q_suspend_finish(unsigned long val)
{
cpu_do_idle();
return 0;
}
static int imx6q_pm_enter(suspend_state_t state)
{
switch (state) {
case PM_SUSPEND_MEM:
imx6q_set_lpm(STOP_POWER_OFF);
imx_gpc_pre_suspend();
imx_set_cpu_jump(0, v7_cpu_resume);
/* Zzz ... */
cpu_suspend(0, imx6q_suspend_finish);
imx_smp_prepare();
imx_gpc_post_resume();
break;
default:
return -EINVAL;
}
return 0;
}
static const struct platform_suspend_ops imx6q_pm_ops = {
.enter = imx6q_pm_enter,
.valid = suspend_valid_only_mem,
};
void __init imx6q_pm_init(void)
{
/*
* The l2x0 core code provides an infrastucture to save and restore
* l2x0 registers across suspend/resume cycle. But because imx6q
* retains L2 content during suspend and needs to resume L2 before
* MMU is enabled, it can only utilize register saving support and
* have to take care of restoring on its own. So we save physical
* address of the data structure used by l2x0 core to save registers,
* and later restore the necessary ones in imx6q resume entry.
*/
phys_l2x0_saved_regs = __pa(&l2x0_saved_regs);
suspend_set_ops(&imx6q_pm_ops);
}
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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/init.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <asm/unified.h>
#define SRC_SCR 0x000
#define SRC_GPR1 0x020
#define BP_SRC_SCR_CORE1_RST 14
#define BP_SRC_SCR_CORE1_ENABLE 22
static void __iomem *src_base;
void imx_enable_cpu(int cpu, bool enable)
{
u32 mask, val;
mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
val = readl_relaxed(src_base + SRC_SCR);
val = enable ? val | mask : val & ~mask;
writel_relaxed(val, src_base + SRC_SCR);
}
void imx_set_cpu_jump(int cpu, void *jump_addr)
{
writel_relaxed(BSYM(virt_to_phys(jump_addr)),
src_base + SRC_GPR1 + cpu * 8);
}
void __init imx_src_init(void)
{
struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src");
src_base = of_iomap(np, 0);
WARN_ON(!src_base);
}
...@@ -14,17 +14,9 @@ ...@@ -14,17 +14,9 @@
#include <mach/mx23.h> #include <mach/mx23.h>
#include <mach/mx28.h> #include <mach/mx28.h>
#ifdef CONFIG_SOC_IMX23 #ifdef CONFIG_DEBUG_IMX23_UART
#ifdef UART_PADDR
#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
#endif
#define UART_PADDR MX23_DUART_BASE_ADDR #define UART_PADDR MX23_DUART_BASE_ADDR
#endif #elif defined (CONFIG_DEBUG_IMX28_UART)
#ifdef CONFIG_SOC_IMX28
#ifdef UART_PADDR
#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
#endif
#define UART_PADDR MX28_DUART_BASE_ADDR #define UART_PADDR MX28_DUART_BASE_ADDR
#endif #endif
......
...@@ -10,23 +10,10 @@ ...@@ -10,23 +10,10 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#if defined(CONFIG_MACH_REALVIEW_EB) || \ #ifdef CONFIG_DEBUG_REALVIEW_STD_PORT
defined(CONFIG_MACH_REALVIEW_PB11MP) || \
defined(CONFIG_MACH_REALVIEW_PBA8) || \
defined(CONFIG_MACH_REALVIEW_PBX)
#ifndef DEBUG_LL_UART_OFFSET
#define DEBUG_LL_UART_OFFSET 0x00009000 #define DEBUG_LL_UART_OFFSET 0x00009000
#elif DEBUG_LL_UART_OFFSET != 0x00009000 #elif defined(CONFIG_DEBUG_REALVIEW_PB1176_PORT)
#warning "DEBUG_LL_UART_OFFSET already defined to a different value"
#endif
#endif
#ifdef CONFIG_MACH_REALVIEW_PB1176
#ifndef DEBUG_LL_UART_OFFSET
#define DEBUG_LL_UART_OFFSET 0x0010c000 #define DEBUG_LL_UART_OFFSET 0x0010c000
#elif DEBUG_LL_UART_OFFSET != 0x0010c000
#warning "DEBUG_LL_UART_OFFSET already defined to a different value"
#endif
#endif #endif
#ifndef DEBUG_LL_UART_OFFSET #ifndef DEBUG_LL_UART_OFFSET
......
...@@ -819,7 +819,7 @@ config CACHE_FEROCEON_L2_WRITETHROUGH ...@@ -819,7 +819,7 @@ config CACHE_FEROCEON_L2_WRITETHROUGH
config CACHE_L2X0 config CACHE_L2X0
bool "Enable the L2x0 outer cache controller" bool "Enable the L2x0 outer cache controller"
depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
REALVIEW_EB_A9MP || SOC_IMX35 || SOC_IMX31 || MACH_REALVIEW_PBX || \ REALVIEW_EB_A9MP || ARCH_IMX_V6_V7 || MACH_REALVIEW_PBX || \
ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \ ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \
ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || \ ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || \
ARCH_PRIMA2 || ARCH_ZYNQ || ARCH_CNS3XXX || ARCH_HIGHBANK ARCH_PRIMA2 || ARCH_ZYNQ || ARCH_CNS3XXX || ARCH_HIGHBANK
......
...@@ -6,7 +6,7 @@ menu "Freescale MXC Implementations" ...@@ -6,7 +6,7 @@ menu "Freescale MXC Implementations"
choice choice
prompt "Freescale CPU family:" prompt "Freescale CPU family:"
default ARCH_MX3 default ARCH_IMX_V6_V7
config ARCH_IMX_V4_V5 config ARCH_IMX_V4_V5
bool "i.MX1, i.MX21, i.MX25, i.MX27" bool "i.MX1, i.MX21, i.MX25, i.MX27"
...@@ -16,10 +16,13 @@ config ARCH_IMX_V4_V5 ...@@ -16,10 +16,13 @@ config ARCH_IMX_V4_V5
This enables support for systems based on the Freescale i.MX ARMv4 This enables support for systems based on the Freescale i.MX ARMv4
and ARMv5 SoCs and ARMv5 SoCs
config ARCH_MX3 config ARCH_IMX_V6_V7
bool "MX3-based" bool "i.MX3, i.MX6"
select AUTO_ZRELADDR if !ZBOOT_ROM
select ARM_PATCH_PHYS_VIRT
help help
This enables support for systems based on the Freescale i.MX3 family This enables support for systems based on the Freescale i.MX3 and i.MX6
family.
config ARCH_MX5 config ARCH_MX5
bool "i.MX50, i.MX51, i.MX53" bool "i.MX50, i.MX51, i.MX53"
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# Common support # Common support
obj-y := clock.o time.o devices.o cpu.o system.o irq-common.o obj-y := clock.o time.o devices.o cpu.o system.o irq-common.o
# MX51 uses the TZIC interrupt controller, older platforms use AVIC obj-$(CONFIG_ARM_GIC) += gic.o
obj-$(CONFIG_MXC_TZIC) += tzic.o obj-$(CONFIG_MXC_TZIC) += tzic.o
obj-$(CONFIG_MXC_AVIC) += avic.o obj-$(CONFIG_MXC_AVIC) += avic.o
......
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* 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/io.h>
#include <asm/exception.h>
#include <asm/localtimer.h>
#include <asm/hardware/gic.h>
#ifdef CONFIG_SMP
#include <asm/smp.h>
#endif
asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
{
u32 irqstat, irqnr;
do {
irqstat = readl_relaxed(gic_cpu_base_addr + GIC_CPU_INTACK);
irqnr = irqstat & 0x3ff;
if (irqnr == 1023)
break;
if (irqnr > 29 && irqnr < 1021)
handle_IRQ(irqnr, regs);
#ifdef CONFIG_SMP
else if (irqnr < 16) {
writel_relaxed(irqstat, gic_cpu_base_addr +
GIC_CPU_EOI);
handle_IPI(irqnr, regs);
}
#endif
#ifdef CONFIG_LOCAL_TIMERS
else if (irqnr == 29) {
writel_relaxed(irqstat, gic_cpu_base_addr +
GIC_CPU_EOI);
handle_local_timer(regs);
}
#endif
} while (1);
}
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
struct platform_device; struct platform_device;
struct clk; struct clk;
enum mxc_cpu_pwr_mode;
extern void mx1_map_io(void); extern void mx1_map_io(void);
extern void mx21_map_io(void); extern void mx21_map_io(void);
...@@ -66,6 +67,7 @@ extern int mx53_clocks_init(unsigned long ckil, unsigned long osc, ...@@ -66,6 +67,7 @@ extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
unsigned long ckih1, unsigned long ckih2); unsigned long ckih1, unsigned long ckih2);
extern int mx51_clocks_init_dt(void); extern int mx51_clocks_init_dt(void);
extern int mx53_clocks_init_dt(void); extern int mx53_clocks_init_dt(void);
extern int mx6q_clocks_init(void);
extern struct platform_device *mxc_register_gpio(char *name, int id, extern struct platform_device *mxc_register_gpio(char *name, int id,
resource_size_t iobase, resource_size_t iosize, int irq, int irq_high); resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
extern void mxc_set_cpu_type(unsigned int type); extern void mxc_set_cpu_type(unsigned int type);
...@@ -88,6 +90,7 @@ extern void imx_print_silicon_rev(const char *cpu, int srev); ...@@ -88,6 +90,7 @@ extern void imx_print_silicon_rev(const char *cpu, int srev);
void avic_handle_irq(struct pt_regs *); void avic_handle_irq(struct pt_regs *);
void tzic_handle_irq(struct pt_regs *); void tzic_handle_irq(struct pt_regs *);
void gic_handle_irq(struct pt_regs *);
#define imx1_handle_irq avic_handle_irq #define imx1_handle_irq avic_handle_irq
#define imx21_handle_irq avic_handle_irq #define imx21_handle_irq avic_handle_irq
...@@ -98,10 +101,36 @@ void tzic_handle_irq(struct pt_regs *); ...@@ -98,10 +101,36 @@ void tzic_handle_irq(struct pt_regs *);
#define imx50_handle_irq tzic_handle_irq #define imx50_handle_irq tzic_handle_irq
#define imx51_handle_irq tzic_handle_irq #define imx51_handle_irq tzic_handle_irq
#define imx53_handle_irq tzic_handle_irq #define imx53_handle_irq tzic_handle_irq
#define imx6q_handle_irq gic_handle_irq
extern void imx_enable_cpu(int cpu, bool enable);
extern void imx_set_cpu_jump(int cpu, void *jump_addr);
#ifdef CONFIG_DEBUG_LL
extern void imx_lluart_map_io(void);
#else
static inline void imx_lluart_map_io(void) {}
#endif
extern void v7_cpu_resume(void);
extern u32 *pl310_get_save_ptr(void);
#ifdef CONFIG_SMP
extern void v7_secondary_startup(void);
extern void imx_scu_map_io(void);
extern void imx_smp_prepare(void);
#else
static inline void imx_scu_map_io(void) {}
static inline void imx_smp_prepare(void) {}
#endif
extern void imx_enable_cpu(int cpu, bool enable);
extern void imx_set_cpu_jump(int cpu, void *jump_addr);
extern void imx_src_init(void);
extern void imx_gpc_init(void);
extern void imx_gpc_pre_suspend(void);
extern void imx_gpc_post_resume(void);
extern void imx51_babbage_common_init(void); extern void imx51_babbage_common_init(void);
extern void imx53_ard_common_init(void); extern void imx53_ard_common_init(void);
extern void imx53_evk_common_init(void); extern void imx53_evk_common_init(void);
extern void imx53_qsb_common_init(void); extern void imx53_qsb_common_init(void);
extern void imx53_smd_common_init(void); extern void imx53_smd_common_init(void);
extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
extern void imx6q_pm_init(void);
#endif #endif
...@@ -12,44 +12,20 @@ ...@@ -12,44 +12,20 @@
*/ */
#include <mach/hardware.h> #include <mach/hardware.h>
#ifdef CONFIG_SOC_IMX1 #ifdef CONFIG_DEBUG_IMX1_UART
#define UART_PADDR MX1_UART1_BASE_ADDR #define UART_PADDR MX1_UART1_BASE_ADDR
#endif #elif defined (CONFIG_DEBUG_IMX25_UART)
#ifdef CONFIG_SOC_IMX25
#ifdef UART_PADDR
#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
#endif
#define UART_PADDR MX25_UART1_BASE_ADDR #define UART_PADDR MX25_UART1_BASE_ADDR
#endif #elif defined (CONFIG_DEBUG_IMX21_IMX27_UART)
#if defined(CONFIG_SOC_IMX21) || defined (CONFIG_SOC_IMX27)
#ifdef UART_PADDR
#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
#endif
#define UART_PADDR MX2x_UART1_BASE_ADDR #define UART_PADDR MX2x_UART1_BASE_ADDR
#endif #elif defined (CONFIG_DEBUG_IMX31_IMX35_UART)
#if defined(CONFIG_SOC_IMX31) || defined(CONFIG_SOC_IMX35)
#ifdef UART_PADDR
#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
#endif
#define UART_PADDR MX3x_UART1_BASE_ADDR #define UART_PADDR MX3x_UART1_BASE_ADDR
#endif #elif defined (CONFIG_DEBUG_IMX51_UART)
#ifdef CONFIG_SOC_IMX51
#ifdef UART_PADDR
#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
#endif
#define UART_PADDR MX51_UART1_BASE_ADDR #define UART_PADDR MX51_UART1_BASE_ADDR
#endif #elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
/* iMX50/53 have same addresses, but not iMX51 */
#if defined(CONFIG_SOC_IMX50) || defined(CONFIG_SOC_IMX53)
#ifdef UART_PADDR
#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
#endif
#define UART_PADDR MX53_UART1_BASE_ADDR #define UART_PADDR MX53_UART1_BASE_ADDR
#elif defined (CONFIG_DEBUG_IMX6Q_UART)
#define UART_PADDR MX6Q_UART4_BASE_ADDR
#endif #endif
#define UART_VADDR IMX_IO_ADDRESS(UART_PADDR) #define UART_VADDR IMX_IO_ADDRESS(UART_PADDR)
......
...@@ -22,3 +22,9 @@ ...@@ -22,3 +22,9 @@
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
.endm .endm
.macro test_for_ipi, irqnr, irqstat, base, tmp
.endm
.macro test_for_ltirq, irqnr, irqstat, base, tmp
.endm
...@@ -91,6 +91,11 @@ ...@@ -91,6 +91,11 @@
* SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
* AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000 * AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000
* AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000 * AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000
* mx6q:
* SCU 0x00a00000+0x001000 -> 0xf4000000+0x001000
* CCM 0x020c4000+0x004000 -> 0xf42c4000+0x004000
* ANATOP 0x020c8000+0x001000 -> 0xf42c8000+0x001000
* UART4 0x021f0000+0x004000 -> 0xf42f0000+0x004000
*/ */
#define IMX_IO_P2V(x) ( \ #define IMX_IO_P2V(x) ( \
0xf4000000 + \ 0xf4000000 + \
...@@ -102,6 +107,7 @@ ...@@ -102,6 +107,7 @@
#include <mach/mxc.h> #include <mach/mxc.h>
#include <mach/mx6q.h>
#include <mach/mx50.h> #include <mach/mx50.h>
#include <mach/mx51.h> #include <mach/mx51.h>
#include <mach/mx53.h> #include <mach/mx53.h>
......
...@@ -14,9 +14,15 @@ ...@@ -14,9 +14,15 @@
#include <asm-generic/gpio.h> #include <asm-generic/gpio.h>
/* /*
* SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64 * SoCs with GIC interrupt controller have 160 IRQs, those with TZIC
* have 128 IRQs, and those with AVIC have 64.
*
* To support single image, the biggest number should be defined on
* top of the list.
*/ */
#ifdef CONFIG_MXC_TZIC #if defined CONFIG_ARM_GIC
#define MXC_INTERNAL_IRQS 160
#elif defined CONFIG_MXC_TZIC
#define MXC_INTERNAL_IRQS 128 #define MXC_INTERNAL_IRQS 128
#else #else
#define MXC_INTERNAL_IRQS 64 #define MXC_INTERNAL_IRQS 64
......
/*
* Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2011 Linaro Ltd.
*
* 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
*/
#ifndef __MACH_MX6Q_H__
#define __MACH_MX6Q_H__
#define MX6Q_IO_P2V(x) IMX_IO_P2V(x)
#define MX6Q_IO_ADDRESS(x) IOMEM(MX6Q_IO_P2V(x))
/*
* The following are the blocks that need to be statically mapped.
* For other blocks, the base address really should be retrieved from
* device tree.
*/
#define MX6Q_SCU_BASE_ADDR 0x00a00000
#define MX6Q_SCU_SIZE 0x1000
#define MX6Q_CCM_BASE_ADDR 0x020c4000
#define MX6Q_CCM_SIZE 0x4000
#define MX6Q_ANATOP_BASE_ADDR 0x020c8000
#define MX6Q_ANATOP_SIZE 0x1000
#define MX6Q_UART4_BASE_ADDR 0x021f0000
#define MX6Q_UART4_SIZE 0x4000
#endif /* __MACH_MX6Q_H__ */
...@@ -367,4 +367,11 @@ config SAMSUNG_PD ...@@ -367,4 +367,11 @@ config SAMSUNG_PD
help help
Say Y here if you want to control Power Domain by Runtime PM. Say Y here if you want to control Power Domain by Runtime PM.
config DEBUG_S3C_UART
depends on PLAT_SAMSUNG
int
default "0" if DEBUG_S3C_UART0
default "1" if DEBUG_S3C_UART1
default "2" if DEBUG_S3C_UART2
endif endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment