aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-08 13:05:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-08 13:05:57 -0400
commit4fd6c6bf83cb16321e9902b00e2af79054f4e0d6 (patch)
tree7153f611af0125336ac0ec22c5cb430fe520edcc /arch/arm
parentc5f347579a661c9506e794315f0798b75ef71d35 (diff)
parent84b9414babdc303dde1d3f44cd2a54dffb67ab97 (diff)
Merge branch 'for-linus' of git://android.kernel.org/kernel/tegra
* 'for-linus' of git://android.kernel.org/kernel/tegra: [ARM] tegra: add MAINTAINERS entry [ARM] tegra: harmony: Add harmony board file [ARM] tegra: add pinmux support [ARM] tegra: add GPIO support [ARM] tegra: Add timer support [ARM] tegra: SMP support [ARM] tegra: Add clock support [ARM] tegra: Add IRQ support [ARM] tegra: initial tegra support
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig24
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/mach-tegra/Kconfig50
-rw-r--r--arch/arm/mach-tegra/Makefile14
-rw-r--r--arch/arm/mach-tegra/Makefile.boot3
-rw-r--r--arch/arm/mach-tegra/board-harmony-pinmux.c144
-rw-r--r--arch/arm/mach-tegra/board-harmony.c127
-rw-r--r--arch/arm/mach-tegra/board-harmony.h22
-rw-r--r--arch/arm/mach-tegra/board.h32
-rw-r--r--arch/arm/mach-tegra/clock.c488
-rw-r--r--arch/arm/mach-tegra/clock.h147
-rw-r--r--arch/arm/mach-tegra/common.c61
-rw-r--r--arch/arm/mach-tegra/gpio-names.h247
-rw-r--r--arch/arm/mach-tegra/gpio.c348
-rw-r--r--arch/arm/mach-tegra/headsmp.S61
-rw-r--r--arch/arm/mach-tegra/hotplug.c140
-rw-r--r--arch/arm/mach-tegra/include/mach/barriers.h30
-rw-r--r--arch/arm/mach-tegra/include/mach/clk.h26
-rw-r--r--arch/arm/mach-tegra/include/mach/clkdev.h32
-rw-r--r--arch/arm/mach-tegra/include/mach/debug-macro.S46
-rw-r--r--arch/arm/mach-tegra/include/mach/entry-macro.S118
-rw-r--r--arch/arm/mach-tegra/include/mach/gpio.h53
-rw-r--r--arch/arm/mach-tegra/include/mach/hardware.h24
-rw-r--r--arch/arm/mach-tegra/include/mach/io.h79
-rw-r--r--arch/arm/mach-tegra/include/mach/iomap.h203
-rw-r--r--arch/arm/mach-tegra/include/mach/irqs.h173
-rw-r--r--arch/arm/mach-tegra/include/mach/memory.h28
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux.h348
-rw-r--r--arch/arm/mach-tegra/include/mach/smp.h30
-rw-r--r--arch/arm/mach-tegra/include/mach/system.h39
-rw-r--r--arch/arm/mach-tegra/include/mach/timex.h26
-rw-r--r--arch/arm/mach-tegra/include/mach/uncompress.h78
-rw-r--r--arch/arm/mach-tegra/include/mach/vmalloc.h28
-rw-r--r--arch/arm/mach-tegra/io.c78
-rw-r--r--arch/arm/mach-tegra/irq.c34
-rw-r--r--arch/arm/mach-tegra/localtimer.c25
-rw-r--r--arch/arm/mach-tegra/pinmux.c945
-rw-r--r--arch/arm/mach-tegra/platsmp.c156
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c1359
-rw-r--r--arch/arm/mach-tegra/timer.c187
-rw-r--r--arch/arm/mm/Kconfig3
41 files changed, 6052 insertions, 5 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9e10882c81d7..232f0c758252 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -558,6 +558,18 @@ config ARCH_NUC93X
558 Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a 558 Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a
559 low-power and high performance MPEG-4/JPEG multimedia controller chip. 559 low-power and high performance MPEG-4/JPEG multimedia controller chip.
560 560
561config ARCH_TEGRA
562 bool "NVIDIA Tegra"
563 select GENERIC_TIME
564 select GENERIC_CLOCKEVENTS
565 select GENERIC_GPIO
566 select HAVE_CLK
567 select COMMON_CLKDEV
568 select ARCH_HAS_BARRIERS if CACHE_L2X0
569 help
570 This enables support for NVIDIA Tegra based systems (Tegra APX,
571 Tegra 6xx and Tegra 2 series).
572
561config ARCH_PNX4008 573config ARCH_PNX4008
562 bool "Philips Nexperia PNX4008 Mobile" 574 bool "Philips Nexperia PNX4008 Mobile"
563 select CPU_ARM926T 575 select CPU_ARM926T
@@ -907,6 +919,8 @@ source "arch/arm/mach-shmobile/Kconfig"
907 919
908source "arch/arm/plat-stmp3xxx/Kconfig" 920source "arch/arm/plat-stmp3xxx/Kconfig"
909 921
922source "arch/arm/mach-tegra/Kconfig"
923
910source "arch/arm/mach-u300/Kconfig" 924source "arch/arm/mach-u300/Kconfig"
911 925
912source "arch/arm/mach-ux500/Kconfig" 926source "arch/arm/mach-ux500/Kconfig"
@@ -1094,10 +1108,11 @@ config SMP
1094 bool "Symmetric Multi-Processing (EXPERIMENTAL)" 1108 bool "Symmetric Multi-Processing (EXPERIMENTAL)"
1095 depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\ 1109 depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
1096 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\ 1110 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
1097 ARCH_U8500 || ARCH_VEXPRESS_CA9X4) 1111 ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_TEGRA)
1098 depends on GENERIC_CLOCKEVENTS 1112 depends on GENERIC_CLOCKEVENTS
1099 select USE_GENERIC_SMP_HELPERS 1113 select USE_GENERIC_SMP_HELPERS
1100 select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4) 1114 select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || \
1115 ARCH_VEXPRESS_CA9X4 || ARCH_TEGRA)
1101 help 1116 help
1102 This enables support for systems with more than one CPU. If you have 1117 This enables support for systems with more than one CPU. If you have
1103 a system with only one CPU, like most personal computers, say N. If 1118 a system with only one CPU, like most personal computers, say N. If
@@ -1167,9 +1182,10 @@ config LOCAL_TIMERS
1167 bool "Use local timer interrupts" 1182 bool "Use local timer interrupts"
1168 depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \ 1183 depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \
1169 REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ 1184 REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
1170 ARCH_U8500 || ARCH_VEXPRESS_CA9X4) 1185 ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_TEGRA)
1171 default y 1186 default y
1172 select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_VEXPRESS || ARCH_OMAP4 || ARCH_U8500) 1187 select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_VEXPRESS || ARCH_OMAP4 || \\
1188 ARCH_U8500 || ARCH_TEGRA
1173 help 1189 help
1174 Enable support for local timers on SMP platforms, rather then the 1190 Enable support for local timers on SMP platforms, rather then the
1175 legacy IPI broadcast method. Local timers allows the system 1191 legacy IPI broadcast method. Local timers allows the system
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 63d998e8c672..a8d4dca9da35 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -179,6 +179,7 @@ machine-$(CONFIG_ARCH_SHARK) := shark
179machine-$(CONFIG_ARCH_SHMOBILE) := shmobile 179machine-$(CONFIG_ARCH_SHMOBILE) := shmobile
180machine-$(CONFIG_ARCH_STMP378X) := stmp378x 180machine-$(CONFIG_ARCH_STMP378X) := stmp378x
181machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx 181machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx
182machine-$(CONFIG_ARCH_TEGRA) := tegra
182machine-$(CONFIG_ARCH_U300) := u300 183machine-$(CONFIG_ARCH_U300) := u300
183machine-$(CONFIG_ARCH_U8500) := ux500 184machine-$(CONFIG_ARCH_U8500) := ux500
184machine-$(CONFIG_ARCH_VERSATILE) := versatile 185machine-$(CONFIG_ARCH_VERSATILE) := versatile
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
new file mode 100644
index 000000000000..a57713c1954a
--- /dev/null
+++ b/arch/arm/mach-tegra/Kconfig
@@ -0,0 +1,50 @@
1if ARCH_TEGRA
2
3comment "NVIDIA Tegra options"
4
5choice
6 prompt "Select Tegra processor family for target system"
7
8config ARCH_TEGRA_2x_SOC
9 bool "Tegra 2 family"
10 select CPU_V7
11 select ARM_GIC
12 select ARCH_REQUIRE_GPIOLIB
13 help
14 Support for NVIDIA Tegra AP20 and T20 processors, based on the
15 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
16
17endchoice
18
19comment "Tegra board type"
20
21config MACH_HARMONY
22 bool "Harmony board"
23 help
24 Support for nVidia Harmony development platform
25
26choice
27 prompt "Low-level debug console UART"
28 default TEGRA_DEBUG_UART_NONE
29
30config TEGRA_DEBUG_UART_NONE
31 bool "None"
32
33config TEGRA_DEBUG_UARTA
34 bool "UART-A"
35
36config TEGRA_DEBUG_UARTB
37 bool "UART-B"
38
39config TEGRA_DEBUG_UARTC
40 bool "UART-C"
41
42config TEGRA_DEBUG_UARTD
43 bool "UART-D"
44
45config TEGRA_DEBUG_UARTE
46 bool "UART-E"
47
48endchoice
49
50endif
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
new file mode 100644
index 000000000000..51e9370eed99
--- /dev/null
+++ b/arch/arm/mach-tegra/Makefile
@@ -0,0 +1,14 @@
1obj-y += common.o
2obj-y += io.o
3obj-y += irq.o
4obj-y += clock.o
5obj-y += timer.o
6obj-y += gpio.o
7obj-y += pinmux.o
8obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o
9obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o
10obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o
11obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
12
13obj-${CONFIG_MACH_HARMONY} += board-harmony.o
14obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o
diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot
new file mode 100644
index 000000000000..db52d61a7386
--- /dev/null
+++ b/arch/arm/mach-tegra/Makefile.boot
@@ -0,0 +1,3 @@
1zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00008000
2params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100
3initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000
diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c
new file mode 100644
index 000000000000..50b15d500cac
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony-pinmux.c
@@ -0,0 +1,144 @@
1/*
2 * arch/arm/mach-tegra/board-harmony-pinmux.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <mach/pinmux.h>
19
20#include "board-harmony.h"
21
22static struct tegra_pingroup_config harmony_pinmux[] = {
23 {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
24 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
25 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
26 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
27 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
28 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_OSC, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
29 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
30 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
31 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
32 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
33 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
34 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
35 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
36 {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
37 {TEGRA_PINGROUP_DTA, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
38 {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
39 {TEGRA_PINGROUP_DTC, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
40 {TEGRA_PINGROUP_DTD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
41 {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
42 {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
43 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
44 {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
45 {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
46 {TEGRA_PINGROUP_GMD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
47 {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
48 {TEGRA_PINGROUP_GPU, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
49 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
50 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
51 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
52 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
53 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
54 {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
55 {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
56 {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
57 {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
58 {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
59 {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
60 {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
61 {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
62 {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
63 {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
64 {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
65 {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
66 {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
67 {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
68 {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
69 {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
70 {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
71 {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
72 {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
73 {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
74 {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
75 {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
76 {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
77 {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
78 {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
79 {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
80 {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
81 {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
82 {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
83 {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
84 {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
85 {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
86 {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
87 {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
88 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
89 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
90 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
91 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
92 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
93 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
94 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
95 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
96 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
97 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
98 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
99 {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
100 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
101 {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
102 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
103 {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
104 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
105 {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
106 {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
107 {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
108 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
109 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
110 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
111 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
112 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
113 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
114 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
115 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
116 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
117 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
118 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
119 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
120 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
121 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
122 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
123 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
124 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
125 {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
126 {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
127 {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
128 {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
129 {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
130 {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
131 {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
132 {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
133 {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
134 {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
135 {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
136 {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
137 {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
138 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
139};
140
141void harmony_pinmux_init(void)
142{
143 tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux));
144}
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
new file mode 100644
index 000000000000..05e78dd9b50c
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -0,0 +1,127 @@
1/*
2 * arch/arm/mach-tegra/board-harmony.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/platform_device.h>
20#include <linux/serial_8250.h>
21#include <linux/clk.h>
22#include <linux/dma-mapping.h>
23#include <linux/pda_power.h>
24#include <linux/io.h>
25
26#include <asm/mach-types.h>
27#include <asm/mach/arch.h>
28#include <asm/mach/time.h>
29#include <asm/setup.h>
30
31#include <mach/iomap.h>
32#include <mach/irqs.h>
33
34#include "board.h"
35#include "board-harmony.h"
36#include "clock.h"
37
38/* NVidia bootloader tags */
39#define ATAG_NVIDIA 0x41000801
40
41#define ATAG_NVIDIA_RM 0x1
42#define ATAG_NVIDIA_DISPLAY 0x2
43#define ATAG_NVIDIA_FRAMEBUFFER 0x3
44#define ATAG_NVIDIA_CHIPSHMOO 0x4
45#define ATAG_NVIDIA_CHIPSHMOOPHYS 0x5
46#define ATAG_NVIDIA_PRESERVED_MEM_0 0x10000
47#define ATAG_NVIDIA_PRESERVED_MEM_N 2
48#define ATAG_NVIDIA_FORCE_32 0x7fffffff
49
50struct tag_tegra {
51 __u32 bootarg_key;
52 __u32 bootarg_len;
53 char bootarg[1];
54};
55
56static int __init parse_tag_nvidia(const struct tag *tag)
57{
58
59 return 0;
60}
61__tagtable(ATAG_NVIDIA, parse_tag_nvidia);
62
63static struct plat_serial8250_port debug_uart_platform_data[] = {
64 {
65 .membase = IO_ADDRESS(TEGRA_UARTD_BASE),
66 .mapbase = TEGRA_UARTD_BASE,
67 .irq = INT_UARTD,
68 .flags = UPF_BOOT_AUTOCONF,
69 .iotype = UPIO_MEM,
70 .regshift = 2,
71 .uartclk = 216000000,
72 }, {
73 .flags = 0
74 }
75};
76
77static struct platform_device debug_uart = {
78 .name = "serial8250",
79 .id = PLAT8250_DEV_PLATFORM,
80 .dev = {
81 .platform_data = debug_uart_platform_data,
82 },
83};
84
85static struct platform_device *harmony_devices[] __initdata = {
86 &debug_uart,
87};
88
89static void __init tegra_harmony_fixup(struct machine_desc *desc,
90 struct tag *tags, char **cmdline, struct meminfo *mi)
91{
92 mi->nr_banks = 2;
93 mi->bank[0].start = PHYS_OFFSET;
94 mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
95 mi->bank[0].size = 448 * SZ_1M;
96 mi->bank[1].start = SZ_512M;
97 mi->bank[1].node = PHYS_TO_NID(SZ_512M);
98 mi->bank[1].size = SZ_512M;
99}
100
101static __initdata struct tegra_clk_init_table harmony_clk_init_table[] = {
102 /* name parent rate enabled */
103 { "uartd", "pll_p", 216000000, true },
104 { NULL, NULL, 0, 0},
105};
106
107static void __init tegra_harmony_init(void)
108{
109 tegra_common_init();
110
111 tegra_clk_init_from_table(harmony_clk_init_table);
112
113 harmony_pinmux_init();
114
115 platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices));
116}
117
118MACHINE_START(HARMONY, "harmony")
119 .boot_params = 0x00000100,
120 .phys_io = IO_APB_PHYS,
121 .io_pg_offst = ((IO_APB_VIRT) >> 18) & 0xfffc,
122 .fixup = tegra_harmony_fixup,
123 .init_irq = tegra_init_irq,
124 .init_machine = tegra_harmony_init,
125 .map_io = tegra_map_common_io,
126 .timer = &tegra_timer,
127MACHINE_END
diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h
new file mode 100644
index 000000000000..09ca7755dd55
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony.h
@@ -0,0 +1,22 @@
1/*
2 * arch/arm/mach-tegra/board-harmony.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef _MACH_TEGRA_BOARD_HARMONY_H
18#define _MACH_TEGRA_BOARD_HARMONY_H
19
20void harmony_pinmux_init(void);
21
22#endif
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
new file mode 100644
index 000000000000..3d06354136f2
--- /dev/null
+++ b/arch/arm/mach-tegra/board.h
@@ -0,0 +1,32 @@
1/*
2 * arch/arm/mach-tegra/board.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Erik Gilling <konkers@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#ifndef __MACH_TEGRA_BOARD_H
22#define __MACH_TEGRA_BOARD_H
23
24#include <linux/types.h>
25
26void __init tegra_common_init(void);
27void __init tegra_map_common_io(void);
28void __init tegra_init_irq(void);
29void __init tegra_init_clock(void);
30
31extern struct sys_timer tegra_timer;
32#endif
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
new file mode 100644
index 000000000000..03ad578349b9
--- /dev/null
+++ b/arch/arm/mach-tegra/clock.c
@@ -0,0 +1,488 @@
1/*
2 *
3 * Copyright (C) 2010 Google, Inc.
4 *
5 * Author:
6 * Colin Cross <ccross@google.com>
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/kernel.h>
20#include <linux/clk.h>
21#include <linux/list.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/debugfs.h>
25#include <linux/slab.h>
26#include <linux/seq_file.h>
27#include <asm/clkdev.h>
28
29#include "clock.h"
30
31static LIST_HEAD(clocks);
32
33static DEFINE_SPINLOCK(clock_lock);
34
35struct clk *tegra_get_clock_by_name(const char *name)
36{
37 struct clk *c;
38 struct clk *ret = NULL;
39 unsigned long flags;
40 spin_lock_irqsave(&clock_lock, flags);
41 list_for_each_entry(c, &clocks, node) {
42 if (strcmp(c->name, name) == 0) {
43 ret = c;
44 break;
45 }
46 }
47 spin_unlock_irqrestore(&clock_lock, flags);
48 return ret;
49}
50
51int clk_reparent(struct clk *c, struct clk *parent)
52{
53 pr_debug("%s: %s\n", __func__, c->name);
54 if (c->refcnt && c->parent)
55 clk_disable_locked(c->parent);
56 c->parent = parent;
57 if (c->refcnt && c->parent)
58 clk_enable_locked(c->parent);
59 list_del(&c->sibling);
60 list_add_tail(&c->sibling, &parent->children);
61 return 0;
62}
63
64static void propagate_rate(struct clk *c)
65{
66 struct clk *clkp;
67 pr_debug("%s: %s\n", __func__, c->name);
68 list_for_each_entry(clkp, &c->children, sibling) {
69 pr_debug(" %s\n", clkp->name);
70 if (clkp->ops->recalculate_rate)
71 clkp->ops->recalculate_rate(clkp);
72 propagate_rate(clkp);
73 }
74}
75
76void clk_init(struct clk *c)
77{
78 unsigned long flags;
79
80 spin_lock_irqsave(&clock_lock, flags);
81
82 INIT_LIST_HEAD(&c->children);
83 INIT_LIST_HEAD(&c->sibling);
84
85 if (c->ops && c->ops->init)
86 c->ops->init(c);
87
88 list_add(&c->node, &clocks);
89
90 if (c->parent)
91 list_add_tail(&c->sibling, &c->parent->children);
92
93 spin_unlock_irqrestore(&clock_lock, flags);
94}
95
96int clk_enable_locked(struct clk *c)
97{
98 int ret;
99 pr_debug("%s: %s\n", __func__, c->name);
100 if (c->refcnt == 0) {
101 if (c->parent) {
102 ret = clk_enable_locked(c->parent);
103 if (ret)
104 return ret;
105 }
106
107 if (c->ops && c->ops->enable) {
108 ret = c->ops->enable(c);
109 if (ret) {
110 if (c->parent)
111 clk_disable_locked(c->parent);
112 return ret;
113 }
114 c->state = ON;
115#ifdef CONFIG_DEBUG_FS
116 c->set = 1;
117#endif
118 }
119 }
120 c->refcnt++;
121
122 return 0;
123}
124
125int clk_enable(struct clk *c)
126{
127 int ret;
128 unsigned long flags;
129 spin_lock_irqsave(&clock_lock, flags);
130 ret = clk_enable_locked(c);
131 spin_unlock_irqrestore(&clock_lock, flags);
132 return ret;
133}
134EXPORT_SYMBOL(clk_enable);
135
136void clk_disable_locked(struct clk *c)
137{
138 pr_debug("%s: %s\n", __func__, c->name);
139 if (c->refcnt == 0) {
140 WARN(1, "Attempting to disable clock %s with refcnt 0", c->name);
141 return;
142 }
143 if (c->refcnt == 1) {
144 if (c->ops && c->ops->disable)
145 c->ops->disable(c);
146
147 if (c->parent)
148 clk_disable_locked(c->parent);
149
150 c->state = OFF;
151 }
152 c->refcnt--;
153}
154
155void clk_disable(struct clk *c)
156{
157 unsigned long flags;
158 spin_lock_irqsave(&clock_lock, flags);
159 clk_disable_locked(c);
160 spin_unlock_irqrestore(&clock_lock, flags);
161}
162EXPORT_SYMBOL(clk_disable);
163
164int clk_set_parent_locked(struct clk *c, struct clk *parent)
165{
166 int ret;
167
168 pr_debug("%s: %s\n", __func__, c->name);
169
170 if (!c->ops || !c->ops->set_parent)
171 return -ENOSYS;
172
173 ret = c->ops->set_parent(c, parent);
174
175 if (ret)
176 return ret;
177
178 propagate_rate(c);
179
180 return 0;
181}
182
183int clk_set_parent(struct clk *c, struct clk *parent)
184{
185 int ret;
186 unsigned long flags;
187 spin_lock_irqsave(&clock_lock, flags);
188 ret = clk_set_parent_locked(c, parent);
189 spin_unlock_irqrestore(&clock_lock, flags);
190 return ret;
191}
192EXPORT_SYMBOL(clk_set_parent);
193
194struct clk *clk_get_parent(struct clk *c)
195{
196 return c->parent;
197}
198EXPORT_SYMBOL(clk_get_parent);
199
200int clk_set_rate(struct clk *c, unsigned long rate)
201{
202 int ret = 0;
203 unsigned long flags;
204
205 spin_lock_irqsave(&clock_lock, flags);
206
207 pr_debug("%s: %s\n", __func__, c->name);
208
209 if (c->ops && c->ops->set_rate)
210 ret = c->ops->set_rate(c, rate);
211 else
212 ret = -ENOSYS;
213
214 propagate_rate(c);
215
216 spin_unlock_irqrestore(&clock_lock, flags);
217
218 return ret;
219}
220EXPORT_SYMBOL(clk_set_rate);
221
222unsigned long clk_get_rate(struct clk *c)
223{
224 unsigned long flags;
225 unsigned long ret;
226
227 spin_lock_irqsave(&clock_lock, flags);
228
229 pr_debug("%s: %s\n", __func__, c->name);
230
231 ret = c->rate;
232
233 spin_unlock_irqrestore(&clock_lock, flags);
234 return ret;
235}
236EXPORT_SYMBOL(clk_get_rate);
237
238static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table)
239{
240 struct clk *c;
241 struct clk *p;
242
243 int ret = 0;
244
245 c = tegra_get_clock_by_name(table->name);
246
247 if (!c) {
248 pr_warning("Unable to initialize clock %s\n",
249 table->name);
250 return -ENODEV;
251 }
252
253 if (table->parent) {
254 p = tegra_get_clock_by_name(table->parent);
255 if (!p) {
256 pr_warning("Unable to find parent %s of clock %s\n",
257 table->parent, table->name);
258 return -ENODEV;
259 }
260
261 if (c->parent != p) {
262 ret = clk_set_parent(c, p);
263 if (ret) {
264 pr_warning("Unable to set parent %s of clock %s: %d\n",
265 table->parent, table->name, ret);
266 return -EINVAL;
267 }
268 }
269 }
270
271 if (table->rate && table->rate != clk_get_rate(c)) {
272 ret = clk_set_rate(c, table->rate);
273 if (ret) {
274 pr_warning("Unable to set clock %s to rate %lu: %d\n",
275 table->name, table->rate, ret);
276 return -EINVAL;
277 }
278 }
279
280 if (table->enabled) {
281 ret = clk_enable(c);
282 if (ret) {
283 pr_warning("Unable to enable clock %s: %d\n",
284 table->name, ret);
285 return -EINVAL;
286 }
287 }
288
289 return 0;
290}
291
292void tegra_clk_init_from_table(struct tegra_clk_init_table *table)
293{
294 for (; table->name; table++)
295 tegra_clk_init_one_from_table(table);
296}
297EXPORT_SYMBOL(tegra_clk_init_from_table);
298
299void tegra_periph_reset_deassert(struct clk *c)
300{
301 tegra2_periph_reset_deassert(c);
302}
303EXPORT_SYMBOL(tegra_periph_reset_deassert);
304
305void tegra_periph_reset_assert(struct clk *c)
306{
307 tegra2_periph_reset_assert(c);
308}
309EXPORT_SYMBOL(tegra_periph_reset_assert);
310
311int __init tegra_init_clock(void)
312{
313 tegra2_init_clocks();
314
315 return 0;
316}
317
318#ifdef CONFIG_DEBUG_FS
319static struct dentry *clk_debugfs_root;
320
321
322static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
323{
324 struct clk *child;
325 struct clk *safe;
326 const char *state = "uninit";
327 char div[5] = {0};
328
329 if (c->state == ON)
330 state = "on";
331 else if (c->state == OFF)
332 state = "off";
333
334 if (c->mul != 0 && c->div != 0) {
335 BUG_ON(c->mul > 2);
336 if (c->mul > c->div)
337 snprintf(div, sizeof(div), "x%d", c->mul / c->div);
338 else
339 snprintf(div, sizeof(div), "%d%s", c->div / c->mul,
340 (c->div % c->mul) ? ".5" : "");
341 }
342
343 seq_printf(s, "%*s%-*s %-6s %-3d %-5s %-10lu\n",
344 level * 3 + 1, c->set ? "" : "*",
345 30 - level * 3, c->name,
346 state, c->refcnt, div, c->rate);
347 list_for_each_entry_safe(child, safe, &c->children, sibling) {
348 clock_tree_show_one(s, child, level + 1);
349 }
350}
351
352static int clock_tree_show(struct seq_file *s, void *data)
353{
354 struct clk *c;
355 unsigned long flags;
356 seq_printf(s, " clock state ref div rate \n");
357 seq_printf(s, "-----------------------------------------------------------\n");
358 spin_lock_irqsave(&clock_lock, flags);
359 list_for_each_entry(c, &clocks, node)
360 if (c->parent == NULL)
361 clock_tree_show_one(s, c, 0);
362 spin_unlock_irqrestore(&clock_lock, flags);
363 return 0;
364}
365
366static int clock_tree_open(struct inode *inode, struct file *file)
367{
368 return single_open(file, clock_tree_show, inode->i_private);
369}
370
371static const struct file_operations clock_tree_fops = {
372 .open = clock_tree_open,
373 .read = seq_read,
374 .llseek = seq_lseek,
375 .release = single_release,
376};
377
378static int possible_parents_show(struct seq_file *s, void *data)
379{
380 struct clk *c = s->private;
381 int i;
382
383 for (i = 0; c->inputs[i].input; i++) {
384 char *first = (i == 0) ? "" : " ";
385 seq_printf(s, "%s%s", first, c->inputs[i].input->name);
386 }
387 seq_printf(s, "\n");
388 return 0;
389}
390
391static int possible_parents_open(struct inode *inode, struct file *file)
392{
393 return single_open(file, possible_parents_show, inode->i_private);
394}
395
396static const struct file_operations possible_parents_fops = {
397 .open = possible_parents_open,
398 .read = seq_read,
399 .llseek = seq_lseek,
400 .release = single_release,
401};
402
403static int clk_debugfs_register_one(struct clk *c)
404{
405 struct dentry *d, *child, *child_tmp;
406
407 d = debugfs_create_dir(c->name, clk_debugfs_root);
408 if (!d)
409 return -ENOMEM;
410 c->dent = d;
411
412 d = debugfs_create_u8("refcnt", S_IRUGO, c->dent, (u8 *)&c->refcnt);
413 if (!d)
414 goto err_out;
415
416 d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
417 if (!d)
418 goto err_out;
419
420 d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
421 if (!d)
422 goto err_out;
423
424 if (c->inputs) {
425 d = debugfs_create_file("possible_parents", S_IRUGO, c->dent,
426 c, &possible_parents_fops);
427 if (!d)
428 goto err_out;
429 }
430
431 return 0;
432
433err_out:
434 d = c->dent;
435 list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
436 debugfs_remove(child);
437 debugfs_remove(c->dent);
438 return -ENOMEM;
439}
440
441static int clk_debugfs_register(struct clk *c)
442{
443 int err;
444 struct clk *pa = c->parent;
445
446 if (pa && !pa->dent) {
447 err = clk_debugfs_register(pa);
448 if (err)
449 return err;
450 }
451
452 if (!c->dent) {
453 err = clk_debugfs_register_one(c);
454 if (err)
455 return err;
456 }
457 return 0;
458}
459
460static int __init clk_debugfs_init(void)
461{
462 struct clk *c;
463 struct dentry *d;
464 int err = -ENOMEM;
465
466 d = debugfs_create_dir("clock", NULL);
467 if (!d)
468 return -ENOMEM;
469 clk_debugfs_root = d;
470
471 d = debugfs_create_file("clock_tree", S_IRUGO, clk_debugfs_root, NULL,
472 &clock_tree_fops);
473 if (!d)
474 goto err_out;
475
476 list_for_each_entry(c, &clocks, node) {
477 err = clk_debugfs_register(c);
478 if (err)
479 goto err_out;
480 }
481 return 0;
482err_out:
483 debugfs_remove_recursive(clk_debugfs_root);
484 return err;
485}
486
487late_initcall(clk_debugfs_init);
488#endif
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
new file mode 100644
index 000000000000..af7c70e2a3ba
--- /dev/null
+++ b/arch/arm/mach-tegra/clock.h
@@ -0,0 +1,147 @@
1/*
2 * arch/arm/mach-tegra/include/mach/clock.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#ifndef __MACH_TEGRA_CLOCK_H
21#define __MACH_TEGRA_CLOCK_H
22
23#include <linux/list.h>
24#include <asm/clkdev.h>
25
26#define DIV_BUS (1 << 0)
27#define DIV_U71 (1 << 1)
28#define DIV_U71_FIXED (1 << 2)
29#define DIV_2 (1 << 3)
30#define PLL_FIXED (1 << 4)
31#define PLL_HAS_CPCON (1 << 5)
32#define MUX (1 << 6)
33#define PLLD (1 << 7)
34#define PERIPH_NO_RESET (1 << 8)
35#define PERIPH_NO_ENB (1 << 9)
36#define PERIPH_EMC_ENB (1 << 10)
37#define PERIPH_MANUAL_RESET (1 << 11)
38#define PLL_ALT_MISC_REG (1 << 12)
39#define ENABLE_ON_INIT (1 << 28)
40
41struct clk;
42
43struct clk_mux_sel {
44 struct clk *input;
45 u32 value;
46};
47
48struct clk_pll_table {
49 unsigned long input_rate;
50 unsigned long output_rate;
51 u16 n;
52 u16 m;
53 u8 p;
54 u8 cpcon;
55};
56
57struct clk_ops {
58 void (*init)(struct clk *);
59 int (*enable)(struct clk *);
60 void (*disable)(struct clk *);
61 void (*recalc)(struct clk *);
62 int (*set_parent)(struct clk *, struct clk *);
63 int (*set_rate)(struct clk *, unsigned long);
64 unsigned long (*get_rate)(struct clk *);
65 long (*round_rate)(struct clk *, unsigned long);
66 unsigned long (*recalculate_rate)(struct clk *);
67};
68
69enum clk_state {
70 UNINITIALIZED = 0,
71 ON,
72 OFF,
73};
74
75struct clk {
76 /* node for master clocks list */
77 struct list_head node;
78 struct list_head children; /* list of children */
79 struct list_head sibling; /* node for children */
80#ifdef CONFIG_DEBUG_FS
81 struct dentry *dent;
82 struct dentry *parent_dent;
83#endif
84 struct clk_ops *ops;
85 struct clk *parent;
86 struct clk_lookup lookup;
87 unsigned long rate;
88 u32 flags;
89 u32 refcnt;
90 const char *name;
91 u32 reg;
92 u32 reg_shift;
93 unsigned int clk_num;
94 enum clk_state state;
95#ifdef CONFIG_DEBUG_FS
96 bool set;
97#endif
98
99 /* PLL */
100 unsigned long input_min;
101 unsigned long input_max;
102 unsigned long cf_min;
103 unsigned long cf_max;
104 unsigned long vco_min;
105 unsigned long vco_max;
106 u32 m;
107 u32 n;
108 u32 p;
109 u32 cpcon;
110 const struct clk_pll_table *pll_table;
111
112 /* DIV */
113 u32 div;
114 u32 mul;
115
116 /* MUX */
117 const struct clk_mux_sel *inputs;
118 u32 sel;
119 u32 reg_mask;
120};
121
122
123struct clk_duplicate {
124 const char *name;
125 struct clk_lookup lookup;
126};
127
128struct tegra_clk_init_table {
129 const char *name;
130 const char *parent;
131 unsigned long rate;
132 bool enabled;
133};
134
135void tegra2_init_clocks(void);
136void tegra2_periph_reset_deassert(struct clk *c);
137void tegra2_periph_reset_assert(struct clk *c);
138void clk_init(struct clk *clk);
139struct clk *tegra_get_clock_by_name(const char *name);
140unsigned long clk_measure_input_freq(void);
141void clk_disable_locked(struct clk *c);
142int clk_enable_locked(struct clk *c);
143int clk_set_parent_locked(struct clk *c, struct clk *parent);
144int clk_reparent(struct clk *c, struct clk *parent);
145void tegra_clk_init_from_table(struct tegra_clk_init_table *table);
146
147#endif
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
new file mode 100644
index 000000000000..039a514b61ef
--- /dev/null
+++ b/arch/arm/mach-tegra/common.c
@@ -0,0 +1,61 @@
1/*
2 * arch/arm/mach-tegra/board-harmony.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@android.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/init.h>
21#include <linux/io.h>
22
23#include <asm/hardware/cache-l2x0.h>
24
25#include <mach/iomap.h>
26
27#include "board.h"
28#include "clock.h"
29
30static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
31 /* name parent rate enabled */
32 { "clk_m", NULL, 0, true },
33 { "pll_p", "clk_m", 216000000, true },
34 { "pll_p_out1", "pll_p", 28800000, true },
35 { "pll_p_out2", "pll_p", 48000000, true },
36 { "pll_p_out3", "pll_p", 72000000, true },
37 { "pll_p_out4", "pll_p", 108000000, true },
38 { "sys", "pll_p_out4", 108000000, true },
39 { "hclk", "sys", 108000000, true },
40 { "pclk", "hclk", 54000000, true },
41 { NULL, NULL, 0, 0},
42};
43
44void __init tegra_init_cache(void)
45{
46#ifdef CONFIG_CACHE_L2X0
47 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
48
49 writel(0x331, p + L2X0_TAG_LATENCY_CTRL);
50 writel(0x441, p + L2X0_DATA_LATENCY_CTRL);
51
52 l2x0_init(p, 0x6C080001, 0x8200c3fe);
53#endif
54}
55
56void __init tegra_common_init(void)
57{
58 tegra_init_clock();
59 tegra_clk_init_from_table(common_clk_init_table);
60 tegra_init_cache();
61}
diff --git a/arch/arm/mach-tegra/gpio-names.h b/arch/arm/mach-tegra/gpio-names.h
new file mode 100644
index 000000000000..f28220a641b2
--- /dev/null
+++ b/arch/arm/mach-tegra/gpio-names.h
@@ -0,0 +1,247 @@
1/*
2 * arch/arm/mach-tegra/include/mach/gpio-names.h
3 *
4 * Copyright (c) 2010 Google, Inc
5 *
6 * Author:
7 * Erik Gilling <konkers@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#ifndef __MACH_TEGRA_GPIO_NAMES_H
20#define __MACH_TEGRA_GPIO_NAMES_H
21
22#define TEGRA_GPIO_PA0 0
23#define TEGRA_GPIO_PA1 1
24#define TEGRA_GPIO_PA2 2
25#define TEGRA_GPIO_PA3 3
26#define TEGRA_GPIO_PA4 4
27#define TEGRA_GPIO_PA5 5
28#define TEGRA_GPIO_PA6 6
29#define TEGRA_GPIO_PA7 7
30#define TEGRA_GPIO_PB0 8
31#define TEGRA_GPIO_PB1 9
32#define TEGRA_GPIO_PB2 10
33#define TEGRA_GPIO_PB3 11
34#define TEGRA_GPIO_PB4 12
35#define TEGRA_GPIO_PB5 13
36#define TEGRA_GPIO_PB6 14
37#define TEGRA_GPIO_PB7 15
38#define TEGRA_GPIO_PC0 16
39#define TEGRA_GPIO_PC1 17
40#define TEGRA_GPIO_PC2 18
41#define TEGRA_GPIO_PC3 19
42#define TEGRA_GPIO_PC4 20
43#define TEGRA_GPIO_PC5 21
44#define TEGRA_GPIO_PC6 22
45#define TEGRA_GPIO_PC7 23
46#define TEGRA_GPIO_PD0 24
47#define TEGRA_GPIO_PD1 25
48#define TEGRA_GPIO_PD2 26
49#define TEGRA_GPIO_PD3 27
50#define TEGRA_GPIO_PD4 28
51#define TEGRA_GPIO_PD5 29
52#define TEGRA_GPIO_PD6 30
53#define TEGRA_GPIO_PD7 31
54#define TEGRA_GPIO_PE0 32
55#define TEGRA_GPIO_PE1 33
56#define TEGRA_GPIO_PE2 34
57#define TEGRA_GPIO_PE3 35
58#define TEGRA_GPIO_PE4 36
59#define TEGRA_GPIO_PE5 37
60#define TEGRA_GPIO_PE6 38
61#define TEGRA_GPIO_PE7 39
62#define TEGRA_GPIO_PF0 40
63#define TEGRA_GPIO_PF1 41
64#define TEGRA_GPIO_PF2 42
65#define TEGRA_GPIO_PF3 43
66#define TEGRA_GPIO_PF4 44
67#define TEGRA_GPIO_PF5 45
68#define TEGRA_GPIO_PF6 46
69#define TEGRA_GPIO_PF7 47
70#define TEGRA_GPIO_PG0 48
71#define TEGRA_GPIO_PG1 49
72#define TEGRA_GPIO_PG2 50
73#define TEGRA_GPIO_PG3 51
74#define TEGRA_GPIO_PG4 52
75#define TEGRA_GPIO_PG5 53
76#define TEGRA_GPIO_PG6 54
77#define TEGRA_GPIO_PG7 55
78#define TEGRA_GPIO_PH0 56
79#define TEGRA_GPIO_PH1 57
80#define TEGRA_GPIO_PH2 58
81#define TEGRA_GPIO_PH3 59
82#define TEGRA_GPIO_PH4 60
83#define TEGRA_GPIO_PH5 61
84#define TEGRA_GPIO_PH6 62
85#define TEGRA_GPIO_PH7 63
86#define TEGRA_GPIO_PI0 64
87#define TEGRA_GPIO_PI1 65
88#define TEGRA_GPIO_PI2 66
89#define TEGRA_GPIO_PI3 67
90#define TEGRA_GPIO_PI4 68
91#define TEGRA_GPIO_PI5 69
92#define TEGRA_GPIO_PI6 70
93#define TEGRA_GPIO_PI7 71
94#define TEGRA_GPIO_PJ0 72
95#define TEGRA_GPIO_PJ1 73
96#define TEGRA_GPIO_PJ2 74
97#define TEGRA_GPIO_PJ3 75
98#define TEGRA_GPIO_PJ4 76
99#define TEGRA_GPIO_PJ5 77
100#define TEGRA_GPIO_PJ6 78
101#define TEGRA_GPIO_PJ7 79
102#define TEGRA_GPIO_PK0 80
103#define TEGRA_GPIO_PK1 81
104#define TEGRA_GPIO_PK2 82
105#define TEGRA_GPIO_PK3 83
106#define TEGRA_GPIO_PK4 84
107#define TEGRA_GPIO_PK5 85
108#define TEGRA_GPIO_PK6 86
109#define TEGRA_GPIO_PK7 87
110#define TEGRA_GPIO_PL0 88
111#define TEGRA_GPIO_PL1 89
112#define TEGRA_GPIO_PL2 90
113#define TEGRA_GPIO_PL3 91
114#define TEGRA_GPIO_PL4 92
115#define TEGRA_GPIO_PL5 93
116#define TEGRA_GPIO_PL6 94
117#define TEGRA_GPIO_PL7 95
118#define TEGRA_GPIO_PM0 96
119#define TEGRA_GPIO_PM1 97
120#define TEGRA_GPIO_PM2 98
121#define TEGRA_GPIO_PM3 99
122#define TEGRA_GPIO_PM4 100
123#define TEGRA_GPIO_PM5 101
124#define TEGRA_GPIO_PM6 102
125#define TEGRA_GPIO_PM7 103
126#define TEGRA_GPIO_PN0 104
127#define TEGRA_GPIO_PN1 105
128#define TEGRA_GPIO_PN2 106
129#define TEGRA_GPIO_PN3 107
130#define TEGRA_GPIO_PN4 108
131#define TEGRA_GPIO_PN5 109
132#define TEGRA_GPIO_PN6 110
133#define TEGRA_GPIO_PN7 111
134#define TEGRA_GPIO_PO0 112
135#define TEGRA_GPIO_PO1 113
136#define TEGRA_GPIO_PO2 114
137#define TEGRA_GPIO_PO3 115
138#define TEGRA_GPIO_PO4 116
139#define TEGRA_GPIO_PO5 117
140#define TEGRA_GPIO_PO6 118
141#define TEGRA_GPIO_PO7 119
142#define TEGRA_GPIO_PP0 120
143#define TEGRA_GPIO_PP1 121
144#define TEGRA_GPIO_PP2 122
145#define TEGRA_GPIO_PP3 123
146#define TEGRA_GPIO_PP4 124
147#define TEGRA_GPIO_PP5 125
148#define TEGRA_GPIO_PP6 126
149#define TEGRA_GPIO_PP7 127
150#define TEGRA_GPIO_PQ0 128
151#define TEGRA_GPIO_PQ1 129
152#define TEGRA_GPIO_PQ2 130
153#define TEGRA_GPIO_PQ3 131
154#define TEGRA_GPIO_PQ4 132
155#define TEGRA_GPIO_PQ5 133
156#define TEGRA_GPIO_PQ6 134
157#define TEGRA_GPIO_PQ7 135
158#define TEGRA_GPIO_PR0 136
159#define TEGRA_GPIO_PR1 137
160#define TEGRA_GPIO_PR2 138
161#define TEGRA_GPIO_PR3 139
162#define TEGRA_GPIO_PR4 140
163#define TEGRA_GPIO_PR5 141
164#define TEGRA_GPIO_PR6 142
165#define TEGRA_GPIO_PR7 143
166#define TEGRA_GPIO_PS0 144
167#define TEGRA_GPIO_PS1 145
168#define TEGRA_GPIO_PS2 146
169#define TEGRA_GPIO_PS3 147
170#define TEGRA_GPIO_PS4 148
171#define TEGRA_GPIO_PS5 149
172#define TEGRA_GPIO_PS6 150
173#define TEGRA_GPIO_PS7 151
174#define TEGRA_GPIO_PT0 152
175#define TEGRA_GPIO_PT1 153
176#define TEGRA_GPIO_PT2 154
177#define TEGRA_GPIO_PT3 155
178#define TEGRA_GPIO_PT4 156
179#define TEGRA_GPIO_PT5 157
180#define TEGRA_GPIO_PT6 158
181#define TEGRA_GPIO_PT7 159
182#define TEGRA_GPIO_PU0 160
183#define TEGRA_GPIO_PU1 161
184#define TEGRA_GPIO_PU2 162
185#define TEGRA_GPIO_PU3 163
186#define TEGRA_GPIO_PU4 164
187#define TEGRA_GPIO_PU5 165
188#define TEGRA_GPIO_PU6 166
189#define TEGRA_GPIO_PU7 167
190#define TEGRA_GPIO_PV0 168
191#define TEGRA_GPIO_PV1 169
192#define TEGRA_GPIO_PV2 170
193#define TEGRA_GPIO_PV3 171
194#define TEGRA_GPIO_PV4 172
195#define TEGRA_GPIO_PV5 173
196#define TEGRA_GPIO_PV6 174
197#define TEGRA_GPIO_PV7 175
198#define TEGRA_GPIO_PW0 176
199#define TEGRA_GPIO_PW1 177
200#define TEGRA_GPIO_PW2 178
201#define TEGRA_GPIO_PW3 179
202#define TEGRA_GPIO_PW4 180
203#define TEGRA_GPIO_PW5 181
204#define TEGRA_GPIO_PW6 182
205#define TEGRA_GPIO_PW7 183
206#define TEGRA_GPIO_PX0 184
207#define TEGRA_GPIO_PX1 185
208#define TEGRA_GPIO_PX2 186
209#define TEGRA_GPIO_PX3 187
210#define TEGRA_GPIO_PX4 188
211#define TEGRA_GPIO_PX5 189
212#define TEGRA_GPIO_PX6 190
213#define TEGRA_GPIO_PX7 191
214#define TEGRA_GPIO_PY0 192
215#define TEGRA_GPIO_PY1 193
216#define TEGRA_GPIO_PY2 194
217#define TEGRA_GPIO_PY3 195
218#define TEGRA_GPIO_PY4 196
219#define TEGRA_GPIO_PY5 197
220#define TEGRA_GPIO_PY6 198
221#define TEGRA_GPIO_PY7 199
222#define TEGRA_GPIO_PZ0 200
223#define TEGRA_GPIO_PZ1 201
224#define TEGRA_GPIO_PZ2 202
225#define TEGRA_GPIO_PZ3 203
226#define TEGRA_GPIO_PZ4 204
227#define TEGRA_GPIO_PZ5 205
228#define TEGRA_GPIO_PZ6 206
229#define TEGRA_GPIO_PZ7 207
230#define TEGRA_GPIO_PAA0 208
231#define TEGRA_GPIO_PAA1 209
232#define TEGRA_GPIO_PAA2 210
233#define TEGRA_GPIO_PAA3 211
234#define TEGRA_GPIO_PAA4 212
235#define TEGRA_GPIO_PAA5 213
236#define TEGRA_GPIO_PAA6 214
237#define TEGRA_GPIO_PAA7 215
238#define TEGRA_GPIO_PBB0 216
239#define TEGRA_GPIO_PBB1 217
240#define TEGRA_GPIO_PBB2 218
241#define TEGRA_GPIO_PBB3 219
242#define TEGRA_GPIO_PBB4 220
243#define TEGRA_GPIO_PBB5 221
244#define TEGRA_GPIO_PBB6 222
245#define TEGRA_GPIO_PBB7 223
246
247#endif
diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c
new file mode 100644
index 000000000000..fe78fba25f3c
--- /dev/null
+++ b/arch/arm/mach-tegra/gpio.c
@@ -0,0 +1,348 @@
1/*
2 * arch/arm/mach-tegra/gpio.c
3 *
4 * Copyright (c) 2010 Google, Inc
5 *
6 * Author:
7 * Erik Gilling <konkers@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/init.h>
21#include <linux/irq.h>
22
23#include <linux/io.h>
24#include <linux/gpio.h>
25
26#include <mach/iomap.h>
27
28#define GPIO_BANK(x) ((x) >> 5)
29#define GPIO_PORT(x) (((x) >> 3) & 0x3)
30#define GPIO_BIT(x) ((x) & 0x7)
31
32#define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \
33 GPIO_BANK(x) * 0x80 + \
34 GPIO_PORT(x) * 4)
35
36#define GPIO_CNF(x) (GPIO_REG(x) + 0x00)
37#define GPIO_OE(x) (GPIO_REG(x) + 0x10)
38#define GPIO_OUT(x) (GPIO_REG(x) + 0X20)
39#define GPIO_IN(x) (GPIO_REG(x) + 0x30)
40#define GPIO_INT_STA(x) (GPIO_REG(x) + 0x40)
41#define GPIO_INT_ENB(x) (GPIO_REG(x) + 0x50)
42#define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60)
43#define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70)
44
45#define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x800)
46#define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x810)
47#define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0X820)
48#define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0x840)
49#define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0x850)
50#define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0x860)
51
52#define GPIO_INT_LVL_MASK 0x010101
53#define GPIO_INT_LVL_EDGE_RISING 0x000101
54#define GPIO_INT_LVL_EDGE_FALLING 0x000100
55#define GPIO_INT_LVL_EDGE_BOTH 0x010100
56#define GPIO_INT_LVL_LEVEL_HIGH 0x000001
57#define GPIO_INT_LVL_LEVEL_LOW 0x000000
58
59struct tegra_gpio_bank {
60 int bank;
61 int irq;
62 spinlock_t lvl_lock[4];
63};
64
65
66static struct tegra_gpio_bank tegra_gpio_banks[] = {
67 {.bank = 0, .irq = INT_GPIO1},
68 {.bank = 1, .irq = INT_GPIO2},
69 {.bank = 2, .irq = INT_GPIO3},
70 {.bank = 3, .irq = INT_GPIO4},
71 {.bank = 4, .irq = INT_GPIO5},
72 {.bank = 5, .irq = INT_GPIO6},
73 {.bank = 6, .irq = INT_GPIO7},
74};
75
76static int tegra_gpio_compose(int bank, int port, int bit)
77{
78 return (bank << 5) | ((port & 0x3) << 3) | (bit & 0x7);
79}
80
81static void tegra_gpio_mask_write(u32 reg, int gpio, int value)
82{
83 u32 val;
84
85 val = 0x100 << GPIO_BIT(gpio);
86 if (value)
87 val |= 1 << GPIO_BIT(gpio);
88 __raw_writel(val, reg);
89}
90
91void tegra_gpio_enable(int gpio)
92{
93 tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1);
94}
95
96void tegra_gpio_disable(int gpio)
97{
98 tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0);
99}
100
101static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
102{
103 tegra_gpio_mask_write(GPIO_MSK_OUT(offset), offset, value);
104}
105
106static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset)
107{
108 return (__raw_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1;
109}
110
111static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
112{
113 tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 0);
114 return 0;
115}
116
117static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
118 int value)
119{
120 tegra_gpio_set(chip, offset, value);
121 tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 1);
122 return 0;
123}
124
125
126
127static struct gpio_chip tegra_gpio_chip = {
128 .label = "tegra-gpio",
129 .direction_input = tegra_gpio_direction_input,
130 .get = tegra_gpio_get,
131 .direction_output = tegra_gpio_direction_output,
132 .set = tegra_gpio_set,
133 .base = 0,
134 .ngpio = ARCH_NR_GPIOS,
135};
136
137static void tegra_gpio_irq_ack(unsigned int irq)
138{
139 int gpio = irq - INT_GPIO_BASE;
140
141 __raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
142}
143
144static void tegra_gpio_irq_mask(unsigned int irq)
145{
146 int gpio = irq - INT_GPIO_BASE;
147
148 tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0);
149}
150
151static void tegra_gpio_irq_unmask(unsigned int irq)
152{
153 int gpio = irq - INT_GPIO_BASE;
154
155 tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1);
156}
157
158static int tegra_gpio_irq_set_type(unsigned int irq, unsigned int type)
159{
160 int gpio = irq - INT_GPIO_BASE;
161 struct tegra_gpio_bank *bank = get_irq_chip_data(irq);
162 int port = GPIO_PORT(gpio);
163 int lvl_type;
164 int val;
165 unsigned long flags;
166
167 switch (type & IRQ_TYPE_SENSE_MASK) {
168 case IRQ_TYPE_EDGE_RISING:
169 lvl_type = GPIO_INT_LVL_EDGE_RISING;
170 break;
171
172 case IRQ_TYPE_EDGE_FALLING:
173 lvl_type = GPIO_INT_LVL_EDGE_FALLING;
174 break;
175
176 case IRQ_TYPE_EDGE_BOTH:
177 lvl_type = GPIO_INT_LVL_EDGE_BOTH;
178 break;
179
180 case IRQ_TYPE_LEVEL_HIGH:
181 lvl_type = GPIO_INT_LVL_LEVEL_HIGH;
182 break;
183
184 case IRQ_TYPE_LEVEL_LOW:
185 lvl_type = GPIO_INT_LVL_LEVEL_LOW;
186 break;
187
188 default:
189 return -EINVAL;
190 }
191
192 spin_lock_irqsave(&bank->lvl_lock[port], flags);
193
194 val = __raw_readl(GPIO_INT_LVL(gpio));
195 val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio));
196 val |= lvl_type << GPIO_BIT(gpio);
197 __raw_writel(val, GPIO_INT_LVL(gpio));
198
199 spin_unlock_irqrestore(&bank->lvl_lock[port], flags);
200
201 if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
202 __set_irq_handler_unlocked(irq, handle_level_irq);
203 else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
204 __set_irq_handler_unlocked(irq, handle_edge_irq);
205
206 return 0;
207}
208
209static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
210{
211 struct tegra_gpio_bank *bank;
212 int port;
213 int pin;
214 int unmasked = 0;
215
216 desc->chip->ack(irq);
217
218 bank = get_irq_data(irq);
219
220 for (port = 0; port < 4; port++) {
221 int gpio = tegra_gpio_compose(bank->bank, port, 0);
222 unsigned long sta = __raw_readl(GPIO_INT_STA(gpio)) &
223 __raw_readl(GPIO_INT_ENB(gpio));
224 u32 lvl = __raw_readl(GPIO_INT_LVL(gpio));
225
226 for_each_set_bit(pin, &sta, 8) {
227 __raw_writel(1 << pin, GPIO_INT_CLR(gpio));
228
229 /* if gpio is edge triggered, clear condition
230 * before executing the hander so that we don't
231 * miss edges
232 */
233 if (lvl & (0x100 << pin)) {
234 unmasked = 1;
235 desc->chip->unmask(irq);
236 }
237
238 generic_handle_irq(gpio_to_irq(gpio + pin));
239 }
240 }
241
242 if (!unmasked)
243 desc->chip->unmask(irq);
244
245}
246
247
248static struct irq_chip tegra_gpio_irq_chip = {
249 .name = "GPIO",
250 .ack = tegra_gpio_irq_ack,
251 .mask = tegra_gpio_irq_mask,
252 .unmask = tegra_gpio_irq_unmask,
253 .set_type = tegra_gpio_irq_set_type,
254};
255
256
257/* This lock class tells lockdep that GPIO irqs are in a different
258 * category than their parents, so it won't report false recursion.
259 */
260static struct lock_class_key gpio_lock_class;
261
262static int __init tegra_gpio_init(void)
263{
264 struct tegra_gpio_bank *bank;
265 int i;
266 int j;
267
268 for (i = 0; i < 7; i++) {
269 for (j = 0; j < 4; j++) {
270 int gpio = tegra_gpio_compose(i, j, 0);
271 __raw_writel(0x00, GPIO_INT_ENB(gpio));
272 }
273 }
274
275 gpiochip_add(&tegra_gpio_chip);
276
277 for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + ARCH_NR_GPIOS); i++) {
278 bank = &tegra_gpio_banks[GPIO_BANK(irq_to_gpio(i))];
279
280 lockdep_set_class(&irq_desc[i].lock, &gpio_lock_class);
281 set_irq_chip_data(i, bank);
282 set_irq_chip(i, &tegra_gpio_irq_chip);
283 set_irq_handler(i, handle_simple_irq);
284 set_irq_flags(i, IRQF_VALID);
285 }
286
287 for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
288 bank = &tegra_gpio_banks[i];
289
290 set_irq_chained_handler(bank->irq, tegra_gpio_irq_handler);
291 set_irq_data(bank->irq, bank);
292
293 for (j = 0; j < 4; j++)
294 spin_lock_init(&bank->lvl_lock[j]);
295 }
296
297 return 0;
298}
299
300postcore_initcall(tegra_gpio_init);
301
302#ifdef CONFIG_DEBUG_FS
303
304#include <linux/debugfs.h>
305#include <linux/seq_file.h>
306
307static int dbg_gpio_show(struct seq_file *s, void *unused)
308{
309 int i;
310 int j;
311
312 for (i = 0; i < 7; i++) {
313 for (j = 0; j < 4; j++) {
314 int gpio = tegra_gpio_compose(i, j, 0);
315 seq_printf(s, "%d:%d %02x %02x %02x %02x %02x %02x %06x\n",
316 i, j,
317 __raw_readl(GPIO_CNF(gpio)),
318 __raw_readl(GPIO_OE(gpio)),
319 __raw_readl(GPIO_OUT(gpio)),
320 __raw_readl(GPIO_IN(gpio)),
321 __raw_readl(GPIO_INT_STA(gpio)),
322 __raw_readl(GPIO_INT_ENB(gpio)),
323 __raw_readl(GPIO_INT_LVL(gpio)));
324 }
325 }
326 return 0;
327}
328
329static int dbg_gpio_open(struct inode *inode, struct file *file)
330{
331 return single_open(file, dbg_gpio_show, &inode->i_private);
332}
333
334static const struct file_operations debug_fops = {
335 .open = dbg_gpio_open,
336 .read = seq_read,
337 .llseek = seq_lseek,
338 .release = single_release,
339};
340
341static int __init tegra_gpio_debuginit(void)
342{
343 (void) debugfs_create_file("tegra_gpio", S_IRUGO,
344 NULL, NULL, &debug_fops);
345 return 0;
346}
347late_initcall(tegra_gpio_debuginit);
348#endif
diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S
new file mode 100644
index 000000000000..b5349b2f13d2
--- /dev/null
+++ b/arch/arm/mach-tegra/headsmp.S
@@ -0,0 +1,61 @@
1#include <linux/linkage.h>
2#include <linux/init.h>
3
4 .section ".text.head", "ax"
5 __CPUINIT
6
7/*
8 * Tegra specific entry point for secondary CPUs.
9 * The secondary kernel init calls v7_flush_dcache_all before it enables
10 * the L1; however, the L1 comes out of reset in an undefined state, so
11 * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
12 * of cache lines with uninitialized data and uninitialized tags to get
13 * written out to memory, which does really unpleasant things to the main
14 * processor. We fix this by performing an invalidate, rather than a
15 * clean + invalidate, before jumping into the kernel.
16 */
17ENTRY(v7_invalidate_l1)
18 mov r0, #0
19 mcr p15, 2, r0, c0, c0, 0
20 mrc p15, 1, r0, c0, c0, 0
21
22 ldr r1, =0x7fff
23 and r2, r1, r0, lsr #13
24
25 ldr r1, =0x3ff
26
27 and r3, r1, r0, lsr #3 @ NumWays - 1
28 add r2, r2, #1 @ NumSets
29
30 and r0, r0, #0x7
31 add r0, r0, #4 @ SetShift
32
33 clz r1, r3 @ WayShift
34 add r4, r3, #1 @ NumWays
351: sub r2, r2, #1 @ NumSets--
36 mov r3, r4 @ Temp = NumWays
372: subs r3, r3, #1 @ Temp--
38 mov r5, r3, lsl r1
39 mov r6, r2, lsl r0
40 orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
41 mcr p15, 0, r5, c7, c6, 2
42 bgt 2b
43 cmp r2, #0
44 bgt 1b
45 dsb
46 isb
47 mov pc, lr
48ENDPROC(v7_invalidate_l1)
49
50ENTRY(tegra_secondary_startup)
51 msr cpsr_fsxc, #0xd3
52 bl v7_invalidate_l1
53 mrc p15, 0, r0, c0, c0, 5
54 and r0, r0, #15
55 ldr r1, =0x6000f100
56 str r0, [r1]
571: ldr r2, [r1]
58 cmp r0, r2
59 beq 1b
60 b secondary_startup
61ENDPROC(tegra_secondary_startup)
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
new file mode 100644
index 000000000000..8e7f115aa21e
--- /dev/null
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -0,0 +1,140 @@
1/*
2 * linux/arch/arm/mach-realview/hotplug.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/smp.h>
14#include <linux/completion.h>
15
16#include <asm/cacheflush.h>
17
18static DECLARE_COMPLETION(cpu_killed);
19
20static inline void cpu_enter_lowpower(void)
21{
22 unsigned int v;
23
24 flush_cache_all();
25 asm volatile(
26 " mcr p15, 0, %1, c7, c5, 0\n"
27 " mcr p15, 0, %1, c7, c10, 4\n"
28 /*
29 * Turn off coherency
30 */
31 " mrc p15, 0, %0, c1, c0, 1\n"
32 " bic %0, %0, #0x20\n"
33 " mcr p15, 0, %0, c1, c0, 1\n"
34 " mrc p15, 0, %0, c1, c0, 0\n"
35 " bic %0, %0, #0x04\n"
36 " mcr p15, 0, %0, c1, c0, 0\n"
37 : "=&r" (v)
38 : "r" (0)
39 : "cc");
40}
41
42static inline void cpu_leave_lowpower(void)
43{
44 unsigned int v;
45
46 asm volatile(
47 "mrc p15, 0, %0, c1, c0, 0\n"
48 " orr %0, %0, #0x04\n"
49 " mcr p15, 0, %0, c1, c0, 0\n"
50 " mrc p15, 0, %0, c1, c0, 1\n"
51 " orr %0, %0, #0x20\n"
52 " mcr p15, 0, %0, c1, c0, 1\n"
53 : "=&r" (v)
54 :
55 : "cc");
56}
57
58static inline void platform_do_lowpower(unsigned int cpu)
59{
60 /*
61 * there is no power-control hardware on this platform, so all
62 * we can do is put the core into WFI; this is safe as the calling
63 * code will have already disabled interrupts
64 */
65 for (;;) {
66 /*
67 * here's the WFI
68 */
69 asm(".word 0xe320f003\n"
70 :
71 :
72 : "memory", "cc");
73
74 /*if (pen_release == cpu) {*/
75 /*
76 * OK, proper wakeup, we're done
77 */
78 break;
79 /*}*/
80
81 /*
82 * getting here, means that we have come out of WFI without
83 * having been woken up - this shouldn't happen
84 *
85 * The trouble is, letting people know about this is not really
86 * possible, since we are currently running incoherently, and
87 * therefore cannot safely call printk() or anything else
88 */
89#ifdef DEBUG
90 printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
91#endif
92 }
93}
94
95int platform_cpu_kill(unsigned int cpu)
96{
97 return wait_for_completion_timeout(&cpu_killed, 5000);
98}
99
100/*
101 * platform-specific code to shutdown a CPU
102 *
103 * Called with IRQs disabled
104 */
105void platform_cpu_die(unsigned int cpu)
106{
107#ifdef DEBUG
108 unsigned int this_cpu = hard_smp_processor_id();
109
110 if (cpu != this_cpu) {
111 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
112 this_cpu, cpu);
113 BUG();
114 }
115#endif
116
117 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
118 complete(&cpu_killed);
119
120 /*
121 * we're ready for shutdown now, so do it
122 */
123 cpu_enter_lowpower();
124 platform_do_lowpower(cpu);
125
126 /*
127 * bring this CPU back into the world of cache
128 * coherency, and then restore interrupts
129 */
130 cpu_leave_lowpower();
131}
132
133int platform_cpu_disable(unsigned int cpu)
134{
135 /*
136 * we don't allow CPU 0 to be shutdown (it is still too special
137 * e.g. clock tick interrupts)
138 */
139 return cpu == 0 ? -EPERM : 0;
140}
diff --git a/arch/arm/mach-tegra/include/mach/barriers.h b/arch/arm/mach-tegra/include/mach/barriers.h
new file mode 100644
index 000000000000..cc115174899b
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/barriers.h
@@ -0,0 +1,30 @@
1/*
2 * arch/arm/mach-realview/include/mach/barriers.h
3 *
4 * Copyright (C) 2010 ARM Ltd.
5 * Written by Catalin Marinas <catalin.marinas@arm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef __MACH_BARRIERS_H
22#define __MACH_BARRIERS_H
23
24#include <asm/outercache.h>
25
26#define rmb() dmb()
27#define wmb() do { dsb(); outer_sync(); } while (0)
28#define mb() wmb()
29
30#endif /* __MACH_BARRIERS_H */
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h
new file mode 100644
index 000000000000..2896f25ebfb5
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/clk.h
@@ -0,0 +1,26 @@
1/*
2 * arch/arm/mach-tegra/include/mach/clk.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Erik Gilling <konkers@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#ifndef __MACH_CLK_H
21#define __MACH_CLK_H
22
23void tegra_periph_reset_deassert(struct clk *c);
24void tegra_periph_reset_assert(struct clk *c);
25
26#endif
diff --git a/arch/arm/mach-tegra/include/mach/clkdev.h b/arch/arm/mach-tegra/include/mach/clkdev.h
new file mode 100644
index 000000000000..412f5c63e65a
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/clkdev.h
@@ -0,0 +1,32 @@
1/*
2 * arch/arm/mach-tegra/include/mach/clkdev.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#ifndef __MACH_CLKDEV_H
21#define __MACH_CLKDEV_H
22
23static inline int __clk_get(struct clk *clk)
24{
25 return 1;
26}
27
28static inline void __clk_put(struct clk *clk)
29{
30}
31
32#endif
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
new file mode 100644
index 000000000000..55a39564b43c
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -0,0 +1,46 @@
1/*
2 * arch/arm/mach-tegra/include/mach/debug-macro.S
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Erik Gilling <konkers@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#include <mach/io.h>
22
23 .macro addruart,rx, tmp
24 mrc p15, 0, \rx, c1, c0
25 tst \rx, #1 @ MMU enabled?
26 ldreq \rx, =IO_APB_PHYS @ physical
27 ldrne \rx, =IO_APB_VIRT @ virtual
28#if defined(CONFIG_TEGRA_DEBUG_UART_NONE)
29#error "A debug UART must be selected in the kernel config to use DEBUG_LL"
30#elif defined(CONFIG_TEGRA_DEBUG_UARTA)
31 orr \rx, \rx, #0x6000
32#elif defined(CONFIG_TEGRA_DEBUG_UARTB)
33 ldr \tmp, =0x6040
34 orr \rx, \rx, \tmp
35#elif defined(CONFIG_TEGRA_DEBUG_UARTC)
36 orr \rx, \rx, #0x6200
37#elif defined(CONFIG_TEGRA_DEBUG_UARTD)
38 orr \rx, \rx, #0x6300
39#elif defined(CONFIG_TEGRA_DEBUG_UARTE)
40 orr \rx, \rx, #0x6400
41#endif
42 .endm
43
44#define UART_SHIFT 2
45#include <asm/hardware/debug-8250.S>
46
diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S
new file mode 100644
index 000000000000..2ba9e5c9d2f6
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/entry-macro.S
@@ -0,0 +1,118 @@
1/* arch/arm/mach-tegra/include/mach/entry-macro.S
2 *
3 * Copyright (C) 2009 Palm, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15#include <mach/iomap.h>
16#include <mach/io.h>
17
18#if defined(CONFIG_ARM_GIC)
19
20#include <asm/hardware/gic.h>
21
22 /* Uses the GIC interrupt controller built into the cpu */
23#define ICTRL_BASE (IO_CPU_VIRT + 0x100)
24
25 .macro disable_fiq
26 .endm
27
28 .macro get_irqnr_preamble, base, tmp
29 movw \base, #(ICTRL_BASE & 0x0000ffff)
30 movt \base, #((ICTRL_BASE & 0xffff0000) >> 16)
31 .endm
32
33 .macro arch_ret_to_user, tmp1, tmp2
34 .endm
35
36 /*
37 * The interrupt numbering scheme is defined in the
38 * interrupt controller spec. To wit:
39 *
40 * Interrupts 0-15 are IPI
41 * 16-28 are reserved
42 * 29-31 are local. We allow 30 to be used for the watchdog.
43 * 32-1020 are global
44 * 1021-1022 are reserved
45 * 1023 is "spurious" (no interrupt)
46 *
47 * For now, we ignore all local interrupts so only return an interrupt
48 * if it's between 30 and 1020. The test_for_ipi routine below will
49 * pick up on IPIs.
50 *
51 * A simple read from the controller will tell us the number of the
52 * highest priority enabled interrupt. We then just need to check
53 * whether it is in the valid range for an IRQ (30-1020 inclusive).
54 */
55
56 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
57
58 /* bits 12-10 = src CPU, 9-0 = int # */
59 ldr \irqstat, [\base, #GIC_CPU_INTACK]
60
61 ldr \tmp, =1021
62
63 bic \irqnr, \irqstat, #0x1c00
64
65 cmp \irqnr, #29
66 cmpcc \irqnr, \irqnr
67 cmpne \irqnr, \tmp
68 cmpcs \irqnr, \irqnr
69
70 .endm
71
72 /* We assume that irqstat (the raw value of the IRQ acknowledge
73 * register) is preserved from the macro above.
74 * If there is an IPI, we immediately signal end of interrupt on the
75 * controller, since this requires the original irqstat value which
76 * we won't easily be able to recreate later.
77 */
78
79 .macro test_for_ipi, irqnr, irqstat, base, tmp
80 bic \irqnr, \irqstat, #0x1c00
81 cmp \irqnr, #16
82 strcc \irqstat, [\base, #GIC_CPU_EOI]
83 cmpcs \irqnr, \irqnr
84 .endm
85
86 /* As above, this assumes that irqstat and base are preserved.. */
87
88 .macro test_for_ltirq, irqnr, irqstat, base, tmp
89 bic \irqnr, \irqstat, #0x1c00
90 mov \tmp, #0
91 cmp \irqnr, #29
92 moveq \tmp, #1
93 streq \irqstat, [\base, #GIC_CPU_EOI]
94 cmp \tmp, #0
95 .endm
96
97#else
98 /* legacy interrupt controller for AP16 */
99 .macro disable_fiq
100 .endm
101
102 .macro get_irqnr_preamble, base, tmp
103 @ enable imprecise aborts
104 cpsie a
105 @ EVP base at 0xf010f000
106 mov \base, #0xf0000000
107 orr \base, #0x00100000
108 orr \base, #0x0000f000
109 .endm
110
111 .macro arch_ret_to_user, tmp1, tmp2
112 .endm
113
114 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
115 ldr \irqnr, [\base, #0x20] @ EVT_IRQ_STS
116 cmp \irqnr, #0x80
117 .endm
118#endif
diff --git a/arch/arm/mach-tegra/include/mach/gpio.h b/arch/arm/mach-tegra/include/mach/gpio.h
new file mode 100644
index 000000000000..540e822e50f7
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/gpio.h
@@ -0,0 +1,53 @@
1/*
2 * arch/arm/mach-tegra/include/mach/gpio.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Erik Gilling <konkers@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#ifndef __MACH_TEGRA_GPIO_H
21#define __MACH_TEGRA_GPIO_H
22
23#include <mach/irqs.h>
24
25#define ARCH_NR_GPIOS INT_GPIO_NR
26
27#include <asm-generic/gpio.h>
28
29#define gpio_get_value __gpio_get_value
30#define gpio_set_value __gpio_set_value
31#define gpio_cansleep __gpio_cansleep
32
33#define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio))
34#define TEGRA_IRQ_TO_GPIO(irq) ((gpio) - INT_GPIO_BASE)
35
36static inline int gpio_to_irq(unsigned int gpio)
37{
38 if (gpio < ARCH_NR_GPIOS)
39 return INT_GPIO_BASE + gpio;
40 return -EINVAL;
41}
42
43static inline int irq_to_gpio(unsigned int irq)
44{
45 if ((irq >= INT_GPIO_BASE) && (irq < INT_GPIO_BASE + INT_GPIO_NR))
46 return irq - INT_GPIO_BASE;
47 return -EINVAL;
48}
49
50void tegra_gpio_enable(int gpio);
51void tegra_gpio_disable(int gpio);
52
53#endif
diff --git a/arch/arm/mach-tegra/include/mach/hardware.h b/arch/arm/mach-tegra/include/mach/hardware.h
new file mode 100644
index 000000000000..6014edf60d93
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/hardware.h
@@ -0,0 +1,24 @@
1/*
2 * arch/arm/mach-tegra/include/mach/hardware.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Erik Gilling <konkers@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#ifndef __MACH_TEGRA_HARDWARE_H
22#define __MACH_TEGRA_HARDWARE_H
23
24#endif
diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h
new file mode 100644
index 000000000000..35edfc32ffc9
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/io.h
@@ -0,0 +1,79 @@
1/*
2 * arch/arm/mach-tegra/include/mach/io.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Erik Gilling <konkers@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#ifndef __MACH_TEGRA_IO_H
22#define __MACH_TEGRA_IO_H
23
24#define IO_SPACE_LIMIT 0xffffffff
25
26/* On TEGRA, many peripherals are very closely packed in
27 * two 256MB io windows (that actually only use about 64KB
28 * at the start of each).
29 *
30 * We will just map the first 1MB of each window (to minimize
31 * pt entries needed) and provide a macro to transform physical
32 * io addresses to an appropriate void __iomem *.
33 *
34 */
35
36#define IO_CPU_PHYS 0x50040000
37#define IO_CPU_VIRT 0xFE000000
38#define IO_CPU_SIZE SZ_16K
39
40#define IO_PPSB_PHYS 0x60000000
41#define IO_PPSB_VIRT 0xFE200000
42#define IO_PPSB_SIZE SZ_1M
43
44#define IO_APB_PHYS 0x70000000
45#define IO_APB_VIRT 0xFE300000
46#define IO_APB_SIZE SZ_1M
47
48#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz)))
49#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst)))
50
51#define IO_TO_VIRT(n) ( \
52 IO_TO_VIRT_BETWEEN((n), IO_PPSB_PHYS, IO_PPSB_SIZE) ? \
53 IO_TO_VIRT_XLATE((n), IO_PPSB_PHYS, IO_PPSB_VIRT) : \
54 IO_TO_VIRT_BETWEEN((n), IO_APB_PHYS, IO_APB_SIZE) ? \
55 IO_TO_VIRT_XLATE((n), IO_APB_PHYS, IO_APB_VIRT) : \
56 IO_TO_VIRT_BETWEEN((n), IO_CPU_PHYS, IO_CPU_SIZE) ? \
57 IO_TO_VIRT_XLATE((n), IO_CPU_PHYS, IO_CPU_VIRT) : \
58 0)
59
60#ifndef __ASSEMBLER__
61
62#define __arch_ioremap(p, s, t) tegra_ioremap(p, s, t)
63#define __arch_iounmap(v) tegra_iounmap(v)
64
65void __iomem *tegra_ioremap(unsigned long phys, size_t size, unsigned int type);
66void tegra_iounmap(volatile void __iomem *addr);
67
68#define IO_ADDRESS(n) ((void __iomem *) IO_TO_VIRT(n))
69
70static inline void __iomem *__io(unsigned long addr)
71{
72 return (void __iomem *)addr;
73}
74#define __io(a) __io(a)
75#define __mem_pci(a) (a)
76
77#endif
78
79#endif
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
new file mode 100644
index 000000000000..1741f7dd7a9b
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -0,0 +1,203 @@
1/*
2 * arch/arm/mach-tegra/include/mach/iomap.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Erik Gilling <konkers@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#ifndef __MACH_TEGRA_IOMAP_H
22#define __MACH_TEGRA_IOMAP_H
23
24#include <asm/sizes.h>
25
26#define TEGRA_ARM_PERIF_BASE 0x50040000
27#define TEGRA_ARM_PERIF_SIZE SZ_8K
28
29#define TEGRA_ARM_INT_DIST_BASE 0x50041000
30#define TEGRA_ARM_INT_DIST_SIZE SZ_4K
31
32#define TEGRA_DISPLAY_BASE 0x54200000
33#define TEGRA_DISPLAY_SIZE SZ_256K
34
35#define TEGRA_DISPLAY2_BASE 0x54240000
36#define TEGRA_DISPLAY2_SIZE SZ_256K
37
38#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000
39#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64
40
41#define TEGRA_SECONDARY_ICTLR_BASE 0x60004100
42#define TEGRA_SECONDARY_ICTLR_SIZE SZ_64
43
44#define TEGRA_TERTIARY_ICTLR_BASE 0x60004200
45#define TEGRA_TERTIARY_ICTLR_SIZE SZ_64
46
47#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300
48#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64
49
50#define TEGRA_TMR1_BASE 0x60005000
51#define TEGRA_TMR1_SIZE SZ_8
52
53#define TEGRA_TMR2_BASE 0x60005008
54#define TEGRA_TMR2_SIZE SZ_8
55
56#define TEGRA_TMRUS_BASE 0x60005010
57#define TEGRA_TMRUS_SIZE SZ_64
58
59#define TEGRA_TMR3_BASE 0x60005050
60#define TEGRA_TMR3_SIZE SZ_8
61
62#define TEGRA_TMR4_BASE 0x60005058
63#define TEGRA_TMR4_SIZE SZ_8
64
65#define TEGRA_CLK_RESET_BASE 0x60006000
66#define TEGRA_CLK_RESET_SIZE SZ_4K
67
68#define TEGRA_FLOW_CTRL_BASE 0x60007000
69#define TEGRA_FLOW_CTRL_SIZE 20
70
71#define TEGRA_STATMON_BASE 0x6000C4000
72#define TEGRA_STATMON_SIZE SZ_1K
73
74#define TEGRA_GPIO_BASE 0x6000D000
75#define TEGRA_GPIO_SIZE SZ_4K
76
77#define TEGRA_EXCEPTION_VECTORS_BASE 0x6000F000
78#define TEGRA_EXCEPTION_VECTORS_SIZE SZ_4K
79
80#define TEGRA_APB_MISC_BASE 0x70000000
81#define TEGRA_APB_MISC_SIZE SZ_4K
82
83#define TEGRA_AC97_BASE 0x70002000
84#define TEGRA_AC97_SIZE SZ_512
85
86#define TEGRA_SPDIF_BASE 0x70002400
87#define TEGRA_SPDIF_SIZE SZ_512
88
89#define TEGRA_I2S1_BASE 0x70002800
90#define TEGRA_I2S1_SIZE SZ_256
91
92#define TEGRA_I2S2_BASE 0x70002A00
93#define TEGRA_I2S2_SIZE SZ_256
94
95#define TEGRA_UARTA_BASE 0x70006000
96#define TEGRA_UARTA_SIZE SZ_64
97
98#define TEGRA_UARTB_BASE 0x70006040
99#define TEGRA_UARTB_SIZE SZ_64
100
101#define TEGRA_UARTC_BASE 0x70006200
102#define TEGRA_UARTC_SIZE SZ_256
103
104#define TEGRA_UARTD_BASE 0x70006300
105#define TEGRA_UARTD_SIZE SZ_256
106
107#define TEGRA_UARTE_BASE 0x70006400
108#define TEGRA_UARTE_SIZE SZ_256
109
110#define TEGRA_NAND_BASE 0x70008000
111#define TEGRA_NAND_SIZE SZ_256
112
113#define TEGRA_HSMMC_BASE 0x70008500
114#define TEGRA_HSMMC_SIZE SZ_256
115
116#define TEGRA_SNOR_BASE 0x70009000
117#define TEGRA_SNOR_SIZE SZ_4K
118
119#define TEGRA_PWFM_BASE 0x7000A000
120#define TEGRA_PWFM_SIZE SZ_256
121
122#define TEGRA_MIPI_BASE 0x7000B000
123#define TEGRA_MIPI_SIZE SZ_256
124
125#define TEGRA_I2C_BASE 0x7000C000
126#define TEGRA_I2C_SIZE SZ_256
127
128#define TEGRA_TWC_BASE 0x7000C100
129#define TEGRA_TWC_SIZE SZ_256
130
131#define TEGRA_SPI_BASE 0x7000C380
132#define TEGRA_SPI_SIZE 48
133
134#define TEGRA_I2C2_BASE 0x7000C400
135#define TEGRA_I2C2_SIZE SZ_256
136
137#define TEGRA_I2C3_BASE 0x7000C500
138#define TEGRA_I2C3_SIZE SZ_256
139
140#define TEGRA_OWR_BASE 0x7000D000
141#define TEGRA_OWR_SIZE 80
142
143#define TEGRA_DVC_BASE 0x7000D000
144#define TEGRA_DVC_SIZE SZ_512
145
146#define TEGRA_SPI1_BASE 0x7000D400
147#define TEGRA_SPI1_SIZE SZ_512
148
149#define TEGRA_SPI2_BASE 0x7000D600
150#define TEGRA_SPI2_SIZE SZ_512
151
152#define TEGRA_SPI3_BASE 0x7000D800
153#define TEGRA_SPI3_SIZE SZ_512
154
155#define TEGRA_SPI4_BASE 0x7000DA00
156#define TEGRA_SPI4_SIZE SZ_512
157
158#define TEGRA_RTC_BASE 0x7000E000
159#define TEGRA_RTC_SIZE SZ_256
160
161#define TEGRA_KBC_BASE 0x7000E200
162#define TEGRA_KBC_SIZE SZ_256
163
164#define TEGRA_PMC_BASE 0x7000E400
165#define TEGRA_PMC_SIZE SZ_256
166
167#define TEGRA_MC_BASE 0x7000F000
168#define TEGRA_MC_SIZE SZ_1K
169
170#define TEGRA_EMC_BASE 0x7000F400
171#define TEGRA_EMC_SIZE SZ_1K
172
173#define TEGRA_FUSE_BASE 0x7000F800
174#define TEGRA_FUSE_SIZE SZ_1K
175
176#define TEGRA_KFUSE_BASE 0x7000FC00
177#define TEGRA_KFUSE_SIZE SZ_1K
178
179#define TEGRA_CSITE_BASE 0x70040000
180#define TEGRA_CSITE_SIZE SZ_256K
181
182#define TEGRA_USB_BASE 0xC5000000
183#define TEGRA_USB_SIZE SZ_16K
184
185#define TEGRA_USB1_BASE 0xC5004000
186#define TEGRA_USB1_SIZE SZ_16K
187
188#define TEGRA_USB2_BASE 0xC5008000
189#define TEGRA_USB2_SIZE SZ_16K
190
191#define TEGRA_SDMMC1_BASE 0xC8000000
192#define TEGRA_SDMMC1_SIZE SZ_512
193
194#define TEGRA_SDMMC2_BASE 0xC8000200
195#define TEGRA_SDMMC2_SIZE SZ_512
196
197#define TEGRA_SDMMC3_BASE 0xC8000400
198#define TEGRA_SDMMC3_SIZE SZ_512
199
200#define TEGRA_SDMMC4_BASE 0xC8000600
201#define TEGRA_SDMMC4_SIZE SZ_512
202
203#endif
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
new file mode 100644
index 000000000000..20f640edaa0d
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -0,0 +1,173 @@
1/*
2 * arch/arm/mach-tegra/include/mach/irqs.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Erik Gilling <konkers@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#ifndef __MACH_TEGRA_IRQS_H
22#define __MACH_TEGRA_IRQS_H
23
24#define INT_GIC_BASE 0
25
26#define IRQ_LOCALTIMER 29
27
28/* Primary Interrupt Controller */
29#define INT_PRI_BASE (INT_GIC_BASE + 32)
30#define INT_TMR1 (INT_PRI_BASE + 0)
31#define INT_TMR2 (INT_PRI_BASE + 1)
32#define INT_RTC (INT_PRI_BASE + 2)
33#define INT_I2S2 (INT_PRI_BASE + 3)
34#define INT_SHR_SEM_INBOX_IBF (INT_PRI_BASE + 4)
35#define INT_SHR_SEM_INBOX_IBE (INT_PRI_BASE + 5)
36#define INT_SHR_SEM_OUTBOX_IBF (INT_PRI_BASE + 6)
37#define INT_SHR_SEM_OUTBOX_IBE (INT_PRI_BASE + 7)
38#define INT_VDE_UCQ_ERROR (INT_PRI_BASE + 8)
39#define INT_VDE_SYNC_TOKEN (INT_PRI_BASE + 9)
40#define INT_VDE_BSE_V (INT_PRI_BASE + 10)
41#define INT_VDE_BSE_A (INT_PRI_BASE + 11)
42#define INT_VDE_SXE (INT_PRI_BASE + 12)
43#define INT_I2S1 (INT_PRI_BASE + 13)
44#define INT_SDMMC1 (INT_PRI_BASE + 14)
45#define INT_SDMMC2 (INT_PRI_BASE + 15)
46#define INT_XIO (INT_PRI_BASE + 16)
47#define INT_VDE (INT_PRI_BASE + 17)
48#define INT_AVP_UCQ (INT_PRI_BASE + 18)
49#define INT_SDMMC3 (INT_PRI_BASE + 19)
50#define INT_USB (INT_PRI_BASE + 20)
51#define INT_USB2 (INT_PRI_BASE + 21)
52#define INT_PRI_RES_22 (INT_PRI_BASE + 22)
53#define INT_EIDE (INT_PRI_BASE + 23)
54#define INT_NANDFLASH (INT_PRI_BASE + 24)
55#define INT_VCP (INT_PRI_BASE + 25)
56#define INT_APB_DMA (INT_PRI_BASE + 26)
57#define INT_AHB_DMA (INT_PRI_BASE + 27)
58#define INT_GNT_0 (INT_PRI_BASE + 28)
59#define INT_GNT_1 (INT_PRI_BASE + 29)
60#define INT_OWR (INT_PRI_BASE + 30)
61#define INT_SDMMC4 (INT_PRI_BASE + 31)
62
63/* Secondary Interrupt Controller */
64#define INT_SEC_BASE (INT_PRI_BASE + 32)
65#define INT_GPIO1 (INT_SEC_BASE + 0)
66#define INT_GPIO2 (INT_SEC_BASE + 1)
67#define INT_GPIO3 (INT_SEC_BASE + 2)
68#define INT_GPIO4 (INT_SEC_BASE + 3)
69#define INT_UARTA (INT_SEC_BASE + 4)
70#define INT_UARTB (INT_SEC_BASE + 5)
71#define INT_I2C (INT_SEC_BASE + 6)
72#define INT_SPI (INT_SEC_BASE + 7)
73#define INT_TWC (INT_SEC_BASE + 8)
74#define INT_TMR3 (INT_SEC_BASE + 9)
75#define INT_TMR4 (INT_SEC_BASE + 10)
76#define INT_FLOW_RSM0 (INT_SEC_BASE + 11)
77#define INT_FLOW_RSM1 (INT_SEC_BASE + 12)
78#define INT_SPDIF (INT_SEC_BASE + 13)
79#define INT_UARTC (INT_SEC_BASE + 14)
80#define INT_MIPI (INT_SEC_BASE + 15)
81#define INT_EVENTA (INT_SEC_BASE + 16)
82#define INT_EVENTB (INT_SEC_BASE + 17)
83#define INT_EVENTC (INT_SEC_BASE + 18)
84#define INT_EVENTD (INT_SEC_BASE + 19)
85#define INT_VFIR (INT_SEC_BASE + 20)
86#define INT_DVC (INT_SEC_BASE + 21)
87#define INT_SYS_STATS_MON (INT_SEC_BASE + 22)
88#define INT_GPIO5 (INT_SEC_BASE + 23)
89#define INT_CPU0_PMU_INTR (INT_SEC_BASE + 24)
90#define INT_CPU2_PMU_INTR (INT_SEC_BASE + 25)
91#define INT_SEC_RES_26 (INT_SEC_BASE + 26)
92#define INT_S_LINK1 (INT_SEC_BASE + 27)
93#define INT_APB_DMA_COP (INT_SEC_BASE + 28)
94#define INT_AHB_DMA_COP (INT_SEC_BASE + 29)
95#define INT_DMA_TX (INT_SEC_BASE + 30)
96#define INT_DMA_RX (INT_SEC_BASE + 31)
97
98/* Tertiary Interrupt Controller */
99#define INT_TRI_BASE (INT_SEC_BASE + 32)
100#define INT_HOST1X_COP_SYNCPT (INT_TRI_BASE + 0)
101#define INT_HOST1X_MPCORE_SYNCPT (INT_TRI_BASE + 1)
102#define INT_HOST1X_COP_GENERAL (INT_TRI_BASE + 2)
103#define INT_HOST1X_MPCORE_GENERAL (INT_TRI_BASE + 3)
104#define INT_MPE_GENERAL (INT_TRI_BASE + 4)
105#define INT_VI_GENERAL (INT_TRI_BASE + 5)
106#define INT_EPP_GENERAL (INT_TRI_BASE + 6)
107#define INT_ISP_GENERAL (INT_TRI_BASE + 7)
108#define INT_2D_GENERAL (INT_TRI_BASE + 8)
109#define INT_DISPLAY_GENERAL (INT_TRI_BASE + 9)
110#define INT_DISPLAY_B_GENERAL (INT_TRI_BASE + 10)
111#define INT_HDMI (INT_TRI_BASE + 11)
112#define INT_TVO_GENERAL (INT_TRI_BASE + 12)
113#define INT_MC_GENERAL (INT_TRI_BASE + 13)
114#define INT_EMC_GENERAL (INT_TRI_BASE + 14)
115#define INT_TRI_RES_15 (INT_TRI_BASE + 15)
116#define INT_TRI_RES_16 (INT_TRI_BASE + 16)
117#define INT_AC97 (INT_TRI_BASE + 17)
118#define INT_SPI_2 (INT_TRI_BASE + 18)
119#define INT_SPI_3 (INT_TRI_BASE + 19)
120#define INT_I2C2 (INT_TRI_BASE + 20)
121#define INT_KBC (INT_TRI_BASE + 21)
122#define INT_EXTERNAL_PMU (INT_TRI_BASE + 22)
123#define INT_GPIO6 (INT_TRI_BASE + 23)
124#define INT_TVDAC (INT_TRI_BASE + 24)
125#define INT_GPIO7 (INT_TRI_BASE + 25)
126#define INT_UARTD (INT_TRI_BASE + 26)
127#define INT_UARTE (INT_TRI_BASE + 27)
128#define INT_I2C3 (INT_TRI_BASE + 28)
129#define INT_SPI_4 (INT_TRI_BASE + 29)
130#define INT_TRI_RES_30 (INT_TRI_BASE + 30)
131#define INT_SW_RESERVED (INT_TRI_BASE + 31)
132
133/* Quaternary Interrupt Controller */
134#define INT_QUAD_BASE (INT_TRI_BASE + 32)
135#define INT_SNOR (INT_QUAD_BASE + 0)
136#define INT_USB3 (INT_QUAD_BASE + 1)
137#define INT_PCIE_INTR (INT_QUAD_BASE + 2)
138#define INT_PCIE_MSI (INT_QUAD_BASE + 3)
139#define INT_QUAD_RES_4 (INT_QUAD_BASE + 4)
140#define INT_QUAD_RES_5 (INT_QUAD_BASE + 5)
141#define INT_QUAD_RES_6 (INT_QUAD_BASE + 6)
142#define INT_QUAD_RES_7 (INT_QUAD_BASE + 7)
143#define INT_APB_DMA_CH0 (INT_QUAD_BASE + 8)
144#define INT_APB_DMA_CH1 (INT_QUAD_BASE + 9)
145#define INT_APB_DMA_CH2 (INT_QUAD_BASE + 10)
146#define INT_APB_DMA_CH3 (INT_QUAD_BASE + 11)
147#define INT_APB_DMA_CH4 (INT_QUAD_BASE + 12)
148#define INT_APB_DMA_CH5 (INT_QUAD_BASE + 13)
149#define INT_APB_DMA_CH6 (INT_QUAD_BASE + 14)
150#define INT_APB_DMA_CH7 (INT_QUAD_BASE + 15)
151#define INT_APB_DMA_CH8 (INT_QUAD_BASE + 16)
152#define INT_APB_DMA_CH9 (INT_QUAD_BASE + 17)
153#define INT_APB_DMA_CH10 (INT_QUAD_BASE + 18)
154#define INT_APB_DMA_CH11 (INT_QUAD_BASE + 19)
155#define INT_APB_DMA_CH12 (INT_QUAD_BASE + 20)
156#define INT_APB_DMA_CH13 (INT_QUAD_BASE + 21)
157#define INT_APB_DMA_CH14 (INT_QUAD_BASE + 22)
158#define INT_APB_DMA_CH15 (INT_QUAD_BASE + 23)
159#define INT_QUAD_RES_24 (INT_QUAD_BASE + 24)
160#define INT_QUAD_RES_25 (INT_QUAD_BASE + 25)
161#define INT_QUAD_RES_26 (INT_QUAD_BASE + 26)
162#define INT_QUAD_RES_27 (INT_QUAD_BASE + 27)
163#define INT_QUAD_RES_28 (INT_QUAD_BASE + 28)
164#define INT_QUAD_RES_29 (INT_QUAD_BASE + 29)
165#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30)
166#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31)
167
168#define INT_GPIO_BASE (INT_QUAD_BASE + 32)
169#define INT_GPIO_NR (28 * 8)
170
171#define NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR)
172
173#endif
diff --git a/arch/arm/mach-tegra/include/mach/memory.h b/arch/arm/mach-tegra/include/mach/memory.h
new file mode 100644
index 000000000000..6151bab62af2
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/memory.h
@@ -0,0 +1,28 @@
1/*
2 * arch/arm/mach-tegra/include/mach/memory.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Erik Gilling <konkers@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#ifndef __MACH_TEGRA_MEMORY_H
22#define __MACH_TEGRA_MEMORY_H
23
24/* physical offset of RAM */
25#define PHYS_OFFSET UL(0)
26
27#endif
28
diff --git a/arch/arm/mach-tegra/include/mach/pinmux.h b/arch/arm/mach-tegra/include/mach/pinmux.h
new file mode 100644
index 000000000000..41c8ce5b7c27
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pinmux.h
@@ -0,0 +1,348 @@
1/*
2 * linux/arch/arm/mach-tegra/include/mach/pinmux.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef __MACH_TEGRA_PINMUX_H
18#define __MACH_TEGRA_PINMUX_H
19
20enum tegra_pingroup {
21 TEGRA_PINGROUP_ATA = 0,
22 TEGRA_PINGROUP_ATB,
23 TEGRA_PINGROUP_ATC,
24 TEGRA_PINGROUP_ATD,
25 TEGRA_PINGROUP_ATE,
26 TEGRA_PINGROUP_CDEV1,
27 TEGRA_PINGROUP_CDEV2,
28 TEGRA_PINGROUP_CRTP,
29 TEGRA_PINGROUP_CSUS,
30 TEGRA_PINGROUP_DAP1,
31 TEGRA_PINGROUP_DAP2,
32 TEGRA_PINGROUP_DAP3,
33 TEGRA_PINGROUP_DAP4,
34 TEGRA_PINGROUP_DDC,
35 TEGRA_PINGROUP_DTA,
36 TEGRA_PINGROUP_DTB,
37 TEGRA_PINGROUP_DTC,
38 TEGRA_PINGROUP_DTD,
39 TEGRA_PINGROUP_DTE,
40 TEGRA_PINGROUP_DTF,
41 TEGRA_PINGROUP_GMA,
42 TEGRA_PINGROUP_GMB,
43 TEGRA_PINGROUP_GMC,
44 TEGRA_PINGROUP_GMD,
45 TEGRA_PINGROUP_GME,
46 TEGRA_PINGROUP_GPU,
47 TEGRA_PINGROUP_GPU7,
48 TEGRA_PINGROUP_GPV,
49 TEGRA_PINGROUP_HDINT,
50 TEGRA_PINGROUP_I2CP,
51 TEGRA_PINGROUP_IRRX,
52 TEGRA_PINGROUP_IRTX,
53 TEGRA_PINGROUP_KBCA,
54 TEGRA_PINGROUP_KBCB,
55 TEGRA_PINGROUP_KBCC,
56 TEGRA_PINGROUP_KBCD,
57 TEGRA_PINGROUP_KBCE,
58 TEGRA_PINGROUP_KBCF,
59 TEGRA_PINGROUP_LCSN,
60 TEGRA_PINGROUP_LD0,
61 TEGRA_PINGROUP_LD1,
62 TEGRA_PINGROUP_LD10,
63 TEGRA_PINGROUP_LD11,
64 TEGRA_PINGROUP_LD12,
65 TEGRA_PINGROUP_LD13,
66 TEGRA_PINGROUP_LD14,
67 TEGRA_PINGROUP_LD15,
68 TEGRA_PINGROUP_LD16,
69 TEGRA_PINGROUP_LD17,
70 TEGRA_PINGROUP_LD2,
71 TEGRA_PINGROUP_LD3,
72 TEGRA_PINGROUP_LD4,
73 TEGRA_PINGROUP_LD5,
74 TEGRA_PINGROUP_LD6,
75 TEGRA_PINGROUP_LD7,
76 TEGRA_PINGROUP_LD8,
77 TEGRA_PINGROUP_LD9,
78 TEGRA_PINGROUP_LDC,
79 TEGRA_PINGROUP_LDI,
80 TEGRA_PINGROUP_LHP0,
81 TEGRA_PINGROUP_LHP1,
82 TEGRA_PINGROUP_LHP2,
83 TEGRA_PINGROUP_LHS,
84 TEGRA_PINGROUP_LM0,
85 TEGRA_PINGROUP_LM1,
86 TEGRA_PINGROUP_LPP,
87 TEGRA_PINGROUP_LPW0,
88 TEGRA_PINGROUP_LPW1,
89 TEGRA_PINGROUP_LPW2,
90 TEGRA_PINGROUP_LSC0,
91 TEGRA_PINGROUP_LSC1,
92 TEGRA_PINGROUP_LSCK,
93 TEGRA_PINGROUP_LSDA,
94 TEGRA_PINGROUP_LSDI,
95 TEGRA_PINGROUP_LSPI,
96 TEGRA_PINGROUP_LVP0,
97 TEGRA_PINGROUP_LVP1,
98 TEGRA_PINGROUP_LVS,
99 TEGRA_PINGROUP_OWC,
100 TEGRA_PINGROUP_PMC,
101 TEGRA_PINGROUP_PTA,
102 TEGRA_PINGROUP_RM,
103 TEGRA_PINGROUP_SDB,
104 TEGRA_PINGROUP_SDC,
105 TEGRA_PINGROUP_SDD,
106 TEGRA_PINGROUP_SDIO1,
107 TEGRA_PINGROUP_SLXA,
108 TEGRA_PINGROUP_SLXC,
109 TEGRA_PINGROUP_SLXD,
110 TEGRA_PINGROUP_SLXK,
111 TEGRA_PINGROUP_SPDI,
112 TEGRA_PINGROUP_SPDO,
113 TEGRA_PINGROUP_SPIA,
114 TEGRA_PINGROUP_SPIB,
115 TEGRA_PINGROUP_SPIC,
116 TEGRA_PINGROUP_SPID,
117 TEGRA_PINGROUP_SPIE,
118 TEGRA_PINGROUP_SPIF,
119 TEGRA_PINGROUP_SPIG,
120 TEGRA_PINGROUP_SPIH,
121 TEGRA_PINGROUP_UAA,
122 TEGRA_PINGROUP_UAB,
123 TEGRA_PINGROUP_UAC,
124 TEGRA_PINGROUP_UAD,
125 TEGRA_PINGROUP_UCA,
126 TEGRA_PINGROUP_UCB,
127 TEGRA_PINGROUP_UDA,
128 /* these pin groups only have pullup and pull down control */
129 TEGRA_PINGROUP_CK32,
130 TEGRA_PINGROUP_DDRC,
131 TEGRA_PINGROUP_PMCA,
132 TEGRA_PINGROUP_PMCB,
133 TEGRA_PINGROUP_PMCC,
134 TEGRA_PINGROUP_PMCD,
135 TEGRA_PINGROUP_PMCE,
136 TEGRA_PINGROUP_XM2C,
137 TEGRA_PINGROUP_XM2D,
138 TEGRA_MAX_PINGROUP,
139};
140
141enum tegra_mux_func {
142 TEGRA_MUX_RSVD = 0x8000,
143 TEGRA_MUX_RSVD1 = 0x8000,
144 TEGRA_MUX_RSVD2 = 0x8001,
145 TEGRA_MUX_RSVD3 = 0x8002,
146 TEGRA_MUX_RSVD4 = 0x8003,
147 TEGRA_MUX_NONE = -1,
148 TEGRA_MUX_AHB_CLK,
149 TEGRA_MUX_APB_CLK,
150 TEGRA_MUX_AUDIO_SYNC,
151 TEGRA_MUX_CRT,
152 TEGRA_MUX_DAP1,
153 TEGRA_MUX_DAP2,
154 TEGRA_MUX_DAP3,
155 TEGRA_MUX_DAP4,
156 TEGRA_MUX_DAP5,
157 TEGRA_MUX_DISPLAYA,
158 TEGRA_MUX_DISPLAYB,
159 TEGRA_MUX_EMC_TEST0_DLL,
160 TEGRA_MUX_EMC_TEST1_DLL,
161 TEGRA_MUX_GMI,
162 TEGRA_MUX_GMI_INT,
163 TEGRA_MUX_HDMI,
164 TEGRA_MUX_I2C,
165 TEGRA_MUX_I2C2,
166 TEGRA_MUX_I2C3,
167 TEGRA_MUX_IDE,
168 TEGRA_MUX_IRDA,
169 TEGRA_MUX_KBC,
170 TEGRA_MUX_MIO,
171 TEGRA_MUX_MIPI_HS,
172 TEGRA_MUX_NAND,
173 TEGRA_MUX_OSC,
174 TEGRA_MUX_OWR,
175 TEGRA_MUX_PCIE,
176 TEGRA_MUX_PLLA_OUT,
177 TEGRA_MUX_PLLC_OUT1,
178 TEGRA_MUX_PLLM_OUT1,
179 TEGRA_MUX_PLLP_OUT2,
180 TEGRA_MUX_PLLP_OUT3,
181 TEGRA_MUX_PLLP_OUT4,
182 TEGRA_MUX_PWM,
183 TEGRA_MUX_PWR_INTR,
184 TEGRA_MUX_PWR_ON,
185 TEGRA_MUX_RTCK,
186 TEGRA_MUX_SDIO1,
187 TEGRA_MUX_SDIO2,
188 TEGRA_MUX_SDIO3,
189 TEGRA_MUX_SDIO4,
190 TEGRA_MUX_SFLASH,
191 TEGRA_MUX_SPDIF,
192 TEGRA_MUX_SPI1,
193 TEGRA_MUX_SPI2,
194 TEGRA_MUX_SPI2_ALT,
195 TEGRA_MUX_SPI3,
196 TEGRA_MUX_SPI4,
197 TEGRA_MUX_TRACE,
198 TEGRA_MUX_TWC,
199 TEGRA_MUX_UARTA,
200 TEGRA_MUX_UARTB,
201 TEGRA_MUX_UARTC,
202 TEGRA_MUX_UARTD,
203 TEGRA_MUX_UARTE,
204 TEGRA_MUX_ULPI,
205 TEGRA_MUX_VI,
206 TEGRA_MUX_VI_SENSOR_CLK,
207 TEGRA_MUX_XIO,
208 TEGRA_MAX_MUX,
209};
210
211enum tegra_pullupdown {
212 TEGRA_PUPD_NORMAL = 0,
213 TEGRA_PUPD_PULL_DOWN,
214 TEGRA_PUPD_PULL_UP,
215};
216
217enum tegra_tristate {
218 TEGRA_TRI_NORMAL = 0,
219 TEGRA_TRI_TRISTATE = 1,
220};
221
222struct tegra_pingroup_config {
223 enum tegra_pingroup pingroup;
224 enum tegra_mux_func func;
225 enum tegra_pullupdown pupd;
226 enum tegra_tristate tristate;
227};
228
229enum tegra_slew {
230 TEGRA_SLEW_FASTEST = 0,
231 TEGRA_SLEW_FAST,
232 TEGRA_SLEW_SLOW,
233 TEGRA_SLEW_SLOWEST,
234 TEGRA_MAX_SLEW,
235};
236
237enum tegra_pull_strength {
238 TEGRA_PULL_0 = 0,
239 TEGRA_PULL_1,
240 TEGRA_PULL_2,
241 TEGRA_PULL_3,
242 TEGRA_PULL_4,
243 TEGRA_PULL_5,
244 TEGRA_PULL_6,
245 TEGRA_PULL_7,
246 TEGRA_PULL_8,
247 TEGRA_PULL_9,
248 TEGRA_PULL_10,
249 TEGRA_PULL_11,
250 TEGRA_PULL_12,
251 TEGRA_PULL_13,
252 TEGRA_PULL_14,
253 TEGRA_PULL_15,
254 TEGRA_PULL_16,
255 TEGRA_PULL_17,
256 TEGRA_PULL_18,
257 TEGRA_PULL_19,
258 TEGRA_PULL_20,
259 TEGRA_PULL_21,
260 TEGRA_PULL_22,
261 TEGRA_PULL_23,
262 TEGRA_PULL_24,
263 TEGRA_PULL_25,
264 TEGRA_PULL_26,
265 TEGRA_PULL_27,
266 TEGRA_PULL_28,
267 TEGRA_PULL_29,
268 TEGRA_PULL_30,
269 TEGRA_PULL_31,
270 TEGRA_MAX_PULL,
271};
272
273enum tegra_drive_pingroup {
274 TEGRA_DRIVE_PINGROUP_AO1 = 0,
275 TEGRA_DRIVE_PINGROUP_AO2,
276 TEGRA_DRIVE_PINGROUP_AT1,
277 TEGRA_DRIVE_PINGROUP_AT2,
278 TEGRA_DRIVE_PINGROUP_CDEV1,
279 TEGRA_DRIVE_PINGROUP_CDEV2,
280 TEGRA_DRIVE_PINGROUP_CSUS,
281 TEGRA_DRIVE_PINGROUP_DAP1,
282 TEGRA_DRIVE_PINGROUP_DAP2,
283 TEGRA_DRIVE_PINGROUP_DAP3,
284 TEGRA_DRIVE_PINGROUP_DAP4,
285 TEGRA_DRIVE_PINGROUP_DBG,
286 TEGRA_DRIVE_PINGROUP_LCD1,
287 TEGRA_DRIVE_PINGROUP_LCD2,
288 TEGRA_DRIVE_PINGROUP_SDMMC2,
289 TEGRA_DRIVE_PINGROUP_SDMMC3,
290 TEGRA_DRIVE_PINGROUP_SPI,
291 TEGRA_DRIVE_PINGROUP_UAA,
292 TEGRA_DRIVE_PINGROUP_UAB,
293 TEGRA_DRIVE_PINGROUP_UART2,
294 TEGRA_DRIVE_PINGROUP_UART3,
295 TEGRA_DRIVE_PINGROUP_VI1,
296 TEGRA_DRIVE_PINGROUP_VI2,
297 TEGRA_DRIVE_PINGROUP_XM2A,
298 TEGRA_DRIVE_PINGROUP_XM2C,
299 TEGRA_DRIVE_PINGROUP_XM2D,
300 TEGRA_DRIVE_PINGROUP_XM2CLK,
301 TEGRA_DRIVE_PINGROUP_MEMCOMP,
302 TEGRA_MAX_DRIVE_PINGROUP,
303};
304
305enum tegra_drive {
306 TEGRA_DRIVE_DIV_8 = 0,
307 TEGRA_DRIVE_DIV_4,
308 TEGRA_DRIVE_DIV_2,
309 TEGRA_DRIVE_DIV_1,
310 TEGRA_MAX_DRIVE,
311};
312
313enum tegra_hsm {
314 TEGRA_HSM_DISABLE = 0,
315 TEGRA_HSM_ENABLE,
316};
317
318enum tegra_schmitt {
319 TEGRA_SCHMITT_DISABLE = 0,
320 TEGRA_SCHMITT_ENABLE,
321};
322
323struct tegra_drive_pingroup_config {
324 enum tegra_drive_pingroup pingroup;
325 enum tegra_hsm hsm;
326 enum tegra_schmitt schmitt;
327 enum tegra_drive drive;
328 enum tegra_pull_strength pull_down;
329 enum tegra_pull_strength pull_up;
330 enum tegra_slew slew_rising;
331 enum tegra_slew slew_falling;
332};
333
334int tegra_pinmux_set_func(enum tegra_pingroup pg, enum tegra_mux_func func);
335int tegra_pinmux_set_tristate(enum tegra_pingroup pg, enum tegra_tristate tristate);
336int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, enum tegra_pullupdown pupd);
337
338void tegra_pinmux_config_pingroup(enum tegra_pingroup pingroup,
339 enum tegra_mux_func func, enum tegra_pullupdown pupd,
340 enum tegra_tristate tristate);
341
342void tegra_pinmux_config_table(struct tegra_pingroup_config *config, int len);
343
344void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
345 int len);
346
347#endif
348
diff --git a/arch/arm/mach-tegra/include/mach/smp.h b/arch/arm/mach-tegra/include/mach/smp.h
new file mode 100644
index 000000000000..8b42dab79a70
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/smp.h
@@ -0,0 +1,30 @@
1#ifndef ASMARM_ARCH_SMP_H
2#define ASMARM_ARCH_SMP_H
3
4
5#include <asm/hardware/gic.h>
6
7#define hard_smp_processor_id() \
8 ({ \
9 unsigned int cpunum; \
10 __asm__("mrc p15, 0, %0, c0, c0, 5" \
11 : "=r" (cpunum)); \
12 cpunum &= 0x0F; \
13 })
14
15/*
16 * We use IRQ1 as the IPI
17 */
18static inline void smp_cross_call(const struct cpumask *mask)
19{
20 gic_raise_softirq(mask, 1);
21}
22
23/*
24 * Do nothing on MPcore.
25 */
26static inline void smp_cross_call_done(cpumask_t callmap)
27{
28}
29
30#endif
diff --git a/arch/arm/mach-tegra/include/mach/system.h b/arch/arm/mach-tegra/include/mach/system.h
new file mode 100644
index 000000000000..84d5d46113f7
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/system.h
@@ -0,0 +1,39 @@
1/*
2 * arch/arm/mach-tegra/include/mach/system.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Erik Gilling <konkers@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#ifndef __MACH_TEGRA_SYSTEM_H
22#define __MACH_TEGRA_SYSTEM_H
23
24#include <mach/hardware.h>
25#include <mach/iomap.h>
26
27static inline void arch_idle(void)
28{
29}
30
31static inline void arch_reset(char mode, const char *cmd)
32{
33 void __iomem *reset = IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x04);
34 u32 reg = readl(reset);
35 reg |= 0x04;
36 writel(reg, reset);
37}
38
39#endif
diff --git a/arch/arm/mach-tegra/include/mach/timex.h b/arch/arm/mach-tegra/include/mach/timex.h
new file mode 100644
index 000000000000..a44ccbdb7dbf
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/timex.h
@@ -0,0 +1,26 @@
1/*
2 * arch/arm/mach-tegra/include/mach/timex.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Erik Gilling <konkers@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#ifndef __MACH_TEGRA_TIMEX_H
22#define __MACH_TEGRA_TIMEX_H
23
24#define CLOCK_TICK_RATE 1000000
25
26#endif
diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h
new file mode 100644
index 000000000000..6c4dd815abd7
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/uncompress.h
@@ -0,0 +1,78 @@
1/*
2 * arch/arm/mach-tegra/include/mach/uncompress.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Erik Gilling <konkers@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#ifndef __MACH_TEGRA_UNCOMPRESS_H
22#define __MACH_TEGRA_UNCOMPRESS_H
23
24#include <linux/types.h>
25#include <linux/serial_reg.h>
26
27#include <mach/iomap.h>
28
29#if defined(CONFIG_TEGRA_DEBUG_UARTA)
30#define DEBUG_UART_BASE TEGRA_UARTA_BASE
31#elif defined(CONFIG_TEGRA_DEBUG_UARTB)
32#define DEBUG_UART_BASE TEGRA_UARTB_BASE
33#elif defined(CONFIG_TEGRA_DEBUG_UARTC)
34#define DEBUG_UART_BASE TEGRA_UARTC_BASE
35#elif defined(CONFIG_TEGRA_DEBUG_UARTD)
36#define DEBUG_UART_BASE TEGRA_UARTD_BASE
37#elif defined(CONFIG_TEGRA_DEBUG_UARTE)
38#define DEBUG_UART_BASE TEGRA_UARTE_BASE
39#else
40#define DEBUG_UART_BASE NULL
41#endif
42
43static void putc(int c)
44{
45 volatile u8 *uart = (volatile u8 *)DEBUG_UART_BASE;
46 int shift = 2;
47
48 if (uart == NULL)
49 return;
50
51 while (!(uart[UART_LSR << shift] & UART_LSR_THRE))
52 barrier();
53 uart[UART_TX << shift] = c;
54}
55
56static inline void flush(void)
57{
58}
59
60static inline void arch_decomp_setup(void)
61{
62 volatile u8 *uart = (volatile u8 *)DEBUG_UART_BASE;
63 int shift = 2;
64
65 if (uart == NULL)
66 return;
67
68 uart[UART_LCR << shift] |= UART_LCR_DLAB;
69 uart[UART_DLL << shift] = 0x75;
70 uart[UART_DLM << shift] = 0x0;
71 uart[UART_LCR << shift] = 3;
72}
73
74static inline void arch_decomp_wdog(void)
75{
76}
77
78#endif
diff --git a/arch/arm/mach-tegra/include/mach/vmalloc.h b/arch/arm/mach-tegra/include/mach/vmalloc.h
new file mode 100644
index 000000000000..267a141730d9
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/vmalloc.h
@@ -0,0 +1,28 @@
1/*
2 * arch/arm/mach-tegra/include/mach/vmalloc.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Erik Gilling <konkers@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#ifndef __MACH_TEGRA_VMALLOC_H
22#define __MACH_TEGRA_VMALLOC_H
23
24#include <asm/sizes.h>
25
26#define VMALLOC_END 0xFE000000
27
28#endif
diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c
new file mode 100644
index 000000000000..9fe2c5c683d4
--- /dev/null
+++ b/arch/arm/mach-tegra/io.c
@@ -0,0 +1,78 @@
1/*
2 * arch/arm/mach-tegra/io.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * Erik Gilling <konkers@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/mm.h>
25#include <linux/io.h>
26
27#include <mach/hardware.h>
28#include <asm/page.h>
29#include <asm/mach/map.h>
30
31#include "board.h"
32
33static struct map_desc tegra_io_desc[] __initdata = {
34 {
35 .virtual = IO_PPSB_VIRT,
36 .pfn = __phys_to_pfn(IO_PPSB_PHYS),
37 .length = IO_PPSB_SIZE,
38 .type = MT_DEVICE,
39 },
40 {
41 .virtual = IO_APB_VIRT,
42 .pfn = __phys_to_pfn(IO_APB_PHYS),
43 .length = IO_APB_SIZE,
44 .type = MT_DEVICE,
45 },
46 {
47 .virtual = IO_CPU_VIRT,
48 .pfn = __phys_to_pfn(IO_CPU_PHYS),
49 .length = IO_CPU_SIZE,
50 .type = MT_DEVICE,
51 },
52};
53
54void __init tegra_map_common_io(void)
55{
56 iotable_init(tegra_io_desc, ARRAY_SIZE(tegra_io_desc));
57}
58
59/*
60 * Intercept ioremap() requests for addresses in our fixed mapping regions.
61 */
62void __iomem *tegra_ioremap(unsigned long p, size_t size, unsigned int type)
63{
64 void __iomem *v = IO_ADDRESS(p);
65 if (v == NULL)
66 v = __arm_ioremap(p, size, type);
67 return v;
68}
69EXPORT_SYMBOL(tegra_ioremap);
70
71void tegra_iounmap(volatile void __iomem *addr)
72{
73 unsigned long virt = (unsigned long)addr;
74
75 if (virt >= VMALLOC_START && virt < VMALLOC_END)
76 __iounmap(addr);
77}
78EXPORT_SYMBOL(tegra_iounmap);
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
new file mode 100644
index 000000000000..1fdbe708d43d
--- /dev/null
+++ b/arch/arm/mach-tegra/irq.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2010 Google, Inc.
3 *
4 * Author:
5 * Colin Cross <ccross@google.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/interrupt.h>
21#include <linux/irq.h>
22#include <linux/io.h>
23
24#include <asm/hardware/gic.h>
25
26#include <mach/iomap.h>
27
28#include "board.h"
29
30void __init tegra_init_irq(void)
31{
32 gic_dist_init(0, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 29);
33 gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
34}
diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c
new file mode 100644
index 000000000000..f81ca7cbbc1f
--- /dev/null
+++ b/arch/arm/mach-tegra/localtimer.c
@@ -0,0 +1,25 @@
1/*
2 * arch/arm/mach-tegra/localtimer.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/init.h>
12#include <linux/smp.h>
13#include <linux/clockchips.h>
14#include <asm/irq.h>
15#include <asm/smp_twd.h>
16#include <asm/localtimer.h>
17
18/*
19 * Setup the local clock events for a CPU.
20 */
21void __cpuinit local_timer_setup(struct clock_event_device *evt)
22{
23 evt->irq = IRQ_LOCALTIMER;
24 twd_timer_setup(evt);
25}
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
new file mode 100644
index 000000000000..13ae10237e84
--- /dev/null
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -0,0 +1,945 @@
1/*
2 * linux/arch/arm/mach-tegra/pinmux.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17
18#include <linux/kernel.h>
19#include <linux/errno.h>
20#include <linux/spinlock.h>
21#include <linux/io.h>
22
23#include <mach/iomap.h>
24#include <mach/pinmux.h>
25
26
27#define TEGRA_TRI_STATE(x) (0x14 + (4 * (x)))
28#define TEGRA_PP_MUX_CTL(x) (0x80 + (4 * (x)))
29#define TEGRA_PP_PU_PD(x) (0xa0 + (4 * (x)))
30
31#define REG_A 0
32#define REG_B 1
33#define REG_C 2
34#define REG_D 3
35#define REG_E 4
36#define REG_F 5
37#define REG_G 6
38
39#define REG_N -1
40
41#define HSM_EN(reg) (((reg) >> 2) & 0x1)
42#define SCHMT_EN(reg) (((reg) >> 3) & 0x1)
43#define LPMD(reg) (((reg) >> 4) & 0x3)
44#define DRVDN(reg) (((reg) >> 12) & 0x1f)
45#define DRVUP(reg) (((reg) >> 20) & 0x1f)
46#define SLWR(reg) (((reg) >> 28) & 0x3)
47#define SLWF(reg) (((reg) >> 30) & 0x3)
48
49struct tegra_pingroup_desc {
50 const char *name;
51 int funcs[4];
52 s8 tri_reg; /* offset into the TRISTATE_REG_* register bank */
53 s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */
54 s8 mux_reg; /* offset into the PIN_MUX_CTL_* register bank */
55 s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */
56 s8 pupd_reg; /* offset into the PULL_UPDOWN_REG_* register bank */
57 s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */
58};
59
60#define PINGROUP(pg_name, f0, f1, f2, f3, \
61 tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b) \
62 [TEGRA_PINGROUP_ ## pg_name] = { \
63 .name = #pg_name, \
64 .funcs = { \
65 TEGRA_MUX_ ## f0, \
66 TEGRA_MUX_ ## f1, \
67 TEGRA_MUX_ ## f2, \
68 TEGRA_MUX_ ## f3, \
69 }, \
70 .tri_reg = REG_ ## tri_r, \
71 .tri_bit = tri_b, \
72 .mux_reg = REG_ ## mux_r, \
73 .mux_bit = mux_b, \
74 .pupd_reg = REG_ ## pupd_r, \
75 .pupd_bit = pupd_b, \
76 }
77
78static const struct tegra_pingroup_desc pingroups[TEGRA_MAX_PINGROUP] = {
79 PINGROUP(ATA, IDE, NAND, GMI, RSVD, A, 0, A, 24, A, 0),
80 PINGROUP(ATB, IDE, NAND, GMI, SDIO4, A, 1, A, 16, A, 2),
81 PINGROUP(ATC, IDE, NAND, GMI, SDIO4, A, 2, A, 22, A, 4),
82 PINGROUP(ATD, IDE, NAND, GMI, SDIO4, A, 3, A, 20, A, 6),
83 PINGROUP(ATE, IDE, NAND, GMI, RSVD, B, 25, A, 12, A, 8),
84 PINGROUP(CDEV1, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, A, 4, C, 2, C, 0),
85 PINGROUP(CDEV2, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, A, 5, C, 4, C, 2),
86 PINGROUP(CRTP, CRT, RSVD, RSVD, RSVD, D, 14, G, 20, B, 24),
87 PINGROUP(CSUS, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, A, 6, C, 6, D, 24),
88 PINGROUP(DAP1, DAP1, RSVD, GMI, SDIO2, A, 7, C, 20, A, 10),
89 PINGROUP(DAP2, DAP2, TWC, RSVD, GMI, A, 8, C, 22, A, 12),
90 PINGROUP(DAP3, DAP3, RSVD, RSVD, RSVD, A, 9, C, 24, A, 14),
91 PINGROUP(DAP4, DAP4, RSVD, GMI, RSVD, A, 10, C, 26, A, 16),
92 PINGROUP(DDC, I2C2, RSVD, RSVD, RSVD, B, 31, C, 0, E, 28),
93 PINGROUP(DTA, RSVD, SDIO2, VI, RSVD, A, 11, B, 20, A, 18),
94 PINGROUP(DTB, RSVD, RSVD, VI, SPI1, A, 12, B, 22, A, 20),
95 PINGROUP(DTC, RSVD, RSVD, VI, RSVD, A, 13, B, 26, A, 22),
96 PINGROUP(DTD, RSVD, SDIO2, VI, RSVD, A, 14, B, 28, A, 24),
97 PINGROUP(DTE, RSVD, RSVD, VI, SPI1, A, 15, B, 30, A, 26),
98 PINGROUP(DTF, I2C3, RSVD, VI, RSVD, D, 12, G, 30, A, 28),
99 PINGROUP(GMA, UARTE, SPI3, GMI, SDIO4, A, 28, B, 0, E, 20),
100 PINGROUP(GMB, IDE, NAND, GMI, GMI_INT, B, 29, C, 28, E, 22),
101 PINGROUP(GMC, UARTD, SPI4, GMI, SFLASH, A, 29, B, 2, E, 24),
102 PINGROUP(GMD, RSVD, NAND, GMI, SFLASH, B, 30, C, 30, E, 26),
103 PINGROUP(GME, RSVD, DAP5, GMI, SDIO4, B, 0, D, 0, C, 24),
104 PINGROUP(GPU, PWM, UARTA, GMI, RSVD, A, 16, D, 4, B, 20),
105 PINGROUP(GPU7, RTCK, RSVD, RSVD, RSVD, D, 11, G, 28, B, 6),
106 PINGROUP(GPV, PCIE, RSVD, RSVD, RSVD, A, 17, D, 2, A, 30),
107 PINGROUP(HDINT, HDMI, RSVD, RSVD, RSVD, C, 23, B, 4, D, 22),
108 PINGROUP(I2CP, I2C, RSVD, RSVD, RSVD, A, 18, C, 8, B, 2),
109 PINGROUP(IRRX, UARTA, UARTB, GMI, SPI4, A, 20, C, 18, C, 22),
110 PINGROUP(IRTX, UARTA, UARTB, GMI, SPI4, A, 19, C, 16, C, 20),
111 PINGROUP(KBCA, KBC, NAND, SDIO2, EMC_TEST0_DLL, A, 22, C, 10, B, 8),
112 PINGROUP(KBCB, KBC, NAND, SDIO2, MIO, A, 21, C, 12, B, 10),
113 PINGROUP(KBCC, KBC, NAND, TRACE, EMC_TEST1_DLL, B, 26, C, 14, B, 12),
114 PINGROUP(KBCD, KBC, NAND, SDIO2, MIO, D, 10, G, 26, B, 14),
115 PINGROUP(KBCE, KBC, NAND, OWR, RSVD, A, 26, A, 28, E, 2),
116 PINGROUP(KBCF, KBC, NAND, TRACE, MIO, A, 27, A, 26, E, 0),
117 PINGROUP(LCSN, DISPLAYA, DISPLAYB, SPI3, RSVD, C, 31, E, 12, D, 20),
118 PINGROUP(LD0, DISPLAYA, DISPLAYB, XIO, RSVD, C, 0, F, 0, D, 12),
119 PINGROUP(LD1, DISPLAYA, DISPLAYB, XIO, RSVD, C, 1, F, 2, D, 12),
120 PINGROUP(LD10, DISPLAYA, DISPLAYB, XIO, RSVD, C, 10, F, 20, D, 12),
121 PINGROUP(LD11, DISPLAYA, DISPLAYB, XIO, RSVD, C, 11, F, 22, D, 12),
122 PINGROUP(LD12, DISPLAYA, DISPLAYB, XIO, RSVD, C, 12, F, 24, D, 12),
123 PINGROUP(LD13, DISPLAYA, DISPLAYB, XIO, RSVD, C, 13, F, 26, D, 12),
124 PINGROUP(LD14, DISPLAYA, DISPLAYB, XIO, RSVD, C, 14, F, 28, D, 12),
125 PINGROUP(LD15, DISPLAYA, DISPLAYB, XIO, RSVD, C, 15, F, 30, D, 12),
126 PINGROUP(LD16, DISPLAYA, DISPLAYB, XIO, RSVD, C, 16, G, 0, D, 12),
127 PINGROUP(LD17, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 17, G, 2, D, 12),
128 PINGROUP(LD2, DISPLAYA, DISPLAYB, XIO, RSVD, C, 2, F, 4, D, 12),
129 PINGROUP(LD3, DISPLAYA, DISPLAYB, XIO, RSVD, C, 3, F, 6, D, 12),
130 PINGROUP(LD4, DISPLAYA, DISPLAYB, XIO, RSVD, C, 4, F, 8, D, 12),
131 PINGROUP(LD5, DISPLAYA, DISPLAYB, XIO, RSVD, C, 5, F, 10, D, 12),
132 PINGROUP(LD6, DISPLAYA, DISPLAYB, XIO, RSVD, C, 6, F, 12, D, 12),
133 PINGROUP(LD7, DISPLAYA, DISPLAYB, XIO, RSVD, C, 7, F, 14, D, 12),
134 PINGROUP(LD8, DISPLAYA, DISPLAYB, XIO, RSVD, C, 8, F, 16, D, 12),
135 PINGROUP(LD9, DISPLAYA, DISPLAYB, XIO, RSVD, C, 9, F, 18, D, 12),
136 PINGROUP(LDC, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 30, E, 14, D, 20),
137 PINGROUP(LDI, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 6, G, 16, D, 18),
138 PINGROUP(LHP0, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 18, G, 10, D, 16),
139 PINGROUP(LHP1, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 19, G, 4, D, 14),
140 PINGROUP(LHP2, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 20, G, 6, D, 14),
141 PINGROUP(LHS, DISPLAYA, DISPLAYB, XIO, RSVD, D, 7, E, 22, D, 22),
142 PINGROUP(LM0, DISPLAYA, DISPLAYB, SPI3, RSVD, C, 24, E, 26, D, 22),
143 PINGROUP(LM1, DISPLAYA, DISPLAYB, RSVD, CRT, C, 25, E, 28, D, 22),
144 PINGROUP(LPP, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 8, G, 14, D, 18),
145 PINGROUP(LPW0, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 3, E, 0, D, 20),
146 PINGROUP(LPW1, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 4, E, 2, D, 20),
147 PINGROUP(LPW2, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 5, E, 4, D, 20),
148 PINGROUP(LSC0, DISPLAYA, DISPLAYB, XIO, RSVD, C, 27, E, 18, D, 22),
149 PINGROUP(LSC1, DISPLAYA, DISPLAYB, SPI3, HDMI, C, 28, E, 20, D, 20),
150 PINGROUP(LSCK, DISPLAYA, DISPLAYB, SPI3, HDMI, C, 29, E, 16, D, 20),
151 PINGROUP(LSDA, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 1, E, 8, D, 20),
152 PINGROUP(LSDI, DISPLAYA, DISPLAYB, SPI3, RSVD, D, 2, E, 6, D, 20),
153 PINGROUP(LSPI, DISPLAYA, DISPLAYB, XIO, HDMI, D, 0, E, 10, D, 22),
154 PINGROUP(LVP0, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 21, E, 30, D, 22),
155 PINGROUP(LVP1, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 22, G, 8, D, 16),
156 PINGROUP(LVS, DISPLAYA, DISPLAYB, XIO, RSVD, C, 26, E, 24, D, 22),
157 PINGROUP(OWC, OWR, RSVD, RSVD, RSVD, A, 31, B, 8, E, 30),
158 PINGROUP(PMC, PWR_ON, PWR_INTR, RSVD, RSVD, A, 23, G, 18, N, -1),
159 PINGROUP(PTA, I2C2, HDMI, GMI, RSVD, A, 24, G, 22, B, 4),
160 PINGROUP(RM, I2C, RSVD, RSVD, RSVD, A, 25, A, 14, B, 0),
161 PINGROUP(SDB, UARTA, PWM, SDIO3, SPI2, D, 15, D, 10, N, -1),
162 PINGROUP(SDC, PWM, TWC, SDIO3, SPI3, B, 1, D, 12, D, 28),
163 PINGROUP(SDD, UARTA, PWM, SDIO3, SPI3, B, 2, D, 14, D, 30),
164 PINGROUP(SDIO1, SDIO1, RSVD, UARTE, UARTA, A, 30, A, 30, E, 18),
165 PINGROUP(SLXA, PCIE, SPI4, SDIO3, SPI2, B, 3, B, 6, B, 22),
166 PINGROUP(SLXC, SPDIF, SPI4, SDIO3, SPI2, B, 5, B, 10, B, 26),
167 PINGROUP(SLXD, SPDIF, SPI4, SDIO3, SPI2, B, 6, B, 12, B, 28),
168 PINGROUP(SLXK, PCIE, SPI4, SDIO3, SPI2, B, 7, B, 14, B, 30),
169 PINGROUP(SPDI, SPDIF, RSVD, I2C, SDIO2, B, 8, D, 8, B, 16),
170 PINGROUP(SPDO, SPDIF, RSVD, I2C, SDIO2, B, 9, D, 6, B, 18),
171 PINGROUP(SPIA, SPI1, SPI2, SPI3, GMI, B, 10, D, 30, C, 4),
172 PINGROUP(SPIB, SPI1, SPI2, SPI3, GMI, B, 11, D, 28, C, 6),
173 PINGROUP(SPIC, SPI1, SPI2, SPI3, GMI, B, 12, D, 26, C, 8),
174 PINGROUP(SPID, SPI2, SPI1, SPI2_ALT, GMI, B, 13, D, 24, C, 10),
175 PINGROUP(SPIE, SPI2, SPI1, SPI2_ALT, GMI, B, 14, D, 22, C, 12),
176 PINGROUP(SPIF, SPI3, SPI1, SPI2, RSVD, B, 15, D, 20, C, 14),
177 PINGROUP(SPIG, SPI3, SPI2, SPI2_ALT, I2C, B, 16, D, 18, C, 16),
178 PINGROUP(SPIH, SPI3, SPI2, SPI2_ALT, I2C, B, 17, D, 16, C, 18),
179 PINGROUP(UAA, SPI3, MIPI_HS, UARTA, ULPI, B, 18, A, 0, D, 0),
180 PINGROUP(UAB, SPI2, MIPI_HS, UARTA, ULPI, B, 19, A, 2, D, 2),
181 PINGROUP(UAC, OWR, RSVD, RSVD, RSVD, B, 20, A, 4, D, 4),
182 PINGROUP(UAD, IRDA, SPDIF, UARTA, SPI4, B, 21, A, 6, D, 6),
183 PINGROUP(UCA, UARTC, RSVD, GMI, RSVD, B, 22, B, 16, D, 8),
184 PINGROUP(UCB, UARTC, PWM, GMI, RSVD, B, 23, B, 18, D, 10),
185 PINGROUP(UDA, SPI1, RSVD, UARTD, ULPI, D, 13, A, 8, E, 16),
186 /* these pin groups only have pullup and pull down control */
187 PINGROUP(CK32, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 14),
188 PINGROUP(DDRC, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, D, 26),
189 PINGROUP(PMCA, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 4),
190 PINGROUP(PMCB, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 6),
191 PINGROUP(PMCC, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 8),
192 PINGROUP(PMCD, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 10),
193 PINGROUP(PMCE, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 12),
194 PINGROUP(XM2C, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, C, 30),
195 PINGROUP(XM2D, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, C, 28),
196};
197
198static char *tegra_mux_names[TEGRA_MAX_MUX] = {
199 [TEGRA_MUX_AHB_CLK] = "AHB_CLK",
200 [TEGRA_MUX_APB_CLK] = "APB_CLK",
201 [TEGRA_MUX_AUDIO_SYNC] = "AUDIO_SYNC",
202 [TEGRA_MUX_CRT] = "CRT",
203 [TEGRA_MUX_DAP1] = "DAP1",
204 [TEGRA_MUX_DAP2] = "DAP2",
205 [TEGRA_MUX_DAP3] = "DAP3",
206 [TEGRA_MUX_DAP4] = "DAP4",
207 [TEGRA_MUX_DAP5] = "DAP5",
208 [TEGRA_MUX_DISPLAYA] = "DISPLAYA",
209 [TEGRA_MUX_DISPLAYB] = "DISPLAYB",
210 [TEGRA_MUX_EMC_TEST0_DLL] = "EMC_TEST0_DLL",
211 [TEGRA_MUX_EMC_TEST1_DLL] = "EMC_TEST1_DLL",
212 [TEGRA_MUX_GMI] = "GMI",
213 [TEGRA_MUX_GMI_INT] = "GMI_INT",
214 [TEGRA_MUX_HDMI] = "HDMI",
215 [TEGRA_MUX_I2C] = "I2C",
216 [TEGRA_MUX_I2C2] = "I2C2",
217 [TEGRA_MUX_I2C3] = "I2C3",
218 [TEGRA_MUX_IDE] = "IDE",
219 [TEGRA_MUX_IRDA] = "IRDA",
220 [TEGRA_MUX_KBC] = "KBC",
221 [TEGRA_MUX_MIO] = "MIO",
222 [TEGRA_MUX_MIPI_HS] = "MIPI_HS",
223 [TEGRA_MUX_NAND] = "NAND",
224 [TEGRA_MUX_OSC] = "OSC",
225 [TEGRA_MUX_OWR] = "OWR",
226 [TEGRA_MUX_PCIE] = "PCIE",
227 [TEGRA_MUX_PLLA_OUT] = "PLLA_OUT",
228 [TEGRA_MUX_PLLC_OUT1] = "PLLC_OUT1",
229 [TEGRA_MUX_PLLM_OUT1] = "PLLM_OUT1",
230 [TEGRA_MUX_PLLP_OUT2] = "PLLP_OUT2",
231 [TEGRA_MUX_PLLP_OUT3] = "PLLP_OUT3",
232 [TEGRA_MUX_PLLP_OUT4] = "PLLP_OUT4",
233 [TEGRA_MUX_PWM] = "PWM",
234 [TEGRA_MUX_PWR_INTR] = "PWR_INTR",
235 [TEGRA_MUX_PWR_ON] = "PWR_ON",
236 [TEGRA_MUX_RTCK] = "RTCK",
237 [TEGRA_MUX_SDIO1] = "SDIO1",
238 [TEGRA_MUX_SDIO2] = "SDIO2",
239 [TEGRA_MUX_SDIO3] = "SDIO3",
240 [TEGRA_MUX_SDIO4] = "SDIO4",
241 [TEGRA_MUX_SFLASH] = "SFLASH",
242 [TEGRA_MUX_SPDIF] = "SPDIF",
243 [TEGRA_MUX_SPI1] = "SPI1",
244 [TEGRA_MUX_SPI2] = "SPI2",
245 [TEGRA_MUX_SPI2_ALT] = "SPI2_ALT",
246 [TEGRA_MUX_SPI3] = "SPI3",
247 [TEGRA_MUX_SPI4] = "SPI4",
248 [TEGRA_MUX_TRACE] = "TRACE",
249 [TEGRA_MUX_TWC] = "TWC",
250 [TEGRA_MUX_UARTA] = "UARTA",
251 [TEGRA_MUX_UARTB] = "UARTB",
252 [TEGRA_MUX_UARTC] = "UARTC",
253 [TEGRA_MUX_UARTD] = "UARTD",
254 [TEGRA_MUX_UARTE] = "UARTE",
255 [TEGRA_MUX_ULPI] = "ULPI",
256 [TEGRA_MUX_VI] = "VI",
257 [TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK",
258 [TEGRA_MUX_XIO] = "XIO",
259};
260
261struct tegra_drive_pingroup_desc {
262 const char *name;
263 s16 reg;
264};
265
266#define DRIVE_PINGROUP(pg_name, r) \
267 [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \
268 .name = #pg_name, \
269 .reg = r \
270 }
271
272static const struct tegra_drive_pingroup_desc drive_pingroups[TEGRA_MAX_PINGROUP] = {
273 DRIVE_PINGROUP(AO1, 0x868),
274 DRIVE_PINGROUP(AO2, 0x86c),
275 DRIVE_PINGROUP(AT1, 0x870),
276 DRIVE_PINGROUP(AT2, 0x874),
277 DRIVE_PINGROUP(CDEV1, 0x878),
278 DRIVE_PINGROUP(CDEV2, 0x87c),
279 DRIVE_PINGROUP(CSUS, 0x880),
280 DRIVE_PINGROUP(DAP1, 0x884),
281 DRIVE_PINGROUP(DAP2, 0x888),
282 DRIVE_PINGROUP(DAP3, 0x88c),
283 DRIVE_PINGROUP(DAP4, 0x890),
284 DRIVE_PINGROUP(DBG, 0x894),
285 DRIVE_PINGROUP(LCD1, 0x898),
286 DRIVE_PINGROUP(LCD2, 0x89c),
287 DRIVE_PINGROUP(SDMMC2, 0x8a0),
288 DRIVE_PINGROUP(SDMMC3, 0x8a4),
289 DRIVE_PINGROUP(SPI, 0x8a8),
290 DRIVE_PINGROUP(UAA, 0x8ac),
291 DRIVE_PINGROUP(UAB, 0x8b0),
292 DRIVE_PINGROUP(UART2, 0x8b4),
293 DRIVE_PINGROUP(UART3, 0x8b8),
294 DRIVE_PINGROUP(VI1, 0x8bc),
295 DRIVE_PINGROUP(VI2, 0x8c0),
296 DRIVE_PINGROUP(XM2A, 0x8c4),
297 DRIVE_PINGROUP(XM2C, 0x8c8),
298 DRIVE_PINGROUP(XM2D, 0x8cc),
299 DRIVE_PINGROUP(XM2CLK, 0x8d0),
300 DRIVE_PINGROUP(MEMCOMP, 0x8d4),
301};
302
303static const char *tegra_drive_names[TEGRA_MAX_DRIVE] = {
304 [TEGRA_DRIVE_DIV_8] = "DIV_8",
305 [TEGRA_DRIVE_DIV_4] = "DIV_4",
306 [TEGRA_DRIVE_DIV_2] = "DIV_2",
307 [TEGRA_DRIVE_DIV_1] = "DIV_1",
308};
309
310static const char *tegra_slew_names[TEGRA_MAX_SLEW] = {
311 [TEGRA_SLEW_FASTEST] = "FASTEST",
312 [TEGRA_SLEW_FAST] = "FAST",
313 [TEGRA_SLEW_SLOW] = "SLOW",
314 [TEGRA_SLEW_SLOWEST] = "SLOWEST",
315};
316
317static DEFINE_SPINLOCK(mux_lock);
318
319static const char *pingroup_name(enum tegra_pingroup pg)
320{
321 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
322 return "<UNKNOWN>";
323
324 return pingroups[pg].name;
325}
326
327static const char *func_name(enum tegra_mux_func func)
328{
329 if (func == TEGRA_MUX_RSVD1)
330 return "RSVD1";
331
332 if (func == TEGRA_MUX_RSVD2)
333 return "RSVD2";
334
335 if (func == TEGRA_MUX_RSVD3)
336 return "RSVD3";
337
338 if (func == TEGRA_MUX_RSVD4)
339 return "RSVD4";
340
341 if (func == TEGRA_MUX_NONE)
342 return "NONE";
343
344 if (func < 0 || func >= TEGRA_MAX_MUX)
345 return "<UNKNOWN>";
346
347 return tegra_mux_names[func];
348}
349
350
351static const char *tri_name(unsigned long val)
352{
353 return val ? "TRISTATE" : "NORMAL";
354}
355
356static const char *pupd_name(unsigned long val)
357{
358 switch (val) {
359 case 0:
360 return "NORMAL";
361
362 case 1:
363 return "PULL_DOWN";
364
365 case 2:
366 return "PULL_UP";
367
368 default:
369 return "RSVD";
370 }
371}
372
373
374static inline unsigned long pg_readl(unsigned long offset)
375{
376 return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
377}
378
379static inline void pg_writel(unsigned long value, unsigned long offset)
380{
381 writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
382}
383
384int tegra_pinmux_set_func(enum tegra_pingroup pg, enum tegra_mux_func func)
385{
386 int mux = -1;
387 int i;
388 unsigned long reg;
389 unsigned long flags;
390
391 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
392 return -ERANGE;
393
394 if (pingroups[pg].mux_reg == REG_N)
395 return -EINVAL;
396
397 if (func < 0)
398 return -ERANGE;
399
400 if (func & TEGRA_MUX_RSVD) {
401 mux = func & 0x3;
402 } else {
403 for (i = 0; i < 4; i++) {
404 if (pingroups[pg].funcs[i] == func) {
405 mux = i;
406 break;
407 }
408 }
409 }
410
411 if (mux < 0)
412 return -EINVAL;
413
414 spin_lock_irqsave(&mux_lock, flags);
415
416 reg = pg_readl(TEGRA_PP_MUX_CTL(pingroups[pg].mux_reg));
417 reg &= ~(0x3 << pingroups[pg].mux_bit);
418 reg |= mux << pingroups[pg].mux_bit;
419 pg_writel(reg, TEGRA_PP_MUX_CTL(pingroups[pg].mux_reg));
420
421 spin_unlock_irqrestore(&mux_lock, flags);
422
423 return 0;
424}
425
426int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
427 enum tegra_tristate tristate)
428{
429 unsigned long reg;
430 unsigned long flags;
431
432 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
433 return -ERANGE;
434
435 if (pingroups[pg].tri_reg == REG_N)
436 return -EINVAL;
437
438 spin_lock_irqsave(&mux_lock, flags);
439
440 reg = pg_readl(TEGRA_TRI_STATE(pingroups[pg].tri_reg));
441 reg &= ~(0x1 << pingroups[pg].tri_bit);
442 if (tristate)
443 reg |= 1 << pingroups[pg].tri_bit;
444 pg_writel(reg, TEGRA_TRI_STATE(pingroups[pg].tri_reg));
445
446 spin_unlock_irqrestore(&mux_lock, flags);
447
448 return 0;
449}
450
451int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
452 enum tegra_pullupdown pupd)
453{
454 unsigned long reg;
455 unsigned long flags;
456
457 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
458 return -ERANGE;
459
460 if (pingroups[pg].pupd_reg == REG_N)
461 return -EINVAL;
462
463 if (pupd != TEGRA_PUPD_NORMAL &&
464 pupd != TEGRA_PUPD_PULL_DOWN &&
465 pupd != TEGRA_PUPD_PULL_UP)
466 return -EINVAL;
467
468
469 spin_lock_irqsave(&mux_lock, flags);
470
471 reg = pg_readl(TEGRA_PP_PU_PD(pingroups[pg].pupd_reg));
472 reg &= ~(0x3 << pingroups[pg].pupd_bit);
473 reg |= pupd << pingroups[pg].pupd_bit;
474 pg_writel(reg, TEGRA_PP_PU_PD(pingroups[pg].pupd_reg));
475
476 spin_unlock_irqrestore(&mux_lock, flags);
477
478 return 0;
479}
480
481void tegra_pinmux_config_pingroup(enum tegra_pingroup pingroup,
482 enum tegra_mux_func func,
483 enum tegra_pullupdown pupd,
484 enum tegra_tristate tristate)
485{
486 int err;
487
488 if (pingroups[pingroup].mux_reg != REG_N) {
489 err = tegra_pinmux_set_func(pingroup, func);
490 if (err < 0)
491 pr_err("pinmux: can't set pingroup %s func to %s: %d\n",
492 pingroup_name(pingroup), func_name(func), err);
493 }
494
495 if (pingroups[pingroup].pupd_reg != REG_N) {
496 err = tegra_pinmux_set_pullupdown(pingroup, pupd);
497 if (err < 0)
498 pr_err("pinmux: can't set pingroup %s pullupdown to %s: %d\n",
499 pingroup_name(pingroup), pupd_name(pupd), err);
500 }
501
502 if (pingroups[pingroup].tri_reg != REG_N) {
503 err = tegra_pinmux_set_tristate(pingroup, tristate);
504 if (err < 0)
505 pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n",
506 pingroup_name(pingroup), tri_name(func), err);
507 }
508}
509
510
511
512void tegra_pinmux_config_table(struct tegra_pingroup_config *config, int len)
513{
514 int i;
515
516 for (i = 0; i < len; i++)
517 tegra_pinmux_config_pingroup(config[i].pingroup,
518 config[i].func,
519 config[i].pupd,
520 config[i].tristate);
521}
522
523static const char *drive_pinmux_name(enum tegra_drive_pingroup pg)
524{
525 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
526 return "<UNKNOWN>";
527
528 return drive_pingroups[pg].name;
529}
530
531static const char *enable_name(unsigned long val)
532{
533 return val ? "ENABLE" : "DISABLE";
534}
535
536static const char *drive_name(unsigned long val)
537{
538 if (val >= TEGRA_MAX_DRIVE)
539 return "<UNKNOWN>";
540
541 return tegra_drive_names[val];
542}
543
544static const char *slew_name(unsigned long val)
545{
546 if (val >= TEGRA_MAX_SLEW)
547 return "<UNKNOWN>";
548
549 return tegra_slew_names[val];
550}
551
552static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg,
553 enum tegra_hsm hsm)
554{
555 unsigned long flags;
556 u32 reg;
557 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
558 return -ERANGE;
559
560 if (hsm != TEGRA_HSM_ENABLE && hsm != TEGRA_HSM_DISABLE)
561 return -EINVAL;
562
563 spin_lock_irqsave(&mux_lock, flags);
564
565 reg = pg_readl(drive_pingroups[pg].reg);
566 if (hsm == TEGRA_HSM_ENABLE)
567 reg |= (1 << 2);
568 else
569 reg &= ~(1 << 2);
570 pg_writel(reg, drive_pingroups[pg].reg);
571
572 spin_unlock_irqrestore(&mux_lock, flags);
573
574 return 0;
575}
576
577static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg,
578 enum tegra_schmitt schmitt)
579{
580 unsigned long flags;
581 u32 reg;
582 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
583 return -ERANGE;
584
585 if (schmitt != TEGRA_SCHMITT_ENABLE && schmitt != TEGRA_SCHMITT_DISABLE)
586 return -EINVAL;
587
588 spin_lock_irqsave(&mux_lock, flags);
589
590 reg = pg_readl(drive_pingroups[pg].reg);
591 if (schmitt == TEGRA_SCHMITT_ENABLE)
592 reg |= (1 << 3);
593 else
594 reg &= ~(1 << 3);
595 pg_writel(reg, drive_pingroups[pg].reg);
596
597 spin_unlock_irqrestore(&mux_lock, flags);
598
599 return 0;
600}
601
602static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg,
603 enum tegra_drive drive)
604{
605 unsigned long flags;
606 u32 reg;
607 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
608 return -ERANGE;
609
610 if (drive < 0 || drive >= TEGRA_MAX_DRIVE)
611 return -EINVAL;
612
613 spin_lock_irqsave(&mux_lock, flags);
614
615 reg = pg_readl(drive_pingroups[pg].reg);
616 reg &= ~(0x3 << 4);
617 reg |= drive << 4;
618 pg_writel(reg, drive_pingroups[pg].reg);
619
620 spin_unlock_irqrestore(&mux_lock, flags);
621
622 return 0;
623}
624
625static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
626 enum tegra_pull_strength pull_down)
627{
628 unsigned long flags;
629 u32 reg;
630 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
631 return -ERANGE;
632
633 if (pull_down < 0 || pull_down >= TEGRA_MAX_PULL)
634 return -EINVAL;
635
636 spin_lock_irqsave(&mux_lock, flags);
637
638 reg = pg_readl(drive_pingroups[pg].reg);
639 reg &= ~(0x1f << 12);
640 reg |= pull_down << 12;
641 pg_writel(reg, drive_pingroups[pg].reg);
642
643 spin_unlock_irqrestore(&mux_lock, flags);
644
645 return 0;
646}
647
648static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
649 enum tegra_pull_strength pull_up)
650{
651 unsigned long flags;
652 u32 reg;
653 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
654 return -ERANGE;
655
656 if (pull_up < 0 || pull_up >= TEGRA_MAX_PULL)
657 return -EINVAL;
658
659 spin_lock_irqsave(&mux_lock, flags);
660
661 reg = pg_readl(drive_pingroups[pg].reg);
662 reg &= ~(0x1f << 12);
663 reg |= pull_up << 12;
664 pg_writel(reg, drive_pingroups[pg].reg);
665
666 spin_unlock_irqrestore(&mux_lock, flags);
667
668 return 0;
669}
670
671static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg,
672 enum tegra_slew slew_rising)
673{
674 unsigned long flags;
675 u32 reg;
676 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
677 return -ERANGE;
678
679 if (slew_rising < 0 || slew_rising >= TEGRA_MAX_SLEW)
680 return -EINVAL;
681
682 spin_lock_irqsave(&mux_lock, flags);
683
684 reg = pg_readl(drive_pingroups[pg].reg);
685 reg &= ~(0x3 << 28);
686 reg |= slew_rising << 28;
687 pg_writel(reg, drive_pingroups[pg].reg);
688
689 spin_unlock_irqrestore(&mux_lock, flags);
690
691 return 0;
692}
693
694static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg,
695 enum tegra_slew slew_falling)
696{
697 unsigned long flags;
698 u32 reg;
699 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
700 return -ERANGE;
701
702 if (slew_falling < 0 || slew_falling >= TEGRA_MAX_SLEW)
703 return -EINVAL;
704
705 spin_lock_irqsave(&mux_lock, flags);
706
707 reg = pg_readl(drive_pingroups[pg].reg);
708 reg &= ~(0x3 << 30);
709 reg |= slew_falling << 30;
710 pg_writel(reg, drive_pingroups[pg].reg);
711
712 spin_unlock_irqrestore(&mux_lock, flags);
713
714 return 0;
715}
716
717static void tegra_drive_pinmux_config_pingroup(enum tegra_drive_pingroup pingroup,
718 enum tegra_hsm hsm,
719 enum tegra_schmitt schmitt,
720 enum tegra_drive drive,
721 enum tegra_pull_strength pull_down,
722 enum tegra_pull_strength pull_up,
723 enum tegra_slew slew_rising,
724 enum tegra_slew slew_falling)
725{
726 int err;
727
728 err = tegra_drive_pinmux_set_hsm(pingroup, hsm);
729 if (err < 0)
730 pr_err("pinmux: can't set pingroup %s hsm to %s: %d\n",
731 drive_pinmux_name(pingroup),
732 enable_name(hsm), err);
733
734 err = tegra_drive_pinmux_set_schmitt(pingroup, schmitt);
735 if (err < 0)
736 pr_err("pinmux: can't set pingroup %s schmitt to %s: %d\n",
737 drive_pinmux_name(pingroup),
738 enable_name(schmitt), err);
739
740 err = tegra_drive_pinmux_set_drive(pingroup, drive);
741 if (err < 0)
742 pr_err("pinmux: can't set pingroup %s drive to %s: %d\n",
743 drive_pinmux_name(pingroup),
744 drive_name(drive), err);
745
746 err = tegra_drive_pinmux_set_pull_down(pingroup, pull_down);
747 if (err < 0)
748 pr_err("pinmux: can't set pingroup %s pull down to %d: %d\n",
749 drive_pinmux_name(pingroup),
750 pull_down, err);
751
752 err = tegra_drive_pinmux_set_pull_up(pingroup, pull_up);
753 if (err < 0)
754 pr_err("pinmux: can't set pingroup %s pull up to %d: %d\n",
755 drive_pinmux_name(pingroup),
756 pull_up, err);
757
758 err = tegra_drive_pinmux_set_slew_rising(pingroup, slew_rising);
759 if (err < 0)
760 pr_err("pinmux: can't set pingroup %s rising slew to %s: %d\n",
761 drive_pinmux_name(pingroup),
762 slew_name(slew_rising), err);
763
764 err = tegra_drive_pinmux_set_slew_falling(pingroup, slew_falling);
765 if (err < 0)
766 pr_err("pinmux: can't set pingroup %s falling slew to %s: %d\n",
767 drive_pinmux_name(pingroup),
768 slew_name(slew_falling), err);
769}
770
771void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
772 int len)
773{
774 int i;
775
776 for (i = 0; i < len; i++)
777 tegra_drive_pinmux_config_pingroup(config[i].pingroup,
778 config[i].hsm,
779 config[i].schmitt,
780 config[i].drive,
781 config[i].pull_down,
782 config[i].pull_up,
783 config[i].slew_rising,
784 config[i].slew_falling);
785}
786
787
788#ifdef CONFIG_DEBUG_FS
789
790#include <linux/debugfs.h>
791#include <linux/seq_file.h>
792
793static void dbg_pad_field(struct seq_file *s, int len)
794{
795 seq_putc(s, ',');
796
797 while (len-- > -1)
798 seq_putc(s, ' ');
799}
800
801static int dbg_pinmux_show(struct seq_file *s, void *unused)
802{
803 int i;
804 int len;
805
806 for (i = 0; i < TEGRA_MAX_PINGROUP; i++) {
807 unsigned long tri;
808 unsigned long mux;
809 unsigned long pupd;
810
811 seq_printf(s, "\t{TEGRA_PINGROUP_%s", pingroups[i].name);
812 len = strlen(pingroups[i].name);
813 dbg_pad_field(s, 5 - len);
814
815 if (pingroups[i].mux_reg == REG_N) {
816 seq_printf(s, "TEGRA_MUX_NONE");
817 len = strlen("NONE");
818 } else {
819 mux = (pg_readl(TEGRA_PP_MUX_CTL(pingroups[i].mux_reg)) >>
820 pingroups[i].mux_bit) & 0x3;
821 if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) {
822 seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1);
823 len = 5;
824 } else {
825 seq_printf(s, "TEGRA_MUX_%s",
826 tegra_mux_names[pingroups[i].funcs[mux]]);
827 len = strlen(tegra_mux_names[pingroups[i].funcs[mux]]);
828 }
829 }
830 dbg_pad_field(s, 13-len);
831
832 if (pingroups[i].mux_reg == REG_N) {
833 seq_printf(s, "TEGRA_PUPD_NORMAL");
834 len = strlen("NORMAL");
835 } else {
836 pupd = (pg_readl(TEGRA_PP_PU_PD(pingroups[i].pupd_reg)) >>
837 pingroups[i].pupd_bit) & 0x3;
838 seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd));
839 len = strlen(pupd_name(pupd));
840 }
841 dbg_pad_field(s, 9 - len);
842
843 if (pingroups[i].tri_reg == REG_N) {
844 seq_printf(s, "TEGRA_TRI_NORMAL");
845 } else {
846 tri = (pg_readl(TEGRA_TRI_STATE(pingroups[i].tri_reg)) >>
847 pingroups[i].tri_bit) & 0x1;
848
849 seq_printf(s, "TEGRA_TRI_%s", tri_name(tri));
850 }
851 seq_printf(s, "},\n");
852 }
853 return 0;
854}
855
856static int dbg_pinmux_open(struct inode *inode, struct file *file)
857{
858 return single_open(file, dbg_pinmux_show, &inode->i_private);
859}
860
861static const struct file_operations debug_fops = {
862 .open = dbg_pinmux_open,
863 .read = seq_read,
864 .llseek = seq_lseek,
865 .release = single_release,
866};
867
868static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
869{
870 int i;
871 int len;
872
873 for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) {
874 u32 reg;
875
876 seq_printf(s, "\t{TEGRA_DRIVE_PINGROUP_%s",
877 drive_pingroups[i].name);
878 len = strlen(drive_pingroups[i].name);
879 dbg_pad_field(s, 7 - len);
880
881
882 reg = pg_readl(drive_pingroups[i].reg);
883 if (HSM_EN(reg)) {
884 seq_printf(s, "TEGRA_HSM_ENABLE");
885 len = 16;
886 } else {
887 seq_printf(s, "TEGRA_HSM_DISABLE");
888 len = 17;
889 }
890 dbg_pad_field(s, 17 - len);
891
892 if (SCHMT_EN(reg)) {
893 seq_printf(s, "TEGRA_SCHMITT_ENABLE");
894 len = 21;
895 } else {
896 seq_printf(s, "TEGRA_SCHMITT_DISABLE");
897 len = 22;
898 }
899 dbg_pad_field(s, 22 - len);
900
901 seq_printf(s, "TEGRA_DRIVE_%s", drive_name(LPMD(reg)));
902 len = strlen(drive_name(LPMD(reg)));
903 dbg_pad_field(s, 5 - len);
904
905 seq_printf(s, "TEGRA_PULL_%d", DRVDN(reg));
906 len = DRVDN(reg) < 10 ? 1 : 2;
907 dbg_pad_field(s, 2 - len);
908
909 seq_printf(s, "TEGRA_PULL_%d", DRVUP(reg));
910 len = DRVUP(reg) < 10 ? 1 : 2;
911 dbg_pad_field(s, 2 - len);
912
913 seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWR(reg)));
914 len = strlen(slew_name(SLWR(reg)));
915 dbg_pad_field(s, 7 - len);
916
917 seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWF(reg)));
918
919 seq_printf(s, "},\n");
920 }
921 return 0;
922}
923
924static int dbg_drive_pinmux_open(struct inode *inode, struct file *file)
925{
926 return single_open(file, dbg_drive_pinmux_show, &inode->i_private);
927}
928
929static const struct file_operations debug_drive_fops = {
930 .open = dbg_drive_pinmux_open,
931 .read = seq_read,
932 .llseek = seq_lseek,
933 .release = single_release,
934};
935
936static int __init tegra_pinmux_debuginit(void)
937{
938 (void) debugfs_create_file("tegra_pinmux", S_IRUGO,
939 NULL, NULL, &debug_fops);
940 (void) debugfs_create_file("tegra_pinmux_drive", S_IRUGO,
941 NULL, NULL, &debug_drive_fops);
942 return 0;
943}
944late_initcall(tegra_pinmux_debuginit);
945#endif
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
new file mode 100644
index 000000000000..1c0fd92cab39
--- /dev/null
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -0,0 +1,156 @@
1/*
2 * linux/arch/arm/mach-tegra/platsmp.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * Copyright (C) 2009 Palm
8 * All Rights Reserved
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14#include <linux/init.h>
15#include <linux/errno.h>
16#include <linux/delay.h>
17#include <linux/device.h>
18#include <linux/jiffies.h>
19#include <linux/smp.h>
20#include <linux/io.h>
21
22#include <asm/cacheflush.h>
23#include <mach/hardware.h>
24#include <asm/mach-types.h>
25#include <asm/localtimer.h>
26#include <asm/smp_scu.h>
27
28#include <mach/iomap.h>
29
30extern void tegra_secondary_startup(void);
31
32static DEFINE_SPINLOCK(boot_lock);
33static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
34
35#define EVP_CPU_RESET_VECTOR \
36 (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
37#define CLK_RST_CONTROLLER_CLK_CPU_CMPLX \
38 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x4c)
39#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \
40 (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344)
41
42void __cpuinit platform_secondary_init(unsigned int cpu)
43{
44 trace_hardirqs_off();
45
46 /*
47 * if any interrupts are already enabled for the primary
48 * core (e.g. timer irq), then they will not have been enabled
49 * for us: do so
50 */
51 gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x100);
52
53 /*
54 * Synchronise with the boot thread.
55 */
56 spin_lock(&boot_lock);
57 spin_unlock(&boot_lock);
58}
59
60int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
61{
62 unsigned long old_boot_vector;
63 unsigned long boot_vector;
64 unsigned long timeout;
65 u32 reg;
66
67 /*
68 * set synchronisation state between this boot processor
69 * and the secondary one
70 */
71 spin_lock(&boot_lock);
72
73
74 /* set the reset vector to point to the secondary_startup routine */
75
76 boot_vector = virt_to_phys(tegra_secondary_startup);
77 old_boot_vector = readl(EVP_CPU_RESET_VECTOR);
78 writel(boot_vector, EVP_CPU_RESET_VECTOR);
79
80 /* enable cpu clock on cpu1 */
81 reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
82 writel(reg & ~(1<<9), CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
83
84 reg = (1<<13) | (1<<9) | (1<<5) | (1<<1);
85 writel(reg, CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
86
87 smp_wmb();
88 flush_cache_all();
89
90 /* unhalt the cpu */
91 writel(0, IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + 0x14);
92
93 timeout = jiffies + (1 * HZ);
94 while (time_before(jiffies, timeout)) {
95 if (readl(EVP_CPU_RESET_VECTOR) != boot_vector)
96 break;
97 udelay(10);
98 }
99
100 /* put the old boot vector back */
101 writel(old_boot_vector, EVP_CPU_RESET_VECTOR);
102
103 /*
104 * now the secondary core is starting up let it run its
105 * calibrations, then wait for it to finish
106 */
107 spin_unlock(&boot_lock);
108
109 return 0;
110}
111
112/*
113 * Initialise the CPU possible map early - this describes the CPUs
114 * which may be present or become present in the system.
115 */
116void __init smp_init_cpus(void)
117{
118 unsigned int i, ncores = scu_get_core_count(scu_base);
119
120 for (i = 0; i < ncores; i++)
121 cpu_set(i, cpu_possible_map);
122}
123
124void __init smp_prepare_cpus(unsigned int max_cpus)
125{
126 unsigned int ncores = scu_get_core_count(scu_base);
127 unsigned int cpu = smp_processor_id();
128 int i;
129
130 smp_store_cpu_info(cpu);
131
132 /*
133 * are we trying to boot more cores than exist?
134 */
135 if (max_cpus > ncores)
136 max_cpus = ncores;
137
138 /*
139 * Initialise the present map, which describes the set of CPUs
140 * actually populated at the present time.
141 */
142 for (i = 0; i < max_cpus; i++)
143 set_cpu_present(i, true);
144
145 /*
146 * Initialise the SCU if there are more than one CPU and let
147 * them know where to start. Note that, on modern versions of
148 * MILO, the "poke" doesn't actually do anything until each
149 * individual core is sent a soft interrupt to get it out of
150 * WFI
151 */
152 if (max_cpus > 1) {
153 percpu_timer_setup();
154 scu_enable(scu_base);
155 }
156}
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
new file mode 100644
index 000000000000..426163231fff
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -0,0 +1,1359 @@
1/*
2 * arch/arm/mach-tegra/tegra2_clocks.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/list.h>
23#include <linux/spinlock.h>
24#include <linux/delay.h>
25#include <linux/io.h>
26#include <linux/hrtimer.h>
27
28#include <asm/clkdev.h>
29
30#include <mach/iomap.h>
31
32#include "clock.h"
33
34#define RST_DEVICES 0x004
35#define RST_DEVICES_SET 0x300
36#define RST_DEVICES_CLR 0x304
37
38#define CLK_OUT_ENB 0x010
39#define CLK_OUT_ENB_SET 0x320
40#define CLK_OUT_ENB_CLR 0x324
41
42#define OSC_CTRL 0x50
43#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
44#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
45#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30)
46#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30)
47#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
48
49#define OSC_FREQ_DET 0x58
50#define OSC_FREQ_DET_TRIG (1<<31)
51
52#define OSC_FREQ_DET_STATUS 0x5C
53#define OSC_FREQ_DET_BUSY (1<<31)
54#define OSC_FREQ_DET_CNT_MASK 0xFFFF
55
56#define PERIPH_CLK_SOURCE_MASK (3<<30)
57#define PERIPH_CLK_SOURCE_SHIFT 30
58#define PERIPH_CLK_SOURCE_ENABLE (1<<28)
59#define PERIPH_CLK_SOURCE_DIV_MASK 0xFF
60#define PERIPH_CLK_SOURCE_DIV_SHIFT 0
61
62#define PLL_BASE 0x0
63#define PLL_BASE_BYPASS (1<<31)
64#define PLL_BASE_ENABLE (1<<30)
65#define PLL_BASE_REF_ENABLE (1<<29)
66#define PLL_BASE_OVERRIDE (1<<28)
67#define PLL_BASE_LOCK (1<<27)
68#define PLL_BASE_DIVP_MASK (0x7<<20)
69#define PLL_BASE_DIVP_SHIFT 20
70#define PLL_BASE_DIVN_MASK (0x3FF<<8)
71#define PLL_BASE_DIVN_SHIFT 8
72#define PLL_BASE_DIVM_MASK (0x1F)
73#define PLL_BASE_DIVM_SHIFT 0
74
75#define PLL_OUT_RATIO_MASK (0xFF<<8)
76#define PLL_OUT_RATIO_SHIFT 8
77#define PLL_OUT_OVERRIDE (1<<2)
78#define PLL_OUT_CLKEN (1<<1)
79#define PLL_OUT_RESET_DISABLE (1<<0)
80
81#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
82#define PLL_MISC_DCCON_SHIFT 20
83#define PLL_MISC_LOCK_ENABLE (1<<18)
84#define PLL_MISC_CPCON_SHIFT 8
85#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT)
86#define PLL_MISC_LFCON_SHIFT 4
87#define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT)
88#define PLL_MISC_VCOCON_SHIFT 0
89#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT)
90
91#define PLLD_MISC_CLKENABLE (1<<30)
92#define PLLD_MISC_DIV_RST (1<<23)
93#define PLLD_MISC_DCCON_SHIFT 12
94
95#define PERIPH_CLK_TO_ENB_REG(c) ((c->clk_num / 32) * 4)
96#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->clk_num / 32) * 8)
97#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->clk_num % 32))
98
99#define SUPER_CLK_MUX 0x00
100#define SUPER_STATE_SHIFT 28
101#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT)
102#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT)
103#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT)
104#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT)
105#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT)
106#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT)
107#define SUPER_SOURCE_MASK 0xF
108#define SUPER_FIQ_SOURCE_SHIFT 12
109#define SUPER_IRQ_SOURCE_SHIFT 8
110#define SUPER_RUN_SOURCE_SHIFT 4
111#define SUPER_IDLE_SOURCE_SHIFT 0
112
113#define SUPER_CLK_DIVIDER 0x04
114
115#define BUS_CLK_DISABLE (1<<3)
116#define BUS_CLK_DIV_MASK 0x3
117
118static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
119
120#define clk_writel(value, reg) \
121 __raw_writel(value, (u32)reg_clk_base + (reg))
122#define clk_readl(reg) \
123 __raw_readl((u32)reg_clk_base + (reg))
124
125unsigned long clk_measure_input_freq(void)
126{
127 u32 clock_autodetect;
128 clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
129 do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
130 clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
131 if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
132 return 12000000;
133 } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
134 return 13000000;
135 } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
136 return 19200000;
137 } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
138 return 26000000;
139 } else {
140 pr_err("%s: Unexpected clock autodetect value %d", __func__, clock_autodetect);
141 BUG();
142 return 0;
143 }
144}
145
146static int clk_div71_get_divider(struct clk *c, unsigned long rate)
147{
148 unsigned long divider_u71;
149
150 divider_u71 = DIV_ROUND_UP(c->rate * 2, rate);
151
152 if (divider_u71 - 2 > 255 || divider_u71 - 2 < 0)
153 return -EINVAL;
154
155 return divider_u71 - 2;
156}
157
158static unsigned long tegra2_clk_recalculate_rate(struct clk *c)
159{
160 unsigned long rate;
161 rate = c->parent->rate;
162
163 if (c->mul != 0 && c->div != 0)
164 c->rate = rate * c->mul / c->div;
165 else
166 c->rate = rate;
167 return c->rate;
168}
169
170
171/* clk_m functions */
172static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c)
173{
174 u32 auto_clock_control = clk_readl(OSC_CTRL) & ~OSC_CTRL_OSC_FREQ_MASK;
175
176 c->rate = clk_measure_input_freq();
177 switch (c->rate) {
178 case 12000000:
179 auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
180 break;
181 case 13000000:
182 auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
183 break;
184 case 19200000:
185 auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
186 break;
187 case 26000000:
188 auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
189 break;
190 default:
191 pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
192 BUG();
193 }
194 clk_writel(auto_clock_control, OSC_CTRL);
195 return c->rate;
196}
197
198static void tegra2_clk_m_init(struct clk *c)
199{
200 pr_debug("%s on clock %s\n", __func__, c->name);
201 tegra2_clk_m_autodetect_rate(c);
202}
203
204static int tegra2_clk_m_enable(struct clk *c)
205{
206 pr_debug("%s on clock %s\n", __func__, c->name);
207 return 0;
208}
209
210static void tegra2_clk_m_disable(struct clk *c)
211{
212 pr_debug("%s on clock %s\n", __func__, c->name);
213 BUG();
214}
215
216static struct clk_ops tegra_clk_m_ops = {
217 .init = tegra2_clk_m_init,
218 .enable = tegra2_clk_m_enable,
219 .disable = tegra2_clk_m_disable,
220};
221
222/* super clock functions */
223/* "super clocks" on tegra have two-stage muxes and a clock skipping
224 * super divider. We will ignore the clock skipping divider, since we
225 * can't lower the voltage when using the clock skip, but we can if we
226 * lower the PLL frequency.
227 */
228static void tegra2_super_clk_init(struct clk *c)
229{
230 u32 val;
231 int source;
232 int shift;
233 const struct clk_mux_sel *sel;
234 val = clk_readl(c->reg + SUPER_CLK_MUX);
235 c->state = ON;
236 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
237 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
238 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
239 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
240 source = (val >> shift) & SUPER_SOURCE_MASK;
241 for (sel = c->inputs; sel->input != NULL; sel++) {
242 if (sel->value == source)
243 break;
244 }
245 BUG_ON(sel->input == NULL);
246 c->parent = sel->input;
247 tegra2_clk_recalculate_rate(c);
248}
249
250static int tegra2_super_clk_enable(struct clk *c)
251{
252 clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
253 return 0;
254}
255
256static void tegra2_super_clk_disable(struct clk *c)
257{
258 pr_debug("%s on clock %s\n", __func__, c->name);
259
260 /* oops - don't disable the CPU clock! */
261 BUG();
262}
263
264static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p)
265{
266 u32 val;
267 const struct clk_mux_sel *sel;
268 int shift;
269 val = clk_readl(c->reg + SUPER_CLK_MUX);;
270 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
271 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
272 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
273 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
274 for (sel = c->inputs; sel->input != NULL; sel++) {
275 if (sel->input == p) {
276 clk_reparent(c, p);
277 val &= ~(SUPER_SOURCE_MASK << shift);
278 val |= sel->value << shift;
279 clk_writel(val, c->reg);
280 c->rate = c->parent->rate;
281 return 0;
282 }
283 }
284 return -EINVAL;
285}
286
287static struct clk_ops tegra_super_ops = {
288 .init = tegra2_super_clk_init,
289 .enable = tegra2_super_clk_enable,
290 .disable = tegra2_super_clk_disable,
291 .set_parent = tegra2_super_clk_set_parent,
292 .recalculate_rate = tegra2_clk_recalculate_rate,
293};
294
295/* bus clock functions */
296static void tegra2_bus_clk_init(struct clk *c)
297{
298 u32 val = clk_readl(c->reg);
299 c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
300 c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
301 c->mul = 1;
302 tegra2_clk_recalculate_rate(c);
303}
304
305static int tegra2_bus_clk_enable(struct clk *c)
306{
307 u32 val = clk_readl(c->reg);
308 val &= ~(BUS_CLK_DISABLE << c->reg_shift);
309 clk_writel(val, c->reg);
310 return 0;
311}
312
313static void tegra2_bus_clk_disable(struct clk *c)
314{
315 u32 val = clk_readl(c->reg);
316 val |= BUS_CLK_DISABLE << c->reg_shift;
317 clk_writel(val, c->reg);
318}
319
320static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate)
321{
322 u32 val = clk_readl(c->reg);
323 unsigned long parent_rate = c->parent->rate;
324 int i;
325 for (i = 1; i <= 4; i++) {
326 if (rate == parent_rate / i) {
327 val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
328 val |= (i - 1) << c->reg_shift;
329 clk_writel(val, c->reg);
330 c->div = i;
331 c->mul = 1;
332 return 0;
333 }
334 }
335 return -EINVAL;
336}
337
338static struct clk_ops tegra_bus_ops = {
339 .init = tegra2_bus_clk_init,
340 .enable = tegra2_bus_clk_enable,
341 .disable = tegra2_bus_clk_disable,
342 .set_rate = tegra2_bus_clk_set_rate,
343 .recalculate_rate = tegra2_clk_recalculate_rate,
344};
345
346/* PLL Functions */
347static unsigned long tegra2_pll_clk_recalculate_rate(struct clk *c)
348{
349 u64 rate;
350 rate = c->parent->rate;
351 rate *= c->n;
352 do_div(rate, c->m);
353 if (c->p == 2)
354 rate >>= 1;
355 c->rate = rate;
356 return c->rate;
357}
358
359static int tegra2_pll_clk_wait_for_lock(struct clk *c)
360{
361 ktime_t before;
362
363 before = ktime_get();
364 while (!(clk_readl(c->reg + PLL_BASE) & PLL_BASE_LOCK)) {
365 if (ktime_us_delta(ktime_get(), before) > 5000) {
366 pr_err("Timed out waiting for lock bit on pll %s",
367 c->name);
368 return -1;
369 }
370 }
371
372 return 0;
373}
374
375static void tegra2_pll_clk_init(struct clk *c)
376{
377 u32 val = clk_readl(c->reg + PLL_BASE);
378
379 c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
380
381 if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
382 pr_warning("Clock %s has unknown fixed frequency\n", c->name);
383 c->n = 1;
384 c->m = 0;
385 c->p = 1;
386 } else if (val & PLL_BASE_BYPASS) {
387 c->n = 1;
388 c->m = 1;
389 c->p = 1;
390 } else {
391 c->n = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
392 c->m = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
393 c->p = (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
394 }
395
396 val = clk_readl(c->reg + PLL_MISC(c));
397 if (c->flags & PLL_HAS_CPCON)
398 c->cpcon = (val & PLL_MISC_CPCON_MASK) >> PLL_MISC_CPCON_SHIFT;
399
400 tegra2_pll_clk_recalculate_rate(c);
401}
402
403static int tegra2_pll_clk_enable(struct clk *c)
404{
405 u32 val;
406 pr_debug("%s on clock %s\n", __func__, c->name);
407
408 val = clk_readl(c->reg + PLL_BASE);
409 val &= ~PLL_BASE_BYPASS;
410 val |= PLL_BASE_ENABLE;
411 clk_writel(val, c->reg + PLL_BASE);
412
413 val = clk_readl(c->reg + PLL_MISC(c));
414 val |= PLL_MISC_LOCK_ENABLE;
415 clk_writel(val, c->reg + PLL_MISC(c));
416
417 tegra2_pll_clk_wait_for_lock(c);
418
419 return 0;
420}
421
422static void tegra2_pll_clk_disable(struct clk *c)
423{
424 u32 val;
425 pr_debug("%s on clock %s\n", __func__, c->name);
426
427 val = clk_readl(c->reg);
428 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
429 clk_writel(val, c->reg);
430}
431
432static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate)
433{
434 u32 val;
435 unsigned long input_rate;
436 const struct clk_pll_table *sel;
437
438 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
439 BUG_ON(c->refcnt != 0);
440
441 input_rate = c->parent->rate;
442 for (sel = c->pll_table; sel->input_rate != 0; sel++) {
443 if (sel->input_rate == input_rate && sel->output_rate == rate) {
444 c->n = sel->n;
445 c->m = sel->m;
446 c->p = sel->p;
447 c->cpcon = sel->cpcon;
448
449 val = clk_readl(c->reg + PLL_BASE);
450 if (c->flags & PLL_FIXED)
451 val |= PLL_BASE_OVERRIDE;
452 val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK |
453 PLL_BASE_DIVM_MASK);
454 val |= (c->m << PLL_BASE_DIVM_SHIFT) |
455 (c->n << PLL_BASE_DIVN_SHIFT);
456 BUG_ON(c->p > 2);
457 if (c->p == 2)
458 val |= 1 << PLL_BASE_DIVP_SHIFT;
459 clk_writel(val, c->reg + PLL_BASE);
460
461 if (c->flags & PLL_HAS_CPCON) {
462 val = c->cpcon << PLL_MISC_CPCON_SHIFT;
463 val |= PLL_MISC_LOCK_ENABLE;
464 clk_writel(val, c->reg + PLL_MISC(c));
465 }
466
467 if (c->state == ON)
468 tegra2_pll_clk_enable(c);
469
470 c->rate = rate;
471 return 0;
472 }
473 }
474 return -EINVAL;
475}
476
477static struct clk_ops tegra_pll_ops = {
478 .init = tegra2_pll_clk_init,
479 .enable = tegra2_pll_clk_enable,
480 .disable = tegra2_pll_clk_disable,
481 .set_rate = tegra2_pll_clk_set_rate,
482 .recalculate_rate = tegra2_pll_clk_recalculate_rate,
483};
484
485/* Clock divider ops */
486static void tegra2_pll_div_clk_init(struct clk *c)
487{
488 u32 val = clk_readl(c->reg);
489 u32 divu71;
490 val >>= c->reg_shift;
491 c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
492 if (!(val & PLL_OUT_RESET_DISABLE))
493 c->state = OFF;
494
495 if (c->flags & DIV_U71) {
496 divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
497 c->div = (divu71 + 2);
498 c->mul = 2;
499 } else if (c->flags & DIV_2) {
500 c->div = 2;
501 c->mul = 1;
502 } else {
503 c->div = 1;
504 c->mul = 1;
505 }
506
507 tegra2_clk_recalculate_rate(c);
508}
509
510static int tegra2_pll_div_clk_enable(struct clk *c)
511{
512 u32 val;
513 u32 new_val;
514
515 pr_debug("%s: %s\n", __func__, c->name);
516 if (c->flags & DIV_U71) {
517 val = clk_readl(c->reg);
518 new_val = val >> c->reg_shift;
519 new_val &= 0xFFFF;
520
521 new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
522
523 val &= ~(0xFFFF << c->reg_shift);
524 val |= new_val << c->reg_shift;
525 clk_writel(val, c->reg);
526 return 0;
527 } else if (c->flags & DIV_2) {
528 BUG_ON(!(c->flags & PLLD));
529 val = clk_readl(c->reg);
530 val &= ~PLLD_MISC_DIV_RST;
531 clk_writel(val, c->reg);
532 return 0;
533 }
534 return -EINVAL;
535}
536
537static void tegra2_pll_div_clk_disable(struct clk *c)
538{
539 u32 val;
540 u32 new_val;
541
542 pr_debug("%s: %s\n", __func__, c->name);
543 if (c->flags & DIV_U71) {
544 val = clk_readl(c->reg);
545 new_val = val >> c->reg_shift;
546 new_val &= 0xFFFF;
547
548 new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
549
550 val &= ~(0xFFFF << c->reg_shift);
551 val |= new_val << c->reg_shift;
552 clk_writel(val, c->reg);
553 } else if (c->flags & DIV_2) {
554 BUG_ON(!(c->flags & PLLD));
555 val = clk_readl(c->reg);
556 val |= PLLD_MISC_DIV_RST;
557 clk_writel(val, c->reg);
558 }
559}
560
561static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
562{
563 u32 val;
564 u32 new_val;
565 int divider_u71;
566 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
567 if (c->flags & DIV_U71) {
568 divider_u71 = clk_div71_get_divider(c->parent, rate);
569 if (divider_u71 >= 0) {
570 val = clk_readl(c->reg);
571 new_val = val >> c->reg_shift;
572 new_val &= 0xFFFF;
573 if (c->flags & DIV_U71_FIXED)
574 new_val |= PLL_OUT_OVERRIDE;
575 new_val &= ~PLL_OUT_RATIO_MASK;
576 new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
577
578 val &= ~(0xFFFF << c->reg_shift);
579 val |= new_val << c->reg_shift;
580 clk_writel(val, c->reg);
581 c->div = divider_u71 + 2;
582 c->mul = 2;
583 tegra2_clk_recalculate_rate(c);
584 return 0;
585 }
586 } else if (c->flags & DIV_2) {
587 if (c->parent->rate == rate * 2) {
588 c->rate = rate;
589 return 0;
590 }
591 }
592 return -EINVAL;
593}
594
595
596static struct clk_ops tegra_pll_div_ops = {
597 .init = tegra2_pll_div_clk_init,
598 .enable = tegra2_pll_div_clk_enable,
599 .disable = tegra2_pll_div_clk_disable,
600 .set_rate = tegra2_pll_div_clk_set_rate,
601 .recalculate_rate = tegra2_clk_recalculate_rate,
602};
603
604/* Periph clk ops */
605
606static void tegra2_periph_clk_init(struct clk *c)
607{
608 u32 val = clk_readl(c->reg);
609 const struct clk_mux_sel *mux = 0;
610 const struct clk_mux_sel *sel;
611 if (c->flags & MUX) {
612 for (sel = c->inputs; sel->input != NULL; sel++) {
613 if (val >> PERIPH_CLK_SOURCE_SHIFT == sel->value)
614 mux = sel;
615 }
616 BUG_ON(!mux);
617
618 c->parent = mux->input;
619 } else {
620 c->parent = c->inputs[0].input;
621 }
622
623 if (c->flags & DIV_U71) {
624 u32 divu71 = val & PERIPH_CLK_SOURCE_DIV_MASK;
625 c->div = divu71 + 2;
626 c->mul = 2;
627 } else {
628 c->div = 1;
629 c->mul = 1;
630 }
631
632 c->state = ON;
633 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
634 PERIPH_CLK_TO_ENB_BIT(c)))
635 c->state = OFF;
636 if (!(c->flags & PERIPH_NO_RESET))
637 if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
638 PERIPH_CLK_TO_ENB_BIT(c))
639 c->state = OFF;
640 tegra2_clk_recalculate_rate(c);
641}
642
643static int tegra2_periph_clk_enable(struct clk *c)
644{
645 u32 val;
646 pr_debug("%s on clock %s\n", __func__, c->name);
647
648 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
649 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
650 if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET))
651 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
652 RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
653 if (c->flags & PERIPH_EMC_ENB) {
654 /* The EMC peripheral clock has 2 extra enable bits */
655 /* FIXME: Do they need to be disabled? */
656 val = clk_readl(c->reg);
657 val |= 0x3 << 24;
658 clk_writel(val, c->reg);
659 }
660 return 0;
661}
662
663static void tegra2_periph_clk_disable(struct clk *c)
664{
665 pr_debug("%s on clock %s\n", __func__, c->name);
666
667 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
668 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
669}
670
671void tegra2_periph_reset_deassert(struct clk *c)
672{
673 pr_debug("%s on clock %s\n", __func__, c->name);
674 if (!(c->flags & PERIPH_NO_RESET))
675 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
676 RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
677}
678
679void tegra2_periph_reset_assert(struct clk *c)
680{
681 pr_debug("%s on clock %s\n", __func__, c->name);
682 if (!(c->flags & PERIPH_NO_RESET))
683 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
684 RST_DEVICES_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
685}
686
687
688static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
689{
690 u32 val;
691 const struct clk_mux_sel *sel;
692 pr_debug("%s: %s %s\n", __func__, c->name, p->name);
693 for (sel = c->inputs; sel->input != NULL; sel++) {
694 if (sel->input == p) {
695 clk_reparent(c, p);
696 val = clk_readl(c->reg);
697 val &= ~PERIPH_CLK_SOURCE_MASK;
698 val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT;
699 clk_writel(val, c->reg);
700 c->rate = c->parent->rate;
701 return 0;
702 }
703 }
704
705 return -EINVAL;
706}
707
708static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
709{
710 u32 val;
711 int divider_u71;
712 pr_debug("%s: %lu\n", __func__, rate);
713 if (c->flags & DIV_U71) {
714 divider_u71 = clk_div71_get_divider(c->parent, rate);
715 if (divider_u71 >= 0) {
716 val = clk_readl(c->reg);
717 val &= ~PERIPH_CLK_SOURCE_DIV_MASK;
718 val |= divider_u71;
719 clk_writel(val, c->reg);
720 c->div = divider_u71 + 2;
721 c->mul = 2;
722 tegra2_clk_recalculate_rate(c);
723 return 0;
724 }
725 }
726 return -EINVAL;
727}
728
729static struct clk_ops tegra_periph_clk_ops = {
730 .init = &tegra2_periph_clk_init,
731 .enable = &tegra2_periph_clk_enable,
732 .disable = &tegra2_periph_clk_disable,
733 .set_parent = &tegra2_periph_clk_set_parent,
734 .set_rate = &tegra2_periph_clk_set_rate,
735 .recalculate_rate = &tegra2_clk_recalculate_rate,
736};
737
738/* Clock doubler ops */
739static void tegra2_clk_double_init(struct clk *c)
740{
741 c->mul = 2;
742 c->div = 1;
743 c->state = ON;
744 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
745 PERIPH_CLK_TO_ENB_BIT(c)))
746 c->state = OFF;
747 tegra2_clk_recalculate_rate(c);
748};
749
750static struct clk_ops tegra_clk_double_ops = {
751 .init = &tegra2_clk_double_init,
752 .enable = &tegra2_periph_clk_enable,
753 .disable = &tegra2_periph_clk_disable,
754 .recalculate_rate = &tegra2_clk_recalculate_rate,
755};
756
757/* Clock definitions */
758static struct clk tegra_clk_32k = {
759 .name = "clk_32k",
760 .rate = 32678,
761 .ops = NULL,
762};
763
764static struct clk_pll_table tegra_pll_s_table[] = {
765 {32768, 12000000, 366, 1, 1, 0},
766 {32768, 13000000, 397, 1, 1, 0},
767 {32768, 19200000, 586, 1, 1, 0},
768 {32768, 26000000, 793, 1, 1, 0},
769 {0, 0, 0, 0, 0, 0},
770};
771
772static struct clk tegra_pll_s = {
773 .name = "pll_s",
774 .flags = PLL_ALT_MISC_REG,
775 .ops = &tegra_pll_ops,
776 .reg = 0xf0,
777 .input_min = 32768,
778 .input_max = 32768,
779 .parent = &tegra_clk_32k,
780 .cf_min = 0, /* FIXME */
781 .cf_max = 0, /* FIXME */
782 .vco_min = 12000000,
783 .vco_max = 26000000,
784 .pll_table = tegra_pll_s_table,
785};
786
787static struct clk_mux_sel tegra_clk_m_sel[] = {
788 { .input = &tegra_clk_32k, .value = 0},
789 { .input = &tegra_pll_s, .value = 1},
790 { 0, 0},
791};
792static struct clk tegra_clk_m = {
793 .name = "clk_m",
794 .flags = ENABLE_ON_INIT,
795 .ops = &tegra_clk_m_ops,
796 .inputs = tegra_clk_m_sel,
797 .reg = 0x1fc,
798 .reg_mask = (1<<28),
799 .reg_shift = 28,
800};
801
802static struct clk_pll_table tegra_pll_c_table[] = {
803 { 0, 0, 0, 0, 0, 0 },
804};
805
806static struct clk tegra_pll_c = {
807 .name = "pll_c",
808 .flags = PLL_HAS_CPCON,
809 .ops = &tegra_pll_ops,
810 .reg = 0x80,
811 .input_min = 2000000,
812 .input_max = 31000000,
813 .parent = &tegra_clk_m,
814 .cf_min = 1000000,
815 .cf_max = 6000000,
816 .vco_min = 20000000,
817 .vco_max = 1400000000,
818 .pll_table = tegra_pll_c_table,
819};
820
821static struct clk tegra_pll_c_out1 = {
822 .name = "pll_c_out1",
823 .ops = &tegra_pll_div_ops,
824 .flags = DIV_U71,
825 .parent = &tegra_pll_c,
826 .reg = 0x84,
827 .reg_shift = 0,
828};
829
830static struct clk_pll_table tegra_pll_m_table[] = {
831 { 0, 0, 0, 0, 0, 0 },
832};
833
834static struct clk tegra_pll_m = {
835 .name = "pll_m",
836 .flags = PLL_HAS_CPCON,
837 .ops = &tegra_pll_ops,
838 .reg = 0x90,
839 .input_min = 2000000,
840 .input_max = 31000000,
841 .parent = &tegra_clk_m,
842 .cf_min = 1000000,
843 .cf_max = 6000000,
844 .vco_min = 20000000,
845 .vco_max = 1200000000,
846 .pll_table = tegra_pll_m_table,
847};
848
849static struct clk tegra_pll_m_out1 = {
850 .name = "pll_m_out1",
851 .ops = &tegra_pll_div_ops,
852 .flags = DIV_U71,
853 .parent = &tegra_pll_m,
854 .reg = 0x94,
855 .reg_shift = 0,
856};
857
858static struct clk_pll_table tegra_pll_p_table[] = {
859 { 12000000, 216000000, 432, 12, 2, 8},
860 { 13000000, 216000000, 432, 13, 2, 8},
861 { 19200000, 216000000, 90, 4, 2, 1},
862 { 26000000, 216000000, 432, 26, 2, 8},
863 { 12000000, 432000000, 432, 12, 1, 8},
864 { 13000000, 432000000, 432, 13, 1, 8},
865 { 19200000, 432000000, 90, 4, 1, 1},
866 { 26000000, 432000000, 432, 26, 1, 8},
867 { 0, 0, 0, 0, 0, 0 },
868};
869
870static struct clk tegra_pll_p = {
871 .name = "pll_p",
872 .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
873 .ops = &tegra_pll_ops,
874 .reg = 0xa0,
875 .input_min = 2000000,
876 .input_max = 31000000,
877 .parent = &tegra_clk_m,
878 .cf_min = 1000000,
879 .cf_max = 6000000,
880 .vco_min = 20000000,
881 .vco_max = 1400000000,
882 .pll_table = tegra_pll_p_table,
883};
884
885static struct clk tegra_pll_p_out1 = {
886 .name = "pll_p_out1",
887 .ops = &tegra_pll_div_ops,
888 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
889 .parent = &tegra_pll_p,
890 .reg = 0xa4,
891 .reg_shift = 0,
892};
893
894static struct clk tegra_pll_p_out2 = {
895 .name = "pll_p_out2",
896 .ops = &tegra_pll_div_ops,
897 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
898 .parent = &tegra_pll_p,
899 .reg = 0xa4,
900 .reg_shift = 16,
901};
902
903static struct clk tegra_pll_p_out3 = {
904 .name = "pll_p_out3",
905 .ops = &tegra_pll_div_ops,
906 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
907 .parent = &tegra_pll_p,
908 .reg = 0xa8,
909 .reg_shift = 0,
910};
911
912static struct clk tegra_pll_p_out4 = {
913 .name = "pll_p_out4",
914 .ops = &tegra_pll_div_ops,
915 .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
916 .parent = &tegra_pll_p,
917 .reg = 0xa8,
918 .reg_shift = 16,
919};
920
921static struct clk_pll_table tegra_pll_a_table[] = {
922 { 28800000, 56448000, 49, 25, 1, 1},
923 { 28800000, 73728000, 64, 25, 1, 1},
924 { 28800000, 11289600, 49, 25, 1, 1},
925 { 28800000, 12288000, 64, 25, 1, 1},
926 { 0, 0, 0, 0, 0, 0 },
927};
928
929static struct clk tegra_pll_a = {
930 .name = "pll_a",
931 .flags = PLL_HAS_CPCON,
932 .ops = &tegra_pll_ops,
933 .reg = 0xb0,
934 .input_min = 2000000,
935 .input_max = 31000000,
936 .parent = &tegra_pll_p_out1,
937 .cf_min = 1000000,
938 .cf_max = 6000000,
939 .vco_min = 20000000,
940 .vco_max = 1400000000,
941 .pll_table = tegra_pll_a_table,
942};
943
944static struct clk tegra_pll_a_out0 = {
945 .name = "pll_a_out0",
946 .ops = &tegra_pll_div_ops,
947 .flags = DIV_U71,
948 .parent = &tegra_pll_a,
949 .reg = 0xb4,
950 .reg_shift = 0,
951};
952
953static struct clk_pll_table tegra_pll_d_table[] = {
954 { 12000000, 1000000000, 1000, 12, 1, 12},
955 { 13000000, 1000000000, 1000, 13, 1, 12},
956 { 19200000, 1000000000, 625, 12, 1, 8},
957 { 26000000, 1000000000, 1000, 26, 1, 12},
958 { 0, 0, 0, 0, 0, 0 },
959};
960
961static struct clk tegra_pll_d = {
962 .name = "pll_d",
963 .flags = PLL_HAS_CPCON | PLLD,
964 .ops = &tegra_pll_ops,
965 .reg = 0xd0,
966 .input_min = 2000000,
967 .input_max = 40000000,
968 .parent = &tegra_clk_m,
969 .cf_min = 1000000,
970 .cf_max = 6000000,
971 .vco_min = 40000000,
972 .vco_max = 1000000000,
973 .pll_table = tegra_pll_d_table,
974};
975
976static struct clk tegra_pll_d_out0 = {
977 .name = "pll_d_out0",
978 .ops = &tegra_pll_div_ops,
979 .flags = DIV_2 | PLLD,
980 .parent = &tegra_pll_d,
981};
982
983static struct clk_pll_table tegra_pll_u_table[] = {
984 { 12000000, 480000000, 960, 12, 1, 0},
985 { 13000000, 480000000, 960, 13, 1, 0},
986 { 19200000, 480000000, 200, 4, 1, 0},
987 { 26000000, 480000000, 960, 26, 1, 0},
988 { 0, 0, 0, 0, 0, 0 },
989};
990
991static struct clk tegra_pll_u = {
992 .name = "pll_u",
993 .flags = 0,
994 .ops = &tegra_pll_ops,
995 .reg = 0xc0,
996 .input_min = 2000000,
997 .input_max = 40000000,
998 .parent = &tegra_clk_m,
999 .cf_min = 1000000,
1000 .cf_max = 6000000,
1001 .vco_min = 480000000,
1002 .vco_max = 960000000,
1003 .pll_table = tegra_pll_u_table,
1004};
1005
1006static struct clk_pll_table tegra_pll_x_table[] = {
1007 { 12000000, 1000000000, 1000, 12, 1, 12},
1008 { 13000000, 1000000000, 1000, 13, 1, 12},
1009 { 19200000, 1000000000, 625, 12, 1, 8},
1010 { 26000000, 1000000000, 1000, 26, 1, 12},
1011 { 12000000, 750000000, 750, 12, 1, 12},
1012 { 13000000, 750000000, 750, 13, 1, 12},
1013 { 19200000, 750000000, 625, 16, 1, 8},
1014 { 26000000, 750000000, 750, 26, 1, 12},
1015 { 0, 0, 0, 0, 0, 0 },
1016};
1017
1018static struct clk tegra_pll_x = {
1019 .name = "pll_x",
1020 .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG,
1021 .ops = &tegra_pll_ops,
1022 .reg = 0xe0,
1023 .input_min = 2000000,
1024 .input_max = 31000000,
1025 .parent = &tegra_clk_m,
1026 .cf_min = 1000000,
1027 .cf_max = 6000000,
1028 .vco_min = 20000000,
1029 .vco_max = 1200000000,
1030 .pll_table = tegra_pll_x_table,
1031};
1032
1033static struct clk tegra_clk_d = {
1034 .name = "clk_d",
1035 .flags = PERIPH_NO_RESET,
1036 .ops = &tegra_clk_double_ops,
1037 .clk_num = 90,
1038 .reg = 0x34,
1039 .reg_shift = 12,
1040 .parent = &tegra_clk_m,
1041};
1042
1043/* FIXME: need tegra_audio
1044static struct clk tegra_clk_audio_2x = {
1045 .name = "clk_d",
1046 .flags = PERIPH_NO_RESET,
1047 .ops = &tegra_clk_double_ops,
1048 .clk_num = 89,
1049 .reg = 0x34,
1050 .reg_shift = 8,
1051 .parent = &tegra_audio,
1052}
1053*/
1054
1055static struct clk_mux_sel mux_cclk[] = {
1056 { .input = &tegra_clk_m, .value = 0},
1057 { .input = &tegra_pll_c, .value = 1},
1058 { .input = &tegra_clk_32k, .value = 2},
1059 { .input = &tegra_pll_m, .value = 3},
1060 { .input = &tegra_pll_p, .value = 4},
1061 { .input = &tegra_pll_p_out4, .value = 5},
1062 { .input = &tegra_pll_p_out3, .value = 6},
1063 { .input = &tegra_clk_d, .value = 7},
1064 { .input = &tegra_pll_x, .value = 8},
1065 { 0, 0},
1066};
1067
1068static struct clk_mux_sel mux_sclk[] = {
1069 { .input = &tegra_clk_m, .value = 0},
1070 { .input = &tegra_pll_c_out1, .value = 1},
1071 { .input = &tegra_pll_p_out4, .value = 2},
1072 { .input = &tegra_pll_p_out3, .value = 3},
1073 { .input = &tegra_pll_p_out2, .value = 4},
1074 { .input = &tegra_clk_d, .value = 5},
1075 { .input = &tegra_clk_32k, .value = 6},
1076 { .input = &tegra_pll_m_out1, .value = 7},
1077 { 0, 0},
1078};
1079
1080static struct clk tegra_clk_cpu = {
1081 .name = "cpu",
1082 .inputs = mux_cclk,
1083 .reg = 0x20,
1084 .ops = &tegra_super_ops,
1085};
1086
1087static struct clk tegra_clk_sys = {
1088 .name = "sys",
1089 .inputs = mux_sclk,
1090 .reg = 0x28,
1091 .ops = &tegra_super_ops,
1092};
1093
1094static struct clk tegra_clk_hclk = {
1095 .name = "hclk",
1096 .flags = DIV_BUS,
1097 .parent = &tegra_clk_sys,
1098 .reg = 0x30,
1099 .reg_shift = 4,
1100 .ops = &tegra_bus_ops,
1101};
1102
1103static struct clk tegra_clk_pclk = {
1104 .name = "pclk",
1105 .flags = DIV_BUS,
1106 .parent = &tegra_clk_hclk,
1107 .reg = 0x30,
1108 .reg_shift = 0,
1109 .ops = &tegra_bus_ops,
1110};
1111
1112static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
1113 { .input = &tegra_pll_m, .value = 0},
1114 { .input = &tegra_pll_c, .value = 1},
1115 { .input = &tegra_pll_p, .value = 2},
1116 { .input = &tegra_pll_a_out0, .value = 3},
1117 { 0, 0},
1118};
1119
1120static struct clk_mux_sel mux_pllm_pllc_pllp_clkm[] = {
1121 { .input = &tegra_pll_m, .value = 0},
1122 { .input = &tegra_pll_c, .value = 1},
1123 { .input = &tegra_pll_p, .value = 2},
1124 { .input = &tegra_clk_m, .value = 3},
1125 { 0, 0},
1126};
1127
1128static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
1129 { .input = &tegra_pll_p, .value = 0},
1130 { .input = &tegra_pll_c, .value = 1},
1131 { .input = &tegra_pll_m, .value = 2},
1132 { .input = &tegra_clk_m, .value = 3},
1133 { 0, 0},
1134};
1135
1136static struct clk_mux_sel mux_plla_audio_pllp_clkm[] = {
1137 {.input = &tegra_pll_a, .value = 0},
1138 /* FIXME: no mux defined for tegra_audio
1139 {.input = &tegra_audio, .value = 1},*/
1140 {.input = &tegra_pll_p, .value = 2},
1141 {.input = &tegra_clk_m, .value = 3},
1142 { 0, 0},
1143};
1144
1145static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
1146 {.input = &tegra_pll_p, .value = 0},
1147 {.input = &tegra_pll_d_out0, .value = 1},
1148 {.input = &tegra_pll_c, .value = 2},
1149 {.input = &tegra_clk_m, .value = 3},
1150 { 0, 0},
1151};
1152
1153static struct clk_mux_sel mux_pllp_pllc_audio_clkm_clk32[] = {
1154 {.input = &tegra_pll_p, .value = 0},
1155 {.input = &tegra_pll_c, .value = 1},
1156 /* FIXME: no mux defined for tegra_audio
1157 {.input = &tegra_audio, .value = 2},*/
1158 {.input = &tegra_clk_m, .value = 3},
1159 {.input = &tegra_clk_32k, .value = 4},
1160 { 0, 0},
1161};
1162
1163static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
1164 {.input = &tegra_pll_p, .value = 0},
1165 {.input = &tegra_pll_c, .value = 1},
1166 {.input = &tegra_pll_m, .value = 2},
1167 { 0, 0},
1168};
1169
1170static struct clk_mux_sel mux_clk_m[] = {
1171 { .input = &tegra_clk_m, .value = 0},
1172 { 0, 0},
1173};
1174
1175static struct clk_mux_sel mux_pllp_out3[] = {
1176 { .input = &tegra_pll_p_out3, .value = 0},
1177 { 0, 0},
1178};
1179
1180static struct clk_mux_sel mux_plld[] = {
1181 { .input = &tegra_pll_d, .value = 0},
1182 { 0, 0},
1183};
1184
1185static struct clk_mux_sel mux_clk_32k[] = {
1186 { .input = &tegra_clk_32k, .value = 0},
1187 { 0, 0},
1188};
1189
1190#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _inputs, _flags) \
1191 { \
1192 .name = _name, \
1193 .lookup = { \
1194 .dev_id = _dev, \
1195 .con_id = _con, \
1196 }, \
1197 .ops = &tegra_periph_clk_ops, \
1198 .clk_num = _clk_num, \
1199 .reg = _reg, \
1200 .inputs = _inputs, \
1201 .flags = _flags, \
1202 }
1203
1204struct clk tegra_periph_clks[] = {
1205 PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, mux_clk_32k, PERIPH_NO_RESET),
1206 PERIPH_CLK("timer", "timer", NULL, 5, 0, mux_clk_m, 0),
1207 PERIPH_CLK("i2s1", "i2s.0", NULL, 11, 0x100, mux_plla_audio_pllp_clkm, MUX | DIV_U71),
1208 PERIPH_CLK("i2s2", "i2s.1", NULL, 18, 0x104, mux_plla_audio_pllp_clkm, MUX | DIV_U71),
1209 /* FIXME: spdif has 2 clocks but 1 enable */
1210 PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, mux_plla_audio_pllp_clkm, MUX | DIV_U71),
1211 PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, mux_pllp_pllc_pllm, MUX | DIV_U71),
1212 PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71),
1213 PERIPH_CLK("spi", "spi", NULL, 43, 0x114, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1214 PERIPH_CLK("xio", "xio", NULL, 45, 0x120, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1215 PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1216 PERIPH_CLK("sbc1", "spi_tegra.0", NULL, 41, 0x134, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1217 PERIPH_CLK("sbc2", "spi_tegra.1", NULL, 44, 0x118, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1218 PERIPH_CLK("sbc3", "spi_tegra.2", NULL, 46, 0x11c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1219 PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1220 PERIPH_CLK("ide", "ide", NULL, 25, 0x144, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1221 PERIPH_CLK("ndflash", "tegra_nand", NULL, 13, 0x160, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1222 /* FIXME: vfir shares an enable with uartb */
1223 PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1224 PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1225 PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1226 PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1227 PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x160, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1228 PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1229 PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1230 /* FIXME: what is la? */
1231 PERIPH_CLK("la", "la", NULL, 76, 0x1f8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1232 PERIPH_CLK("owr", "owr", NULL, 71, 0x1cc, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1233 PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1234 PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1235 PERIPH_CLK("i2c1", "tegra-i2c.0", NULL, 12, 0x124, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1236 PERIPH_CLK("i2c2", "tegra-i2c.1", NULL, 54, 0x198, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1237 PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1238 PERIPH_CLK("dvc", "tegra-i2c.3", NULL, 47, 0x128, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1239 PERIPH_CLK("i2c1_i2c", "tegra-i2c.0", "i2c", 0, 0, mux_pllp_out3, 0),
1240 PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, mux_pllp_out3, 0),
1241 PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, mux_pllp_out3, 0),
1242 PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, mux_pllp_out3, 0),
1243 PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1244 PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1245 PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1246 PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1247 PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1248 PERIPH_CLK("3d", "3d", NULL, 24, 0x158, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET),
1249 PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
1250 /* FIXME: vi and vi_sensor share an enable */
1251 PERIPH_CLK("vi", "vi", NULL, 20, 0x148, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
1252 PERIPH_CLK("vi_sensor", "vi_sensor", NULL, 20, 0x1a8, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
1253 PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
1254 PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
1255 PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
1256 /* FIXME: cve and tvo share an enable */
1257 PERIPH_CLK("cve", "cve", NULL, 49, 0x140, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
1258 PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
1259 PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
1260 PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
1261 PERIPH_CLK("disp1", "tegrafb.0", NULL, 27, 0x138, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
1262 PERIPH_CLK("disp2", "tegrafb.1", NULL, 26, 0x13c, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
1263 PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, mux_clk_m, 0),
1264 PERIPH_CLK("usb2", "usb.1", NULL, 58, 0, mux_clk_m, 0),
1265 PERIPH_CLK("usb3", "usb.2", NULL, 59, 0, mux_clk_m, 0),
1266 PERIPH_CLK("emc", "emc", NULL, 57, 0x19c, mux_pllm_pllc_pllp_clkm, MUX | DIV_U71 | PERIPH_EMC_ENB),
1267 PERIPH_CLK("dsi", "dsi", NULL, 48, 0, mux_plld, 0),
1268};
1269
1270#define CLK_DUPLICATE(_name, _dev, _con) \
1271 { \
1272 .name = _name, \
1273 .lookup = { \
1274 .dev_id = _dev, \
1275 .con_id = _con, \
1276 }, \
1277 }
1278
1279/* Some clocks may be used by different drivers depending on the board
1280 * configuration. List those here to register them twice in the clock lookup
1281 * table under two names.
1282 */
1283struct clk_duplicate tegra_clk_duplicates[] = {
1284 CLK_DUPLICATE("uarta", "tegra_uart.0", NULL),
1285 CLK_DUPLICATE("uartb", "tegra_uart.1", NULL),
1286 CLK_DUPLICATE("uartc", "tegra_uart.2", NULL),
1287 CLK_DUPLICATE("uartd", "tegra_uart.3", NULL),
1288 CLK_DUPLICATE("uarte", "tegra_uart.4", NULL),
1289};
1290
1291#define CLK(dev, con, ck) \
1292 { \
1293 .dev_id = dev, \
1294 .con_id = con, \
1295 .clk = ck, \
1296 }
1297
1298struct clk_lookup tegra_clk_lookups[] = {
1299 /* external root sources */
1300 CLK(NULL, "32k_clk", &tegra_clk_32k),
1301 CLK(NULL, "pll_s", &tegra_pll_s),
1302 CLK(NULL, "clk_m", &tegra_clk_m),
1303 CLK(NULL, "pll_m", &tegra_pll_m),
1304 CLK(NULL, "pll_m_out1", &tegra_pll_m_out1),
1305 CLK(NULL, "pll_c", &tegra_pll_c),
1306 CLK(NULL, "pll_c_out1", &tegra_pll_c_out1),
1307 CLK(NULL, "pll_p", &tegra_pll_p),
1308 CLK(NULL, "pll_p_out1", &tegra_pll_p_out1),
1309 CLK(NULL, "pll_p_out2", &tegra_pll_p_out2),
1310 CLK(NULL, "pll_p_out3", &tegra_pll_p_out3),
1311 CLK(NULL, "pll_p_out4", &tegra_pll_p_out4),
1312 CLK(NULL, "pll_a", &tegra_pll_a),
1313 CLK(NULL, "pll_a_out0", &tegra_pll_a_out0),
1314 CLK(NULL, "pll_d", &tegra_pll_d),
1315 CLK(NULL, "pll_d_out0", &tegra_pll_d_out0),
1316 CLK(NULL, "pll_u", &tegra_pll_u),
1317 CLK(NULL, "pll_x", &tegra_pll_x),
1318 CLK(NULL, "cpu", &tegra_clk_cpu),
1319 CLK(NULL, "sys", &tegra_clk_sys),
1320 CLK(NULL, "hclk", &tegra_clk_hclk),
1321 CLK(NULL, "pclk", &tegra_clk_pclk),
1322 CLK(NULL, "clk_d", &tegra_clk_d),
1323};
1324
1325void __init tegra2_init_clocks(void)
1326{
1327 int i;
1328 struct clk_lookup *cl;
1329 struct clk *c;
1330 struct clk_duplicate *cd;
1331
1332 for (i = 0; i < ARRAY_SIZE(tegra_clk_lookups); i++) {
1333 cl = &tegra_clk_lookups[i];
1334 clk_init(cl->clk);
1335 clkdev_add(cl);
1336 }
1337
1338 for (i = 0; i < ARRAY_SIZE(tegra_periph_clks); i++) {
1339 c = &tegra_periph_clks[i];
1340 cl = &c->lookup;
1341 cl->clk = c;
1342
1343 clk_init(cl->clk);
1344 clkdev_add(cl);
1345 }
1346
1347 for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
1348 cd = &tegra_clk_duplicates[i];
1349 c = tegra_get_clock_by_name(cd->name);
1350 if (c) {
1351 cl = &cd->lookup;
1352 cl->clk = c;
1353 clkdev_add(cl);
1354 } else {
1355 pr_err("%s: Unknown duplicate clock %s\n", __func__,
1356 cd->name);
1357 }
1358 }
1359}
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
new file mode 100644
index 000000000000..2f420210d406
--- /dev/null
+++ b/arch/arm/mach-tegra/timer.c
@@ -0,0 +1,187 @@
1/*
2 * arch/arch/mach-tegra/timer.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/init.h>
21#include <linux/time.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/clockchips.h>
25#include <linux/clocksource.h>
26#include <linux/clk.h>
27#include <linux/io.h>
28#include <linux/cnt32_to_63.h>
29
30#include <asm/mach/time.h>
31#include <asm/mach/time.h>
32#include <asm/localtimer.h>
33
34#include <mach/iomap.h>
35#include <mach/irqs.h>
36
37#include "board.h"
38#include "clock.h"
39
40#define TIMERUS_CNTR_1US 0x10
41#define TIMERUS_USEC_CFG 0x14
42#define TIMERUS_CNTR_FREEZE 0x4c
43
44#define TIMER1_BASE 0x0
45#define TIMER2_BASE 0x8
46#define TIMER3_BASE 0x50
47#define TIMER4_BASE 0x58
48
49#define TIMER_PTV 0x0
50#define TIMER_PCR 0x4
51
52struct tegra_timer;
53
54static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE);
55
56#define timer_writel(value, reg) \
57 __raw_writel(value, (u32)timer_reg_base + (reg))
58#define timer_readl(reg) \
59 __raw_readl((u32)timer_reg_base + (reg))
60
61static int tegra_timer_set_next_event(unsigned long cycles,
62 struct clock_event_device *evt)
63{
64 u32 reg;
65
66 reg = 0x80000000 | ((cycles > 1) ? (cycles-1) : 0);
67 timer_writel(reg, TIMER3_BASE + TIMER_PTV);
68
69 return 0;
70}
71
72static void tegra_timer_set_mode(enum clock_event_mode mode,
73 struct clock_event_device *evt)
74{
75 u32 reg;
76
77 timer_writel(0, TIMER3_BASE + TIMER_PTV);
78
79 switch (mode) {
80 case CLOCK_EVT_MODE_PERIODIC:
81 reg = 0xC0000000 | ((1000000/HZ)-1);
82 timer_writel(reg, TIMER3_BASE + TIMER_PTV);
83 break;
84 case CLOCK_EVT_MODE_ONESHOT:
85 break;
86 case CLOCK_EVT_MODE_UNUSED:
87 case CLOCK_EVT_MODE_SHUTDOWN:
88 case CLOCK_EVT_MODE_RESUME:
89 break;
90 }
91}
92
93static cycle_t tegra_clocksource_read(struct clocksource *cs)
94{
95 return cnt32_to_63(timer_readl(TIMERUS_CNTR_1US));
96}
97
98static struct clock_event_device tegra_clockevent = {
99 .name = "timer0",
100 .rating = 300,
101 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
102 .set_next_event = tegra_timer_set_next_event,
103 .set_mode = tegra_timer_set_mode,
104};
105
106static struct clocksource tegra_clocksource = {
107 .name = "timer_us",
108 .rating = 300,
109 .read = tegra_clocksource_read,
110 .mask = 0x7FFFFFFFFFFFFFFFULL,
111 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
112};
113
114unsigned long long sched_clock(void)
115{
116 return clocksource_cyc2ns(tegra_clocksource.read(&tegra_clocksource),
117 tegra_clocksource.mult, tegra_clocksource.shift);
118}
119
120static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
121{
122 struct clock_event_device *evt = (struct clock_event_device *)dev_id;
123 timer_writel(1<<30, TIMER3_BASE + TIMER_PCR);
124 evt->event_handler(evt);
125 return IRQ_HANDLED;
126}
127
128static struct irqaction tegra_timer_irq = {
129 .name = "timer0",
130 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH,
131 .handler = tegra_timer_interrupt,
132 .dev_id = &tegra_clockevent,
133 .irq = INT_TMR3,
134};
135
136static void __init tegra_init_timer(void)
137{
138 unsigned long rate = clk_measure_input_freq();
139 int ret;
140
141#ifdef CONFIG_HAVE_ARM_TWD
142 twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
143#endif
144
145 switch (rate) {
146 case 12000000:
147 timer_writel(0x000b, TIMERUS_USEC_CFG);
148 break;
149 case 13000000:
150 timer_writel(0x000c, TIMERUS_USEC_CFG);
151 break;
152 case 19200000:
153 timer_writel(0x045f, TIMERUS_USEC_CFG);
154 break;
155 case 26000000:
156 timer_writel(0x0019, TIMERUS_USEC_CFG);
157 break;
158 default:
159 WARN(1, "Unknown clock rate");
160 }
161
162 if (clocksource_register_hz(&tegra_clocksource, 1000000)) {
163 printk(KERN_ERR "Failed to register clocksource\n");
164 BUG();
165 }
166
167 ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq);
168 if (ret) {
169 printk(KERN_ERR "Failed to register timer IRQ: %d\n", ret);
170 BUG();
171 }
172
173 clockevents_calc_mult_shift(&tegra_clockevent, 1000000, 5);
174 tegra_clockevent.max_delta_ns =
175 clockevent_delta2ns(0x1fffffff, &tegra_clockevent);
176 tegra_clockevent.min_delta_ns =
177 clockevent_delta2ns(0x1, &tegra_clockevent);
178 tegra_clockevent.cpumask = cpu_all_mask;
179 tegra_clockevent.irq = tegra_timer_irq.irq;
180 clockevents_register_device(&tegra_clockevent);
181
182 return;
183}
184
185struct sys_timer tegra_timer = {
186 .init = tegra_init_timer,
187};
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 87ec141fcaa6..e1fd98fff8fa 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -771,7 +771,8 @@ config CACHE_L2X0
771 bool "Enable the L2x0 outer cache controller" 771 bool "Enable the L2x0 outer cache controller"
772 depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ 772 depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
773 REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \ 773 REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \
774 ARCH_NOMADIK || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 774 ARCH_NOMADIK || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
775 ARCH_TEGRA
775 default y 776 default y
776 select OUTER_CACHE 777 select OUTER_CACHE
777 select OUTER_CACHE_SYNC 778 select OUTER_CACHE_SYNC