aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r--arch/arm/mach-tegra/Kconfig36
-rw-r--r--arch/arm/mach-tegra/Makefile15
-rw-r--r--arch/arm/mach-tegra/board-harmony-pcie.c24
-rw-r--r--arch/arm/mach-tegra/board-harmony-pinmux.c35
-rw-r--r--arch/arm/mach-tegra/board-harmony-power.c117
-rw-r--r--arch/arm/mach-tegra/board-harmony.c145
-rw-r--r--arch/arm/mach-tegra/board-harmony.h15
-rw-r--r--arch/arm/mach-tegra/board-paz00-pinmux.c157
-rw-r--r--arch/arm/mach-tegra/board-paz00.c128
-rw-r--r--arch/arm/mach-tegra/board-paz00.h29
-rw-r--r--arch/arm/mach-tegra/board-seaboard-pinmux.c180
-rw-r--r--arch/arm/mach-tegra/board-seaboard.c250
-rw-r--r--arch/arm/mach-tegra/board-seaboard.h41
-rw-r--r--arch/arm/mach-tegra/board-trimslice-pinmux.c154
-rw-r--r--arch/arm/mach-tegra/board-trimslice.c125
-rw-r--r--arch/arm/mach-tegra/board-trimslice.h25
-rw-r--r--arch/arm/mach-tegra/board.h4
-rw-r--r--arch/arm/mach-tegra/clock.c532
-rw-r--r--arch/arm/mach-tegra/clock.h129
-rw-r--r--arch/arm/mach-tegra/common.c27
-rw-r--r--arch/arm/mach-tegra/cpu-tegra.c100
-rw-r--r--arch/arm/mach-tegra/devices.c575
-rw-r--r--arch/arm/mach-tegra/devices.h50
-rw-r--r--arch/arm/mach-tegra/dma.c243
-rw-r--r--arch/arm/mach-tegra/gpio.c19
-rw-r--r--arch/arm/mach-tegra/include/mach/clk.h8
-rw-r--r--arch/arm/mach-tegra/include/mach/clkdev.h2
-rw-r--r--arch/arm/mach-tegra/include/mach/debug-macro.S25
-rw-r--r--arch/arm/mach-tegra/include/mach/gpio.h9
-rw-r--r--arch/arm/mach-tegra/include/mach/harmony_audio.h (renamed from arch/arm/mach-tegra/tegra2_dvfs.h)14
-rw-r--r--arch/arm/mach-tegra/include/mach/iomap.h50
-rw-r--r--arch/arm/mach-tegra/include/mach/irqs.h14
-rw-r--r--arch/arm/mach-tegra/include/mach/kbc.h62
-rw-r--r--arch/arm/mach-tegra/include/mach/legacy_irq.h4
-rw-r--r--arch/arm/mach-tegra/include/mach/memory.h2
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux-t2.h10
-rw-r--r--arch/arm/mach-tegra/include/mach/powergate.h40
-rw-r--r--arch/arm/mach-tegra/include/mach/suspend.h38
-rw-r--r--arch/arm/mach-tegra/include/mach/system.h10
-rw-r--r--arch/arm/mach-tegra/include/mach/uncompress.h18
-rw-r--r--arch/arm/mach-tegra/include/mach/usb_phy.h86
-rw-r--r--arch/arm/mach-tegra/irq.c198
-rw-r--r--arch/arm/mach-tegra/legacy_irq.c109
-rw-r--r--arch/arm/mach-tegra/localtimer.c3
-rw-r--r--arch/arm/mach-tegra/pcie.c38
-rw-r--r--arch/arm/mach-tegra/pinmux-t2-tables.c26
-rw-r--r--arch/arm/mach-tegra/powergate.c212
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c1120
-rw-r--r--arch/arm/mach-tegra/tegra2_dvfs.c86
-rw-r--r--arch/arm/mach-tegra/tegra2_emc.c178
-rw-r--r--arch/arm/mach-tegra/tegra2_emc.h27
-rw-r--r--arch/arm/mach-tegra/timer.c77
-rw-r--r--arch/arm/mach-tegra/usb_phy.c795
53 files changed, 5360 insertions, 1056 deletions
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index acd9552f8ada..3cdeffc97b44 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -10,6 +10,9 @@ config ARCH_TEGRA_2x_SOC
10 select CPU_V7 10 select CPU_V7
11 select ARM_GIC 11 select ARM_GIC
12 select ARCH_REQUIRE_GPIOLIB 12 select ARCH_REQUIRE_GPIOLIB
13 select USB_ARCH_HAS_EHCI if USB_SUPPORT
14 select USB_ULPI if USB_SUPPORT
15 select USB_ULPI_VIEWPORT if USB_SUPPORT
13 help 16 help
14 Support for NVIDIA Tegra AP20 and T20 processors, based on the 17 Support for NVIDIA Tegra AP20 and T20 processors, based on the
15 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller 18 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
@@ -27,6 +30,36 @@ config MACH_HARMONY
27 help 30 help
28 Support for nVidia Harmony development platform 31 Support for nVidia Harmony development platform
29 32
33config MACH_KAEN
34 bool "Kaen board"
35 select MACH_SEABOARD
36 help
37 Support for the Kaen version of Seaboard
38
39config MACH_PAZ00
40 bool "Paz00 board"
41 help
42 Support for the Toshiba AC100/Dynabook AZ netbook
43
44config MACH_SEABOARD
45 bool "Seaboard board"
46 help
47 Support for nVidia Seaboard development platform. It will
48 also be included for some of the derivative boards that
49 have large similarities with the seaboard design.
50
51config MACH_TRIMSLICE
52 bool "TrimSlice board"
53 select TEGRA_PCI
54 help
55 Support for CompuLab TrimSlice platform
56
57config MACH_WARIO
58 bool "Wario board"
59 select MACH_SEABOARD
60 help
61 Support for the Wario version of Seaboard
62
30choice 63choice
31 prompt "Low-level debug console UART" 64 prompt "Low-level debug console UART"
32 default TEGRA_DEBUG_UART_NONE 65 default TEGRA_DEBUG_UART_NONE
@@ -58,4 +91,7 @@ config TEGRA_SYSTEM_DMA
58 Adds system DMA functionality for NVIDIA Tegra SoCs, used by 91 Adds system DMA functionality for NVIDIA Tegra SoCs, used by
59 several Tegra device drivers 92 several Tegra device drivers
60 93
94config TEGRA_EMC_SCALING_ENABLE
95 bool "Enable scaling the memory frequency"
96
61endif 97endif
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index cdbc68e4c0ca..1afe05038c27 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -1,21 +1,34 @@
1obj-y += common.o 1obj-y += common.o
2obj-y += devices.o
2obj-y += io.o 3obj-y += io.o
3obj-y += irq.o legacy_irq.o 4obj-y += irq.o legacy_irq.o
4obj-y += clock.o 5obj-y += clock.o
5obj-y += timer.o 6obj-y += timer.o
6obj-y += gpio.o 7obj-y += gpio.o
7obj-y += pinmux.o 8obj-y += pinmux.o
9obj-y += powergate.o
8obj-y += fuse.o 10obj-y += fuse.o
9obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o 11obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o
10obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o 12obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o
11obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_dvfs.o 13obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
12obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-t2-tables.o 14obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-t2-tables.o
13obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o 15obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o
14obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 16obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
15obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o 17obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
16obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o 18obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
17obj-$(CONFIG_TEGRA_PCI) += pcie.o 19obj-$(CONFIG_TEGRA_PCI) += pcie.o
20obj-$(CONFIG_USB_SUPPORT) += usb_phy.o
18 21
19obj-${CONFIG_MACH_HARMONY} += board-harmony.o 22obj-${CONFIG_MACH_HARMONY} += board-harmony.o
20obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o 23obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o
21obj-${CONFIG_MACH_HARMONY} += board-harmony-pcie.o 24obj-${CONFIG_MACH_HARMONY} += board-harmony-pcie.o
25obj-${CONFIG_MACH_HARMONY} += board-harmony-power.o
26
27obj-${CONFIG_MACH_PAZ00} += board-paz00.o
28obj-${CONFIG_MACH_PAZ00} += board-paz00-pinmux.o
29
30obj-${CONFIG_MACH_SEABOARD} += board-seaboard.o
31obj-${CONFIG_MACH_SEABOARD} += board-seaboard-pinmux.o
32
33obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice.o
34obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice-pinmux.o
diff --git a/arch/arm/mach-tegra/board-harmony-pcie.c b/arch/arm/mach-tegra/board-harmony-pcie.c
index f7e7d4514b6a..9c27b95b8d86 100644
--- a/arch/arm/mach-tegra/board-harmony-pcie.c
+++ b/arch/arm/mach-tegra/board-harmony-pcie.c
@@ -27,13 +27,29 @@
27 27
28#ifdef CONFIG_TEGRA_PCI 28#ifdef CONFIG_TEGRA_PCI
29 29
30/* GPIO 3 of the PMIC */
31#define EN_VDD_1V05_GPIO (TEGRA_NR_GPIOS + 2)
32
30static int __init harmony_pcie_init(void) 33static int __init harmony_pcie_init(void)
31{ 34{
35 struct regulator *regulator = NULL;
32 int err; 36 int err;
33 37
34 if (!machine_is_harmony()) 38 if (!machine_is_harmony())
35 return 0; 39 return 0;
36 40
41 err = gpio_request(EN_VDD_1V05_GPIO, "EN_VDD_1V05");
42 if (err)
43 return err;
44
45 gpio_direction_output(EN_VDD_1V05_GPIO, 1);
46
47 regulator = regulator_get(NULL, "pex_clk");
48 if (IS_ERR_OR_NULL(regulator))
49 goto err_reg;
50
51 regulator_enable(regulator);
52
37 tegra_pinmux_set_tristate(TEGRA_PINGROUP_GPV, TEGRA_TRI_NORMAL); 53 tegra_pinmux_set_tristate(TEGRA_PINGROUP_GPV, TEGRA_TRI_NORMAL);
38 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_NORMAL); 54 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_NORMAL);
39 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_NORMAL); 55 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_NORMAL);
@@ -49,9 +65,15 @@ err_pcie:
49 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_TRISTATE); 65 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_TRISTATE);
50 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_TRISTATE); 66 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_TRISTATE);
51 67
68 regulator_disable(regulator);
69 regulator_put(regulator);
70err_reg:
71 gpio_free(EN_VDD_1V05_GPIO);
72
52 return err; 73 return err;
53} 74}
54 75
55subsys_initcall(harmony_pcie_init); 76/* PCI should be initialized after I2C, mfd and regulators */
77subsys_initcall_sync(harmony_pcie_init);
56 78
57#endif 79#endif
diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c
index 50b15d500cac..4d63e2e97a8d 100644
--- a/arch/arm/mach-tegra/board-harmony-pinmux.c
+++ b/arch/arm/mach-tegra/board-harmony-pinmux.c
@@ -15,8 +15,10 @@
15 */ 15 */
16 16
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/gpio.h>
18#include <mach/pinmux.h> 19#include <mach/pinmux.h>
19 20
21#include "gpio-names.h"
20#include "board-harmony.h" 22#include "board-harmony.h"
21 23
22static struct tegra_pingroup_config harmony_pinmux[] = { 24static struct tegra_pingroup_config harmony_pinmux[] = {
@@ -25,19 +27,19 @@ static struct tegra_pingroup_config harmony_pinmux[] = {
25 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 27 {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}, 28 {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}, 29 {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}, 30 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
29 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, 31 {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}, 32 {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}, 33 {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}, 34 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
33 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 35 {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}, 36 {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}, 37 {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}, 38 {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}, 39 {TEGRA_PINGROUP_DTA, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
38 {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 40 {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
39 {TEGRA_PINGROUP_DTC, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 41 {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}, 42 {TEGRA_PINGROUP_DTD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
41 {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 43 {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}, 44 {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}, 45 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
@@ -112,13 +114,13 @@ static struct tegra_pingroup_config harmony_pinmux[] = {
112 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 114 {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}, 115 {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}, 116 {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}, 117 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
116 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, 118 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
117 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, 119 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
118 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, 120 {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}, 121 {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}, 122 {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}, 123 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
122 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, 124 {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}, 125 {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}, 126 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
@@ -138,7 +140,22 @@ static struct tegra_pingroup_config harmony_pinmux[] = {
138 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 140 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
139}; 141};
140 142
143static struct tegra_gpio_table gpio_table[] = {
144 { .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
145 { .gpio = TEGRA_GPIO_SD2_WP, .enable = true },
146 { .gpio = TEGRA_GPIO_SD2_POWER, .enable = true },
147 { .gpio = TEGRA_GPIO_SD4_CD, .enable = true },
148 { .gpio = TEGRA_GPIO_SD4_WP, .enable = true },
149 { .gpio = TEGRA_GPIO_SD4_POWER, .enable = true },
150 { .gpio = TEGRA_GPIO_CDC_IRQ, .enable = true },
151 { .gpio = TEGRA_GPIO_HP_DET, .enable = true },
152 { .gpio = TEGRA_GPIO_INT_MIC_EN, .enable = true },
153 { .gpio = TEGRA_GPIO_EXT_MIC_EN, .enable = true },
154};
155
141void harmony_pinmux_init(void) 156void harmony_pinmux_init(void)
142{ 157{
143 tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux)); 158 tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux));
159
160 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
144} 161}
diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c
new file mode 100644
index 000000000000..c84442cabe07
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony-power.c
@@ -0,0 +1,117 @@
1/*
2 * Copyright (C) 2010 NVIDIA, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/gpio.h>
21
22#include <linux/regulator/machine.h>
23#include <linux/mfd/tps6586x.h>
24
25#include <mach/irqs.h>
26
27#define PMC_CTRL 0x0
28#define PMC_CTRL_INTR_LOW (1 << 17)
29
30static struct regulator_consumer_supply tps658621_ldo0_supply[] = {
31 REGULATOR_SUPPLY("pex_clk", NULL),
32};
33
34static struct regulator_init_data ldo0_data = {
35 .constraints = {
36 .min_uV = 1250 * 1000,
37 .max_uV = 3300 * 1000,
38 .valid_modes_mask = (REGULATOR_MODE_NORMAL |
39 REGULATOR_MODE_STANDBY),
40 .valid_ops_mask = (REGULATOR_CHANGE_MODE |
41 REGULATOR_CHANGE_STATUS |
42 REGULATOR_CHANGE_VOLTAGE),
43 },
44 .num_consumer_supplies = ARRAY_SIZE(tps658621_ldo0_supply),
45 .consumer_supplies = tps658621_ldo0_supply,
46};
47
48#define HARMONY_REGULATOR_INIT(_id, _minmv, _maxmv) \
49 static struct regulator_init_data _id##_data = { \
50 .constraints = { \
51 .min_uV = (_minmv)*1000, \
52 .max_uV = (_maxmv)*1000, \
53 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
54 REGULATOR_MODE_STANDBY), \
55 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
56 REGULATOR_CHANGE_STATUS | \
57 REGULATOR_CHANGE_VOLTAGE), \
58 }, \
59 }
60
61HARMONY_REGULATOR_INIT(sm0, 725, 1500);
62HARMONY_REGULATOR_INIT(sm1, 725, 1500);
63HARMONY_REGULATOR_INIT(sm2, 3000, 4550);
64HARMONY_REGULATOR_INIT(ldo1, 725, 1500);
65HARMONY_REGULATOR_INIT(ldo2, 725, 1500);
66HARMONY_REGULATOR_INIT(ldo3, 1250, 3300);
67HARMONY_REGULATOR_INIT(ldo4, 1700, 2475);
68HARMONY_REGULATOR_INIT(ldo5, 1250, 3300);
69HARMONY_REGULATOR_INIT(ldo6, 1250, 3300);
70HARMONY_REGULATOR_INIT(ldo7, 1250, 3300);
71HARMONY_REGULATOR_INIT(ldo8, 1250, 3300);
72HARMONY_REGULATOR_INIT(ldo9, 1250, 3300);
73
74#define TPS_REG(_id, _data) \
75 { \
76 .id = TPS6586X_ID_##_id, \
77 .name = "tps6586x-regulator", \
78 .platform_data = _data, \
79 }
80
81static struct tps6586x_subdev_info tps_devs[] = {
82 TPS_REG(SM_0, &sm0_data),
83 TPS_REG(SM_1, &sm1_data),
84 TPS_REG(SM_2, &sm2_data),
85 TPS_REG(LDO_0, &ldo0_data),
86 TPS_REG(LDO_1, &ldo1_data),
87 TPS_REG(LDO_2, &ldo2_data),
88 TPS_REG(LDO_3, &ldo3_data),
89 TPS_REG(LDO_4, &ldo4_data),
90 TPS_REG(LDO_5, &ldo5_data),
91 TPS_REG(LDO_6, &ldo6_data),
92 TPS_REG(LDO_7, &ldo7_data),
93 TPS_REG(LDO_8, &ldo8_data),
94 TPS_REG(LDO_9, &ldo9_data),
95};
96
97static struct tps6586x_platform_data tps_platform = {
98 .irq_base = TEGRA_NR_IRQS,
99 .num_subdevs = ARRAY_SIZE(tps_devs),
100 .subdevs = tps_devs,
101 .gpio_base = TEGRA_NR_GPIOS,
102};
103
104static struct i2c_board_info __initdata harmony_regulators[] = {
105 {
106 I2C_BOARD_INFO("tps6586x", 0x34),
107 .irq = INT_EXTERNAL_PMU,
108 .platform_data = &tps_platform,
109 },
110};
111
112int __init harmony_regulator_init(void)
113{
114 i2c_register_board_info(3, harmony_regulators, 1);
115
116 return 0;
117}
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index b9dbdb1289d0..75c918a86a31 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -2,6 +2,7 @@
2 * arch/arm/mach-tegra/board-harmony.c 2 * arch/arm/mach-tegra/board-harmony.c
3 * 3 *
4 * Copyright (C) 2010 Google, Inc. 4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA, Inc.
5 * 6 *
6 * This software is licensed under the terms of the GNU General Public 7 * 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 * License version 2, as published by the Free Software Foundation, and
@@ -22,43 +23,27 @@
22#include <linux/dma-mapping.h> 23#include <linux/dma-mapping.h>
23#include <linux/pda_power.h> 24#include <linux/pda_power.h>
24#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/gpio.h>
27#include <linux/i2c.h>
28#include <linux/i2c-tegra.h>
29
30#include <sound/wm8903.h>
25 31
26#include <asm/mach-types.h> 32#include <asm/mach-types.h>
27#include <asm/mach/arch.h> 33#include <asm/mach/arch.h>
28#include <asm/mach/time.h> 34#include <asm/mach/time.h>
29#include <asm/setup.h> 35#include <asm/setup.h>
30 36
37#include <mach/harmony_audio.h>
31#include <mach/iomap.h> 38#include <mach/iomap.h>
32#include <mach/irqs.h> 39#include <mach/irqs.h>
40#include <mach/sdhci.h>
33 41
34#include "board.h" 42#include "board.h"
35#include "board-harmony.h" 43#include "board-harmony.h"
36#include "clock.h" 44#include "clock.h"
37 45#include "devices.h"
38/* NVidia bootloader tags */ 46#include "gpio-names.h"
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 47
63static struct plat_serial8250_port debug_uart_platform_data[] = { 48static struct plat_serial8250_port debug_uart_platform_data[] = {
64 { 49 {
@@ -82,8 +67,81 @@ static struct platform_device debug_uart = {
82 }, 67 },
83}; 68};
84 69
70static struct harmony_audio_platform_data harmony_audio_pdata = {
71 .gpio_spkr_en = TEGRA_GPIO_SPKR_EN,
72 .gpio_hp_det = TEGRA_GPIO_HP_DET,
73 .gpio_int_mic_en = TEGRA_GPIO_INT_MIC_EN,
74 .gpio_ext_mic_en = TEGRA_GPIO_EXT_MIC_EN,
75};
76
77static struct platform_device harmony_audio_device = {
78 .name = "tegra-snd-harmony",
79 .id = 0,
80 .dev = {
81 .platform_data = &harmony_audio_pdata,
82 },
83};
84
85static struct tegra_i2c_platform_data harmony_i2c1_platform_data = {
86 .bus_clk_rate = 400000,
87};
88
89static struct tegra_i2c_platform_data harmony_i2c2_platform_data = {
90 .bus_clk_rate = 400000,
91};
92
93static struct tegra_i2c_platform_data harmony_i2c3_platform_data = {
94 .bus_clk_rate = 400000,
95};
96
97static struct tegra_i2c_platform_data harmony_dvc_platform_data = {
98 .bus_clk_rate = 400000,
99};
100
101static struct wm8903_platform_data harmony_wm8903_pdata = {
102 .irq_active_low = 0,
103 .micdet_cfg = 0,
104 .micdet_delay = 100,
105 .gpio_base = HARMONY_GPIO_WM8903(0),
106 .gpio_cfg = {
107 WM8903_GPIO_NO_CONFIG,
108 WM8903_GPIO_NO_CONFIG,
109 0,
110 WM8903_GPIO_NO_CONFIG,
111 WM8903_GPIO_NO_CONFIG,
112 },
113};
114
115static struct i2c_board_info __initdata wm8903_board_info = {
116 I2C_BOARD_INFO("wm8903", 0x1a),
117 .platform_data = &harmony_wm8903_pdata,
118 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
119};
120
121static void __init harmony_i2c_init(void)
122{
123 tegra_i2c_device1.dev.platform_data = &harmony_i2c1_platform_data;
124 tegra_i2c_device2.dev.platform_data = &harmony_i2c2_platform_data;
125 tegra_i2c_device3.dev.platform_data = &harmony_i2c3_platform_data;
126 tegra_i2c_device4.dev.platform_data = &harmony_dvc_platform_data;
127
128 platform_device_register(&tegra_i2c_device1);
129 platform_device_register(&tegra_i2c_device2);
130 platform_device_register(&tegra_i2c_device3);
131 platform_device_register(&tegra_i2c_device4);
132
133 i2c_register_board_info(0, &wm8903_board_info, 1);
134}
135
85static struct platform_device *harmony_devices[] __initdata = { 136static struct platform_device *harmony_devices[] __initdata = {
86 &debug_uart, 137 &debug_uart,
138 &tegra_sdhci_device1,
139 &tegra_sdhci_device2,
140 &tegra_sdhci_device4,
141 &tegra_i2s_device1,
142 &tegra_das_device,
143 &tegra_pcm_device,
144 &harmony_audio_device,
87}; 145};
88 146
89static void __init tegra_harmony_fixup(struct machine_desc *desc, 147static void __init tegra_harmony_fixup(struct machine_desc *desc,
@@ -99,25 +157,54 @@ static void __init tegra_harmony_fixup(struct machine_desc *desc,
99static __initdata struct tegra_clk_init_table harmony_clk_init_table[] = { 157static __initdata struct tegra_clk_init_table harmony_clk_init_table[] = {
100 /* name parent rate enabled */ 158 /* name parent rate enabled */
101 { "uartd", "pll_p", 216000000, true }, 159 { "uartd", "pll_p", 216000000, true },
160 { "pll_a", "pll_p_out1", 56448000, true },
161 { "pll_a_out0", "pll_a", 11289600, true },
162 { "cdev1", NULL, 0, true },
163 { "i2s1", "pll_a_out0", 11289600, false},
102 { NULL, NULL, 0, 0}, 164 { NULL, NULL, 0, 0},
103}; 165};
104 166
167
168static struct tegra_sdhci_platform_data sdhci_pdata1 = {
169 .cd_gpio = -1,
170 .wp_gpio = -1,
171 .power_gpio = -1,
172};
173
174static struct tegra_sdhci_platform_data sdhci_pdata2 = {
175 .cd_gpio = TEGRA_GPIO_SD2_CD,
176 .wp_gpio = TEGRA_GPIO_SD2_WP,
177 .power_gpio = TEGRA_GPIO_SD2_POWER,
178};
179
180static struct tegra_sdhci_platform_data sdhci_pdata4 = {
181 .cd_gpio = TEGRA_GPIO_SD4_CD,
182 .wp_gpio = TEGRA_GPIO_SD4_WP,
183 .power_gpio = TEGRA_GPIO_SD4_POWER,
184 .is_8bit = 1,
185};
186
105static void __init tegra_harmony_init(void) 187static void __init tegra_harmony_init(void)
106{ 188{
107 tegra_common_init();
108
109 tegra_clk_init_from_table(harmony_clk_init_table); 189 tegra_clk_init_from_table(harmony_clk_init_table);
110 190
111 harmony_pinmux_init(); 191 harmony_pinmux_init();
112 192
193 tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
194 tegra_sdhci_device2.dev.platform_data = &sdhci_pdata2;
195 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
196
113 platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices)); 197 platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices));
198 harmony_i2c_init();
199 harmony_regulator_init();
114} 200}
115 201
116MACHINE_START(HARMONY, "harmony") 202MACHINE_START(HARMONY, "harmony")
117 .boot_params = 0x00000100, 203 .boot_params = 0x00000100,
118 .fixup = tegra_harmony_fixup, 204 .fixup = tegra_harmony_fixup,
119 .init_irq = tegra_init_irq,
120 .init_machine = tegra_harmony_init,
121 .map_io = tegra_map_common_io, 205 .map_io = tegra_map_common_io,
206 .init_early = tegra_init_early,
207 .init_irq = tegra_init_irq,
122 .timer = &tegra_timer, 208 .timer = &tegra_timer,
209 .init_machine = tegra_harmony_init,
123MACHINE_END 210MACHINE_END
diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h
index 09ca7755dd55..1e57b071f52d 100644
--- a/arch/arm/mach-tegra/board-harmony.h
+++ b/arch/arm/mach-tegra/board-harmony.h
@@ -17,6 +17,21 @@
17#ifndef _MACH_TEGRA_BOARD_HARMONY_H 17#ifndef _MACH_TEGRA_BOARD_HARMONY_H
18#define _MACH_TEGRA_BOARD_HARMONY_H 18#define _MACH_TEGRA_BOARD_HARMONY_H
19 19
20#define HARMONY_GPIO_WM8903(_x_) (TEGRA_NR_GPIOS + (_x_))
21
22#define TEGRA_GPIO_SD2_CD TEGRA_GPIO_PI5
23#define TEGRA_GPIO_SD2_WP TEGRA_GPIO_PH1
24#define TEGRA_GPIO_SD2_POWER TEGRA_GPIO_PT3
25#define TEGRA_GPIO_SD4_CD TEGRA_GPIO_PH2
26#define TEGRA_GPIO_SD4_WP TEGRA_GPIO_PH3
27#define TEGRA_GPIO_SD4_POWER TEGRA_GPIO_PI6
28#define TEGRA_GPIO_CDC_IRQ TEGRA_GPIO_PX3
29#define TEGRA_GPIO_SPKR_EN HARMONY_GPIO_WM8903(2)
30#define TEGRA_GPIO_HP_DET TEGRA_GPIO_PW2
31#define TEGRA_GPIO_INT_MIC_EN TEGRA_GPIO_PX0
32#define TEGRA_GPIO_EXT_MIC_EN TEGRA_GPIO_PX1
33
20void harmony_pinmux_init(void); 34void harmony_pinmux_init(void);
35int harmony_regulator_init(void);
21 36
22#endif 37#endif
diff --git a/arch/arm/mach-tegra/board-paz00-pinmux.c b/arch/arm/mach-tegra/board-paz00-pinmux.c
new file mode 100644
index 000000000000..2643d1bd568b
--- /dev/null
+++ b/arch/arm/mach-tegra/board-paz00-pinmux.c
@@ -0,0 +1,157 @@
1/*
2 * arch/arm/mach-tegra/board-paz00-pinmux.c
3 *
4 * Copyright (C) 2010 Marc Dietrich <marvin24@gmx.de>
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/gpio.h>
19#include <mach/pinmux.h>
20
21#include "gpio-names.h"
22#include "board-paz00.h"
23
24static struct tegra_pingroup_config paz00_pinmux[] = {
25 {TEGRA_PINGROUP_ATA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
26 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
27 {TEGRA_PINGROUP_ATC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
28 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
29 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
30 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
31 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
32 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
33 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_PLLC_OUT1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
34 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
35 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
36 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
37 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
38 {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
39 {TEGRA_PINGROUP_DTA, TEGRA_MUX_RSVD1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
40 {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
41 {TEGRA_PINGROUP_DTC, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
42 {TEGRA_PINGROUP_DTD, TEGRA_MUX_RSVD1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
43 {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
44 {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
45 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
46 {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
47 {TEGRA_PINGROUP_GMC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
48 {TEGRA_PINGROUP_GMD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
49 {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
50 {TEGRA_PINGROUP_GPU, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
51 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
52 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
53 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
54 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
55 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
56 {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
57 {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
58 {TEGRA_PINGROUP_KBCB, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
59 {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
60 {TEGRA_PINGROUP_KBCD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
61 {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
62 {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
63 {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
64 {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
65 {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
66 {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
67 {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
68 {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
69 {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
70 {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
71 {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
72 {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
73 {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
74 {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
75 {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
76 {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
77 {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
78 {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
79 {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
80 {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
81 {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
82 {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
83 {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
84 {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
85 {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
86 {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
87 {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
88 {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
89 {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
90 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
91 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
92 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
93 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
94 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
95 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
96 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
97 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
98 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
99 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
100 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
101 {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
102 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
103 {TEGRA_PINGROUP_OWC, TEGRA_MUX_OWR, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
104 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
105 {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
106 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
107 {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
108 {TEGRA_PINGROUP_SDC, TEGRA_MUX_TWC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
109 {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
110 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
111 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
112 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
113 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
114 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
115 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
116 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
117 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
118 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
119 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
120 {TEGRA_PINGROUP_SPID, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
121 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
122 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_RSVD4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
123 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
124 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
125 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
126 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
127 {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
128 {TEGRA_PINGROUP_UAD, TEGRA_MUX_SPDIF, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
129 {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
130 {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
131 {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
132 {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
133 {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
134 {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
135 {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
136 {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
137 {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
138 {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
139 {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
140 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
141};
142
143static struct tegra_gpio_table gpio_table[] = {
144 { .gpio = TEGRA_GPIO_SD1_CD, .enable = true },
145 { .gpio = TEGRA_GPIO_SD1_WP, .enable = true },
146 { .gpio = TEGRA_GPIO_SD1_POWER, .enable = true },
147 { .gpio = TEGRA_GPIO_SD4_CD, .enable = true },
148 { .gpio = TEGRA_GPIO_SD4_WP, .enable = true },
149 { .gpio = TEGRA_GPIO_SD4_POWER, .enable = true },
150};
151
152void paz00_pinmux_init(void)
153{
154 tegra_pinmux_config_table(paz00_pinmux, ARRAY_SIZE(paz00_pinmux));
155
156 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
157}
diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
new file mode 100644
index 000000000000..57e50a823eec
--- /dev/null
+++ b/arch/arm/mach-tegra/board-paz00.c
@@ -0,0 +1,128 @@
1/*
2 * arch/arm/mach-tegra/board-paz00.c
3 *
4 * Copyright (C) 2011 Marc Dietrich <marvin24@gmx.de>
5 *
6 * Based on board-harmony.c
7 * Copyright (C) 2010 Google, Inc.
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/init.h>
22#include <linux/platform_device.h>
23#include <linux/serial_8250.h>
24#include <linux/clk.h>
25#include <linux/dma-mapping.h>
26#include <linux/pda_power.h>
27#include <linux/io.h>
28
29#include <asm/mach-types.h>
30#include <asm/mach/arch.h>
31#include <asm/mach/time.h>
32#include <asm/setup.h>
33
34#include <mach/iomap.h>
35#include <mach/irqs.h>
36#include <mach/sdhci.h>
37
38#include "board.h"
39#include "board-paz00.h"
40#include "clock.h"
41#include "devices.h"
42#include "gpio-names.h"
43
44static struct plat_serial8250_port debug_uart_platform_data[] = {
45 {
46 .membase = IO_ADDRESS(TEGRA_UARTD_BASE),
47 .mapbase = TEGRA_UARTD_BASE,
48 .irq = INT_UARTD,
49 .flags = UPF_BOOT_AUTOCONF,
50 .iotype = UPIO_MEM,
51 .regshift = 2,
52 .uartclk = 216000000,
53 }, {
54 .flags = 0
55 }
56};
57
58static struct platform_device debug_uart = {
59 .name = "serial8250",
60 .id = PLAT8250_DEV_PLATFORM,
61 .dev = {
62 .platform_data = debug_uart_platform_data,
63 },
64};
65
66static struct platform_device *paz00_devices[] __initdata = {
67 &debug_uart,
68 &tegra_sdhci_device1,
69 &tegra_sdhci_device2,
70 &tegra_sdhci_device4,
71};
72
73static void __init tegra_paz00_fixup(struct machine_desc *desc,
74 struct tag *tags, char **cmdline, struct meminfo *mi)
75{
76 mi->nr_banks = 1;
77 mi->bank[0].start = PHYS_OFFSET;
78 mi->bank[0].size = 448 * SZ_1M;
79}
80
81static __initdata struct tegra_clk_init_table paz00_clk_init_table[] = {
82 /* name parent rate enabled */
83 { "uartd", "pll_p", 216000000, true },
84 { NULL, NULL, 0, 0},
85};
86
87
88static struct tegra_sdhci_platform_data sdhci_pdata1 = {
89 .cd_gpio = TEGRA_GPIO_SD1_CD,
90 .wp_gpio = TEGRA_GPIO_SD1_WP,
91 .power_gpio = TEGRA_GPIO_SD1_POWER,
92};
93
94static struct tegra_sdhci_platform_data sdhci_pdata2 = {
95 .cd_gpio = -1,
96 .wp_gpio = -1,
97 .power_gpio = -1,
98};
99
100static struct tegra_sdhci_platform_data sdhci_pdata4 = {
101 .cd_gpio = TEGRA_GPIO_SD4_CD,
102 .wp_gpio = TEGRA_GPIO_SD4_WP,
103 .power_gpio = TEGRA_GPIO_SD4_POWER,
104 .is_8bit = 1,
105};
106
107static void __init tegra_paz00_init(void)
108{
109 tegra_clk_init_from_table(paz00_clk_init_table);
110
111 paz00_pinmux_init();
112
113 tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
114 tegra_sdhci_device2.dev.platform_data = &sdhci_pdata2;
115 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
116
117 platform_add_devices(paz00_devices, ARRAY_SIZE(paz00_devices));
118}
119
120MACHINE_START(PAZ00, "paz00")
121 .boot_params = 0x00000100,
122 .fixup = tegra_paz00_fixup,
123 .map_io = tegra_map_common_io,
124 .init_early = tegra_init_early,
125 .init_irq = tegra_init_irq,
126 .timer = &tegra_timer,
127 .init_machine = tegra_paz00_init,
128MACHINE_END
diff --git a/arch/arm/mach-tegra/board-paz00.h b/arch/arm/mach-tegra/board-paz00.h
new file mode 100644
index 000000000000..da193ca76d3b
--- /dev/null
+++ b/arch/arm/mach-tegra/board-paz00.h
@@ -0,0 +1,29 @@
1/*
2 * arch/arm/mach-tegra/board-paz00.h
3 *
4 * Copyright (C) 2010 Marc Dietrich <marvin24@gmx.de>
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_PAZ00_H
18#define _MACH_TEGRA_BOARD_PAZ00_H
19
20#define TEGRA_GPIO_SD1_CD TEGRA_GPIO_PV5
21#define TEGRA_GPIO_SD1_WP TEGRA_GPIO_PH1
22#define TEGRA_GPIO_SD1_POWER TEGRA_GPIO_PT3
23#define TEGRA_GPIO_SD4_CD TEGRA_GPIO_PH2
24#define TEGRA_GPIO_SD4_WP TEGRA_GPIO_PH3
25#define TEGRA_GPIO_SD4_POWER TEGRA_GPIO_PI6
26
27void paz00_pinmux_init(void);
28
29#endif
diff --git a/arch/arm/mach-tegra/board-seaboard-pinmux.c b/arch/arm/mach-tegra/board-seaboard-pinmux.c
new file mode 100644
index 000000000000..0bda495e9742
--- /dev/null
+++ b/arch/arm/mach-tegra/board-seaboard-pinmux.c
@@ -0,0 +1,180 @@
1/*
2 * Copyright (C) 2010 NVIDIA Corporation
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/gpio.h>
18
19#include <mach/pinmux.h>
20#include <mach/pinmux-t2.h>
21
22#include "gpio-names.h"
23#include "board-seaboard.h"
24
25#define DEFAULT_DRIVE(_name) \
26 { \
27 .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
28 .hsm = TEGRA_HSM_DISABLE, \
29 .schmitt = TEGRA_SCHMITT_ENABLE, \
30 .drive = TEGRA_DRIVE_DIV_1, \
31 .pull_down = TEGRA_PULL_31, \
32 .pull_up = TEGRA_PULL_31, \
33 .slew_rising = TEGRA_SLEW_SLOWEST, \
34 .slew_falling = TEGRA_SLEW_SLOWEST, \
35 }
36
37static __initdata struct tegra_drive_pingroup_config seaboard_drive_pinmux[] = {
38 DEFAULT_DRIVE(SDIO1),
39};
40
41static __initdata struct tegra_pingroup_config seaboard_pinmux[] = {
42 {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
43 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
44 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
45 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
46 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
47 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
48 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
49 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
50 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
51 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
52 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
53 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
54 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
55 {TEGRA_PINGROUP_DDC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
56 {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
57 {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
58 {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
59 {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
60 {TEGRA_PINGROUP_DTE, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
61 {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
62 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
63 {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
64 {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
65 {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
66 {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
67 {TEGRA_PINGROUP_GPU, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
68 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
69 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
70 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
71 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
72 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTB, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
73 {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTB, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
74 {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
75 {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
76 {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
77 {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
78 {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
79 {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
80 {TEGRA_PINGROUP_LCSN, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
81 {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
82 {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
83 {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
84 {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
85 {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
86 {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
87 {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
88 {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
89 {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
90 {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
91 {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
92 {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
93 {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
94 {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
95 {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
96 {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
97 {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
98 {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
99 {TEGRA_PINGROUP_LDC, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
100 {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
101 {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
102 {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
103 {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
104 {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
105 {TEGRA_PINGROUP_LM0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
106 {TEGRA_PINGROUP_LM1, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
107 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
108 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
109 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
110 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
111 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
112 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
113 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
114 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
115 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
116 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
117 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
118 {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
119 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
120 {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
121 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
122 {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
123 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
124 {TEGRA_PINGROUP_SDB, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
125 {TEGRA_PINGROUP_SDC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
126 {TEGRA_PINGROUP_SDD, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
127 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
128 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
129 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
130 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
131 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
132 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
133 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
134 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
135 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
136 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
137 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
138 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
139 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
140 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
141 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
142 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
143 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
144 {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
145 {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
146 {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
147 {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
148 {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
149 {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
150 {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
151 {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
152 {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
153 {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
154 {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
155 {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
156 {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
157 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
158};
159
160
161
162
163static struct tegra_gpio_table gpio_table[] = {
164 { .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
165 { .gpio = TEGRA_GPIO_SD2_WP, .enable = true },
166 { .gpio = TEGRA_GPIO_SD2_POWER, .enable = true },
167 { .gpio = TEGRA_GPIO_LIDSWITCH, .enable = true },
168 { .gpio = TEGRA_GPIO_POWERKEY, .enable = true },
169 { .gpio = TEGRA_GPIO_ISL29018_IRQ, .enable = true },
170};
171
172void __init seaboard_pinmux_init(void)
173{
174 tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux));
175
176 tegra_drive_pinmux_config_table(seaboard_drive_pinmux,
177 ARRAY_SIZE(seaboard_drive_pinmux));
178
179 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
180}
diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c
new file mode 100644
index 000000000000..a8d7ace9f958
--- /dev/null
+++ b/arch/arm/mach-tegra/board-seaboard.c
@@ -0,0 +1,250 @@
1/*
2 * Copyright (c) 2010, 2011 NVIDIA Corporation.
3 * Copyright (C) 2010, 2011 Google, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * 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/i2c.h>
22#include <linux/i2c-tegra.h>
23#include <linux/delay.h>
24#include <linux/input.h>
25#include <linux/io.h>
26#include <linux/gpio.h>
27#include <linux/gpio_keys.h>
28
29#include <mach/iomap.h>
30#include <mach/irqs.h>
31#include <mach/sdhci.h>
32
33#include <asm/mach-types.h>
34#include <asm/mach/arch.h>
35
36#include "board.h"
37#include "board-seaboard.h"
38#include "clock.h"
39#include "devices.h"
40#include "gpio-names.h"
41
42static struct plat_serial8250_port debug_uart_platform_data[] = {
43 {
44 /* Memory and IRQ filled in before registration */
45 .flags = UPF_BOOT_AUTOCONF,
46 .iotype = UPIO_MEM,
47 .regshift = 2,
48 .uartclk = 216000000,
49 }, {
50 .flags = 0,
51 }
52};
53
54static struct platform_device debug_uart = {
55 .name = "serial8250",
56 .id = PLAT8250_DEV_PLATFORM,
57 .dev = {
58 .platform_data = debug_uart_platform_data,
59 },
60};
61
62static __initdata struct tegra_clk_init_table seaboard_clk_init_table[] = {
63 /* name parent rate enabled */
64 { "uartb", "pll_p", 216000000, true},
65 { "uartd", "pll_p", 216000000, true},
66 { NULL, NULL, 0, 0},
67};
68
69static struct tegra_i2c_platform_data seaboard_i2c1_platform_data = {
70 .bus_clk_rate = 400000.
71};
72
73static struct tegra_i2c_platform_data seaboard_i2c2_platform_data = {
74 .bus_clk_rate = 400000,
75};
76
77static struct tegra_i2c_platform_data seaboard_i2c3_platform_data = {
78 .bus_clk_rate = 400000,
79};
80
81static struct tegra_i2c_platform_data seaboard_dvc_platform_data = {
82 .bus_clk_rate = 400000,
83};
84
85static struct gpio_keys_button seaboard_gpio_keys_buttons[] = {
86 {
87 .code = SW_LID,
88 .gpio = TEGRA_GPIO_LIDSWITCH,
89 .active_low = 0,
90 .desc = "Lid",
91 .type = EV_SW,
92 .wakeup = 1,
93 .debounce_interval = 1,
94 },
95 {
96 .code = KEY_POWER,
97 .gpio = TEGRA_GPIO_POWERKEY,
98 .active_low = 1,
99 .desc = "Power",
100 .type = EV_KEY,
101 .wakeup = 1,
102 },
103};
104
105static struct gpio_keys_platform_data seaboard_gpio_keys = {
106 .buttons = seaboard_gpio_keys_buttons,
107 .nbuttons = ARRAY_SIZE(seaboard_gpio_keys_buttons),
108};
109
110static struct platform_device seaboard_gpio_keys_device = {
111 .name = "gpio-keys",
112 .id = -1,
113 .dev = {
114 .platform_data = &seaboard_gpio_keys,
115 }
116};
117
118static struct tegra_sdhci_platform_data sdhci_pdata1 = {
119 .cd_gpio = -1,
120 .wp_gpio = -1,
121 .power_gpio = -1,
122};
123
124static struct tegra_sdhci_platform_data sdhci_pdata3 = {
125 .cd_gpio = TEGRA_GPIO_SD2_CD,
126 .wp_gpio = TEGRA_GPIO_SD2_WP,
127 .power_gpio = TEGRA_GPIO_SD2_POWER,
128};
129
130static struct tegra_sdhci_platform_data sdhci_pdata4 = {
131 .cd_gpio = -1,
132 .wp_gpio = -1,
133 .power_gpio = -1,
134 .is_8bit = 1,
135};
136
137static struct platform_device *seaboard_devices[] __initdata = {
138 &debug_uart,
139 &tegra_pmu_device,
140 &tegra_sdhci_device1,
141 &tegra_sdhci_device3,
142 &tegra_sdhci_device4,
143 &seaboard_gpio_keys_device,
144};
145
146static struct i2c_board_info __initdata isl29018_device = {
147 I2C_BOARD_INFO("isl29018", 0x44),
148 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_ISL29018_IRQ),
149};
150
151static struct i2c_board_info __initdata adt7461_device = {
152 I2C_BOARD_INFO("adt7461", 0x4c),
153};
154
155static void __init seaboard_i2c_init(void)
156{
157 gpio_request(TEGRA_GPIO_ISL29018_IRQ, "isl29018");
158 gpio_direction_input(TEGRA_GPIO_ISL29018_IRQ);
159
160 i2c_register_board_info(0, &isl29018_device, 1);
161
162 i2c_register_board_info(4, &adt7461_device, 1);
163
164 tegra_i2c_device1.dev.platform_data = &seaboard_i2c1_platform_data;
165 tegra_i2c_device2.dev.platform_data = &seaboard_i2c2_platform_data;
166 tegra_i2c_device3.dev.platform_data = &seaboard_i2c3_platform_data;
167 tegra_i2c_device4.dev.platform_data = &seaboard_dvc_platform_data;
168
169 platform_device_register(&tegra_i2c_device1);
170 platform_device_register(&tegra_i2c_device2);
171 platform_device_register(&tegra_i2c_device3);
172 platform_device_register(&tegra_i2c_device4);
173}
174
175static void __init seaboard_common_init(void)
176{
177 seaboard_pinmux_init();
178
179 tegra_clk_init_from_table(seaboard_clk_init_table);
180
181 tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
182 tegra_sdhci_device3.dev.platform_data = &sdhci_pdata3;
183 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
184
185 platform_add_devices(seaboard_devices, ARRAY_SIZE(seaboard_devices));
186}
187
188static void __init tegra_seaboard_init(void)
189{
190 /* Seaboard uses UARTD for the debug port. */
191 debug_uart_platform_data[0].membase = IO_ADDRESS(TEGRA_UARTD_BASE);
192 debug_uart_platform_data[0].mapbase = TEGRA_UARTD_BASE;
193 debug_uart_platform_data[0].irq = INT_UARTD;
194
195 seaboard_common_init();
196
197 seaboard_i2c_init();
198}
199
200static void __init tegra_kaen_init(void)
201{
202 /* Kaen uses UARTB for the debug port. */
203 debug_uart_platform_data[0].membase = IO_ADDRESS(TEGRA_UARTB_BASE);
204 debug_uart_platform_data[0].mapbase = TEGRA_UARTB_BASE;
205 debug_uart_platform_data[0].irq = INT_UARTB;
206
207 seaboard_common_init();
208
209 seaboard_i2c_init();
210}
211
212static void __init tegra_wario_init(void)
213{
214 /* Wario uses UARTB for the debug port. */
215 debug_uart_platform_data[0].membase = IO_ADDRESS(TEGRA_UARTB_BASE);
216 debug_uart_platform_data[0].mapbase = TEGRA_UARTB_BASE;
217 debug_uart_platform_data[0].irq = INT_UARTB;
218
219 seaboard_common_init();
220
221 seaboard_i2c_init();
222}
223
224
225MACHINE_START(SEABOARD, "seaboard")
226 .boot_params = 0x00000100,
227 .map_io = tegra_map_common_io,
228 .init_early = tegra_init_early,
229 .init_irq = tegra_init_irq,
230 .timer = &tegra_timer,
231 .init_machine = tegra_seaboard_init,
232MACHINE_END
233
234MACHINE_START(KAEN, "kaen")
235 .boot_params = 0x00000100,
236 .map_io = tegra_map_common_io,
237 .init_early = tegra_init_early,
238 .init_irq = tegra_init_irq,
239 .timer = &tegra_timer,
240 .init_machine = tegra_kaen_init,
241MACHINE_END
242
243MACHINE_START(WARIO, "wario")
244 .boot_params = 0x00000100,
245 .map_io = tegra_map_common_io,
246 .init_early = tegra_init_early,
247 .init_irq = tegra_init_irq,
248 .timer = &tegra_timer,
249 .init_machine = tegra_wario_init,
250MACHINE_END
diff --git a/arch/arm/mach-tegra/board-seaboard.h b/arch/arm/mach-tegra/board-seaboard.h
new file mode 100644
index 000000000000..d8415e1a8434
--- /dev/null
+++ b/arch/arm/mach-tegra/board-seaboard.h
@@ -0,0 +1,41 @@
1/*
2 * arch/arm/mach-tegra/board-seaboard.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_SEABOARD_H
18#define _MACH_TEGRA_BOARD_SEABOARD_H
19
20#define TEGRA_GPIO_SD2_CD TEGRA_GPIO_PI5
21#define TEGRA_GPIO_SD2_WP TEGRA_GPIO_PH1
22#define TEGRA_GPIO_SD2_POWER TEGRA_GPIO_PI6
23#define TEGRA_GPIO_LIDSWITCH TEGRA_GPIO_PC7
24#define TEGRA_GPIO_USB1 TEGRA_GPIO_PD0
25#define TEGRA_GPIO_POWERKEY TEGRA_GPIO_PV2
26#define TEGRA_GPIO_BACKLIGHT TEGRA_GPIO_PD4
27#define TEGRA_GPIO_LVDS_SHUTDOWN TEGRA_GPIO_PB2
28#define TEGRA_GPIO_BACKLIGHT_PWM TEGRA_GPIO_PU5
29#define TEGRA_GPIO_BACKLIGHT_VDD TEGRA_GPIO_PW0
30#define TEGRA_GPIO_EN_VDD_PNL TEGRA_GPIO_PC6
31#define TEGRA_GPIO_MAGNETOMETER TEGRA_GPIO_PN5
32#define TEGRA_GPIO_ISL29018_IRQ TEGRA_GPIO_PZ2
33#define TEGRA_GPIO_AC_ONLINE TEGRA_GPIO_PV3
34
35#define TPS_GPIO_BASE TEGRA_NR_GPIOS
36
37#define TPS_GPIO_WWAN_PWR (TPS_GPIO_BASE + 2)
38
39void seaboard_pinmux_init(void);
40
41#endif
diff --git a/arch/arm/mach-tegra/board-trimslice-pinmux.c b/arch/arm/mach-tegra/board-trimslice-pinmux.c
new file mode 100644
index 000000000000..13534fa08abf
--- /dev/null
+++ b/arch/arm/mach-tegra/board-trimslice-pinmux.c
@@ -0,0 +1,154 @@
1/*
2 * arch/arm/mach-tegra/board-trimslice-pinmux.c
3 *
4 * Copyright (C) 2011 CompuLab, Ltd.
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
20#include <mach/pinmux.h>
21#include <mach/gpio.h>
22
23#include "gpio-names.h"
24#include "board-trimslice.h"
25
26static __initdata struct tegra_pingroup_config trimslice_pinmux[] = {
27 {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
28 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
29 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
30 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
31 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
32 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_OSC, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
33 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
34 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
35 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
36 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
37 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
38 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
39 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
40 {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
41 {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
42 {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
43 {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
44 {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
45 {TEGRA_PINGROUP_DTE, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
46 {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
47 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
48 {TEGRA_PINGROUP_GMB, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
49 {TEGRA_PINGROUP_GMC, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
50 {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
51 {TEGRA_PINGROUP_GME, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
52 {TEGRA_PINGROUP_GPU, TEGRA_MUX_UARTA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
53 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
54 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
55 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
56 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
57 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
58 {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
59 {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
60 {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
61 {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
62 {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
63 {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
64 {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
65 {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
66 {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
67 {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
68 {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
69 {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
70 {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
71 {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
72 {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
73 {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
74 {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
75 {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
76 {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
77 {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
78 {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
79 {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
80 {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
81 {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
82 {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
83 {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
84 {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
85 {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
86 {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
87 {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
88 {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
89 {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
90 {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
91 {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
92 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
93 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
94 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
95 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
96 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
97 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
98 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
99 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
100 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
101 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
102 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
103 {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
104 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
105 {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
106 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
107 {TEGRA_PINGROUP_PTA, TEGRA_MUX_RSVD3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
108 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
109 {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
110 {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
111 {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
112 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
113 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
114 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
115 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
116 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
117 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
118 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
119 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
120 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
121 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
122 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
123 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
124 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
125 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
126 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
127 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
128 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
129 {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
130 {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
131 {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
132 {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
133 {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
134 {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
135 {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
136 {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
137 {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
138 {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
139 {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
140 {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
141 {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
142 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
143};
144
145static struct tegra_gpio_table gpio_table[] = {
146 { .gpio = TRIMSLICE_GPIO_SD4_CD, .enable = true }, /* mmc4 cd */
147 { .gpio = TRIMSLICE_GPIO_SD4_WP, .enable = true }, /* mmc4 wp */
148};
149
150void __init trimslice_pinmux_init(void)
151{
152 tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux));
153 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
154}
diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c
new file mode 100644
index 000000000000..cda4cfd78e84
--- /dev/null
+++ b/arch/arm/mach-tegra/board-trimslice.c
@@ -0,0 +1,125 @@
1/*
2 * arch/arm/mach-tegra/board-trimslice.c
3 *
4 * Copyright (C) 2011 CompuLab, Ltd.
5 * Author: Mike Rapoport <mike@compulab.co.il>
6 *
7 * Based on board-harmony.c
8 * Copyright (C) 2010 Google, Inc.
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/init.h>
23#include <linux/platform_device.h>
24#include <linux/serial_8250.h>
25#include <linux/io.h>
26
27#include <asm/mach-types.h>
28#include <asm/mach/arch.h>
29#include <asm/setup.h>
30
31#include <mach/iomap.h>
32#include <mach/sdhci.h>
33
34#include "board.h"
35#include "clock.h"
36#include "devices.h"
37#include "gpio-names.h"
38
39#include "board-trimslice.h"
40
41static struct plat_serial8250_port debug_uart_platform_data[] = {
42 {
43 .membase = IO_ADDRESS(TEGRA_UARTA_BASE),
44 .mapbase = TEGRA_UARTA_BASE,
45 .irq = INT_UARTA,
46 .flags = UPF_BOOT_AUTOCONF,
47 .iotype = UPIO_MEM,
48 .regshift = 2,
49 .uartclk = 216000000,
50 }, {
51 .flags = 0
52 }
53};
54
55static struct platform_device debug_uart = {
56 .name = "serial8250",
57 .id = PLAT8250_DEV_PLATFORM,
58 .dev = {
59 .platform_data = debug_uart_platform_data,
60 },
61};
62static struct tegra_sdhci_platform_data sdhci_pdata1 = {
63 .cd_gpio = -1,
64 .wp_gpio = -1,
65 .power_gpio = -1,
66};
67
68static struct tegra_sdhci_platform_data sdhci_pdata4 = {
69 .cd_gpio = TRIMSLICE_GPIO_SD4_CD,
70 .wp_gpio = TRIMSLICE_GPIO_SD4_WP,
71 .power_gpio = -1,
72};
73
74static struct platform_device *trimslice_devices[] __initdata = {
75 &debug_uart,
76 &tegra_sdhci_device1,
77 &tegra_sdhci_device4,
78};
79
80static void __init tegra_trimslice_fixup(struct machine_desc *desc,
81 struct tag *tags, char **cmdline, struct meminfo *mi)
82{
83 mi->nr_banks = 2;
84 mi->bank[0].start = PHYS_OFFSET;
85 mi->bank[0].size = 448 * SZ_1M;
86 mi->bank[1].start = SZ_512M;
87 mi->bank[1].size = SZ_512M;
88}
89
90static __initdata struct tegra_clk_init_table trimslice_clk_init_table[] = {
91 /* name parent rate enabled */
92 { "uarta", "pll_p", 216000000, true },
93 { NULL, NULL, 0, 0},
94};
95
96static int __init tegra_trimslice_pci_init(void)
97{
98 if (!machine_is_trimslice())
99 return 0;
100
101 return tegra_pcie_init(true, true);
102}
103subsys_initcall(tegra_trimslice_pci_init);
104
105static void __init tegra_trimslice_init(void)
106{
107 tegra_clk_init_from_table(trimslice_clk_init_table);
108
109 trimslice_pinmux_init();
110
111 tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
112 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
113
114 platform_add_devices(trimslice_devices, ARRAY_SIZE(trimslice_devices));
115}
116
117MACHINE_START(TRIMSLICE, "trimslice")
118 .boot_params = 0x00000100,
119 .fixup = tegra_trimslice_fixup,
120 .map_io = tegra_map_common_io,
121 .init_early = tegra_init_early,
122 .init_irq = tegra_init_irq,
123 .timer = &tegra_timer,
124 .init_machine = tegra_trimslice_init,
125MACHINE_END
diff --git a/arch/arm/mach-tegra/board-trimslice.h b/arch/arm/mach-tegra/board-trimslice.h
new file mode 100644
index 000000000000..e8ef6291c6f1
--- /dev/null
+++ b/arch/arm/mach-tegra/board-trimslice.h
@@ -0,0 +1,25 @@
1/*
2 * arch/arm/mach-tegra/board-trimslice.h
3 *
4 * Copyright (C) 2011 CompuLab, Ltd.
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_TRIMSLICE_H
18#define _MACH_TEGRA_BOARD_TRIMSLICE_H
19
20#define TRIMSLICE_GPIO_SD4_CD TEGRA_GPIO_PP1 /* mmc4 cd */
21#define TRIMSLICE_GPIO_SD4_WP TEGRA_GPIO_PP2 /* mmc4 wp */
22
23void trimslice_pinmux_init(void);
24
25#endif
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index 0de565ca37c5..1d14df7eb7de 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -23,7 +23,9 @@
23 23
24#include <linux/types.h> 24#include <linux/types.h>
25 25
26void __init tegra_common_init(void); 26void tegra_assert_system_reset(char mode, const char *cmd);
27
28void __init tegra_init_early(void);
27void __init tegra_map_common_io(void); 29void __init tegra_map_common_io(void);
28void __init tegra_init_irq(void); 30void __init tegra_init_irq(void);
29void __init tegra_init_clock(void); 31void __init tegra_init_clock(void);
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index 77948e0f4909..e028320ab423 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -18,238 +18,177 @@
18 18
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/clk.h> 20#include <linux/clk.h>
21#include <linux/list.h> 21#include <linux/clkdev.h>
22#include <linux/debugfs.h>
23#include <linux/delay.h>
22#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/list.h>
23#include <linux/module.h> 26#include <linux/module.h>
24#include <linux/debugfs.h> 27#include <linux/sched.h>
25#include <linux/slab.h>
26#include <linux/seq_file.h> 28#include <linux/seq_file.h>
27#include <linux/regulator/consumer.h> 29#include <linux/slab.h>
28#include <linux/clkdev.h> 30
31#include <mach/clk.h>
29 32
30#include "clock.h"
31#include "board.h" 33#include "board.h"
32#include "fuse.h" 34#include "clock.h"
33 35
36/*
37 * Locking:
38 *
39 * Each struct clk has a spinlock.
40 *
41 * To avoid AB-BA locking problems, locks must always be traversed from child
42 * clock to parent clock. For example, when enabling a clock, the clock's lock
43 * is taken, and then clk_enable is called on the parent, which take's the
44 * parent clock's lock. There is one exceptions to this ordering: When dumping
45 * the clock tree through debugfs. In this case, clk_lock_all is called,
46 * which attemps to iterate through the entire list of clocks and take every
47 * clock lock. If any call to spin_trylock fails, all locked clocks are
48 * unlocked, and the process is retried. When all the locks are held,
49 * the only clock operation that can be called is clk_get_rate_all_locked.
50 *
51 * Within a single clock, no clock operation can call another clock operation
52 * on itself, except for clk_get_rate_locked and clk_set_rate_locked. Any
53 * clock operation can call any other clock operation on any of it's possible
54 * parents.
55 *
56 * An additional mutex, clock_list_lock, is used to protect the list of all
57 * clocks.
58 *
59 * The clock operations must lock internally to protect against
60 * read-modify-write on registers that are shared by multiple clocks
61 */
62static DEFINE_MUTEX(clock_list_lock);
34static LIST_HEAD(clocks); 63static LIST_HEAD(clocks);
35 64
36static DEFINE_SPINLOCK(clock_lock);
37static DEFINE_MUTEX(dvfs_lock);
38
39static int clk_is_dvfs(struct clk *c)
40{
41 return (c->dvfs != NULL);
42};
43
44static int dvfs_set_rate(struct dvfs *d, unsigned long rate)
45{
46 struct dvfs_table *t;
47
48 if (d->table == NULL)
49 return -ENODEV;
50
51 for (t = d->table; t->rate != 0; t++) {
52 if (rate <= t->rate) {
53 if (!d->reg)
54 return 0;
55
56 return regulator_set_voltage(d->reg,
57 t->millivolts * 1000,
58 d->max_millivolts * 1000);
59 }
60 }
61
62 return -EINVAL;
63}
64
65static void dvfs_init(struct clk *c)
66{
67 int process_id;
68 int i;
69 struct dvfs_table *table;
70
71 process_id = c->dvfs->cpu ? tegra_core_process_id() :
72 tegra_cpu_process_id();
73
74 for (i = 0; i < c->dvfs->process_id_table_length; i++)
75 if (process_id == c->dvfs->process_id_table[i].process_id)
76 c->dvfs->table = c->dvfs->process_id_table[i].table;
77
78 if (c->dvfs->table == NULL) {
79 pr_err("Failed to find dvfs table for clock %s process %d\n",
80 c->name, process_id);
81 return;
82 }
83
84 c->dvfs->max_millivolts = 0;
85 for (table = c->dvfs->table; table->rate != 0; table++)
86 if (c->dvfs->max_millivolts < table->millivolts)
87 c->dvfs->max_millivolts = table->millivolts;
88
89 c->dvfs->reg = regulator_get(NULL, c->dvfs->reg_id);
90
91 if (IS_ERR(c->dvfs->reg)) {
92 pr_err("Failed to get regulator %s for clock %s\n",
93 c->dvfs->reg_id, c->name);
94 c->dvfs->reg = NULL;
95 return;
96 }
97
98 if (c->refcnt > 0)
99 dvfs_set_rate(c->dvfs, c->rate);
100}
101
102struct clk *tegra_get_clock_by_name(const char *name) 65struct clk *tegra_get_clock_by_name(const char *name)
103{ 66{
104 struct clk *c; 67 struct clk *c;
105 struct clk *ret = NULL; 68 struct clk *ret = NULL;
106 unsigned long flags; 69 mutex_lock(&clock_list_lock);
107 spin_lock_irqsave(&clock_lock, flags);
108 list_for_each_entry(c, &clocks, node) { 70 list_for_each_entry(c, &clocks, node) {
109 if (strcmp(c->name, name) == 0) { 71 if (strcmp(c->name, name) == 0) {
110 ret = c; 72 ret = c;
111 break; 73 break;
112 } 74 }
113 } 75 }
114 spin_unlock_irqrestore(&clock_lock, flags); 76 mutex_unlock(&clock_list_lock);
115 return ret; 77 return ret;
116} 78}
117 79
118static void clk_recalculate_rate(struct clk *c) 80/* Must be called with c->spinlock held */
81static unsigned long clk_predict_rate_from_parent(struct clk *c, struct clk *p)
119{ 82{
120 u64 rate; 83 u64 rate;
121 84
122 if (!c->parent) 85 rate = clk_get_rate(p);
123 return;
124
125 rate = c->parent->rate;
126 86
127 if (c->mul != 0 && c->div != 0) { 87 if (c->mul != 0 && c->div != 0) {
128 rate = rate * c->mul; 88 rate *= c->mul;
89 rate += c->div - 1; /* round up */
129 do_div(rate, c->div); 90 do_div(rate, c->div);
130 } 91 }
131 92
132 if (rate > c->max_rate) 93 return rate;
133 pr_warn("clocks: Set clock %s to rate %llu, max is %lu\n",
134 c->name, rate, c->max_rate);
135
136 c->rate = rate;
137} 94}
138 95
139int clk_reparent(struct clk *c, struct clk *parent) 96/* Must be called with c->spinlock held */
97unsigned long clk_get_rate_locked(struct clk *c)
140{ 98{
141 pr_debug("%s: %s\n", __func__, c->name); 99 unsigned long rate;
142 c->parent = parent;
143 list_del(&c->sibling);
144 list_add_tail(&c->sibling, &parent->children);
145 return 0;
146}
147 100
148static void propagate_rate(struct clk *c) 101 if (c->parent)
149{ 102 rate = clk_predict_rate_from_parent(c, c->parent);
150 struct clk *clkp; 103 else
151 pr_debug("%s: %s\n", __func__, c->name); 104 rate = c->rate;
152 list_for_each_entry(clkp, &c->children, sibling) { 105
153 pr_debug(" %s\n", clkp->name); 106 return rate;
154 clk_recalculate_rate(clkp);
155 propagate_rate(clkp);
156 }
157} 107}
158 108
159void clk_init(struct clk *c) 109unsigned long clk_get_rate(struct clk *c)
160{ 110{
161 unsigned long flags; 111 unsigned long flags;
112 unsigned long rate;
113
114 spin_lock_irqsave(&c->spinlock, flags);
162 115
163 pr_debug("%s: %s\n", __func__, c->name); 116 rate = clk_get_rate_locked(c);
164 117
165 spin_lock_irqsave(&clock_lock, flags); 118 spin_unlock_irqrestore(&c->spinlock, flags);
166 119
167 INIT_LIST_HEAD(&c->children); 120 return rate;
168 INIT_LIST_HEAD(&c->sibling); 121}
122EXPORT_SYMBOL(clk_get_rate);
123
124int clk_reparent(struct clk *c, struct clk *parent)
125{
126 c->parent = parent;
127 return 0;
128}
129
130void clk_init(struct clk *c)
131{
132 spin_lock_init(&c->spinlock);
169 133
170 if (c->ops && c->ops->init) 134 if (c->ops && c->ops->init)
171 c->ops->init(c); 135 c->ops->init(c);
172 136
173 clk_recalculate_rate(c); 137 if (!c->ops || !c->ops->enable) {
138 c->refcnt++;
139 c->set = true;
140 if (c->parent)
141 c->state = c->parent->state;
142 else
143 c->state = ON;
144 }
174 145
146 mutex_lock(&clock_list_lock);
175 list_add(&c->node, &clocks); 147 list_add(&c->node, &clocks);
176 148 mutex_unlock(&clock_list_lock);
177 if (c->parent)
178 list_add_tail(&c->sibling, &c->parent->children);
179
180 spin_unlock_irqrestore(&clock_lock, flags);
181} 149}
182 150
183int clk_enable_locked(struct clk *c) 151int clk_enable(struct clk *c)
184{ 152{
185 int ret; 153 int ret = 0;
186 pr_debug("%s: %s\n", __func__, c->name); 154 unsigned long flags;
155
156 spin_lock_irqsave(&c->spinlock, flags);
157
187 if (c->refcnt == 0) { 158 if (c->refcnt == 0) {
188 if (c->parent) { 159 if (c->parent) {
189 ret = clk_enable_locked(c->parent); 160 ret = clk_enable(c->parent);
190 if (ret) 161 if (ret)
191 return ret; 162 goto out;
192 } 163 }
193 164
194 if (c->ops && c->ops->enable) { 165 if (c->ops && c->ops->enable) {
195 ret = c->ops->enable(c); 166 ret = c->ops->enable(c);
196 if (ret) { 167 if (ret) {
197 if (c->parent) 168 if (c->parent)
198 clk_disable_locked(c->parent); 169 clk_disable(c->parent);
199 return ret; 170 goto out;
200 } 171 }
201 c->state = ON; 172 c->state = ON;
202#ifdef CONFIG_DEBUG_FS 173 c->set = true;
203 c->set = 1;
204#endif
205 } 174 }
206 } 175 }
207 c->refcnt++; 176 c->refcnt++;
208 177out:
209 return 0; 178 spin_unlock_irqrestore(&c->spinlock, flags);
210}
211
212int clk_enable_cansleep(struct clk *c)
213{
214 int ret;
215 unsigned long flags;
216
217 mutex_lock(&dvfs_lock);
218
219 if (clk_is_dvfs(c) && c->refcnt > 0)
220 dvfs_set_rate(c->dvfs, c->rate);
221
222 spin_lock_irqsave(&clock_lock, flags);
223 ret = clk_enable_locked(c);
224 spin_unlock_irqrestore(&clock_lock, flags);
225
226 mutex_unlock(&dvfs_lock);
227
228 return ret; 179 return ret;
229} 180}
230EXPORT_SYMBOL(clk_enable_cansleep); 181EXPORT_SYMBOL(clk_enable);
231 182
232int clk_enable(struct clk *c) 183void clk_disable(struct clk *c)
233{ 184{
234 int ret;
235 unsigned long flags; 185 unsigned long flags;
236 186
237 if (clk_is_dvfs(c)) 187 spin_lock_irqsave(&c->spinlock, flags);
238 BUG();
239
240 spin_lock_irqsave(&clock_lock, flags);
241 ret = clk_enable_locked(c);
242 spin_unlock_irqrestore(&clock_lock, flags);
243
244 return ret;
245}
246EXPORT_SYMBOL(clk_enable);
247 188
248void clk_disable_locked(struct clk *c)
249{
250 pr_debug("%s: %s\n", __func__, c->name);
251 if (c->refcnt == 0) { 189 if (c->refcnt == 0) {
252 WARN(1, "Attempting to disable clock %s with refcnt 0", c->name); 190 WARN(1, "Attempting to disable clock %s with refcnt 0", c->name);
191 spin_unlock_irqrestore(&c->spinlock, flags);
253 return; 192 return;
254 } 193 }
255 if (c->refcnt == 1) { 194 if (c->refcnt == 1) {
@@ -257,71 +196,39 @@ void clk_disable_locked(struct clk *c)
257 c->ops->disable(c); 196 c->ops->disable(c);
258 197
259 if (c->parent) 198 if (c->parent)
260 clk_disable_locked(c->parent); 199 clk_disable(c->parent);
261 200
262 c->state = OFF; 201 c->state = OFF;
263 } 202 }
264 c->refcnt--; 203 c->refcnt--;
265}
266
267void clk_disable_cansleep(struct clk *c)
268{
269 unsigned long flags;
270
271 mutex_lock(&dvfs_lock);
272
273 spin_lock_irqsave(&clock_lock, flags);
274 clk_disable_locked(c);
275 spin_unlock_irqrestore(&clock_lock, flags);
276 204
277 if (clk_is_dvfs(c) && c->refcnt == 0) 205 spin_unlock_irqrestore(&c->spinlock, flags);
278 dvfs_set_rate(c->dvfs, c->rate);
279
280 mutex_unlock(&dvfs_lock);
281}
282EXPORT_SYMBOL(clk_disable_cansleep);
283
284void clk_disable(struct clk *c)
285{
286 unsigned long flags;
287
288 if (clk_is_dvfs(c))
289 BUG();
290
291 spin_lock_irqsave(&clock_lock, flags);
292 clk_disable_locked(c);
293 spin_unlock_irqrestore(&clock_lock, flags);
294} 206}
295EXPORT_SYMBOL(clk_disable); 207EXPORT_SYMBOL(clk_disable);
296 208
297int clk_set_parent_locked(struct clk *c, struct clk *parent) 209int clk_set_parent(struct clk *c, struct clk *parent)
298{ 210{
299 int ret; 211 int ret;
212 unsigned long flags;
213 unsigned long new_rate;
214 unsigned long old_rate;
300 215
301 pr_debug("%s: %s\n", __func__, c->name); 216 spin_lock_irqsave(&c->spinlock, flags);
302 217
303 if (!c->ops || !c->ops->set_parent) 218 if (!c->ops || !c->ops->set_parent) {
304 return -ENOSYS; 219 ret = -ENOSYS;
220 goto out;
221 }
305 222
306 ret = c->ops->set_parent(c, parent); 223 new_rate = clk_predict_rate_from_parent(c, parent);
224 old_rate = clk_get_rate_locked(c);
307 225
226 ret = c->ops->set_parent(c, parent);
308 if (ret) 227 if (ret)
309 return ret; 228 goto out;
310
311 clk_recalculate_rate(c);
312
313 propagate_rate(c);
314
315 return 0;
316}
317 229
318int clk_set_parent(struct clk *c, struct clk *parent) 230out:
319{ 231 spin_unlock_irqrestore(&c->spinlock, flags);
320 int ret;
321 unsigned long flags;
322 spin_lock_irqsave(&clock_lock, flags);
323 ret = clk_set_parent_locked(c, parent);
324 spin_unlock_irqrestore(&clock_lock, flags);
325 return ret; 232 return ret;
326} 233}
327EXPORT_SYMBOL(clk_set_parent); 234EXPORT_SYMBOL(clk_set_parent);
@@ -334,100 +241,86 @@ EXPORT_SYMBOL(clk_get_parent);
334 241
335int clk_set_rate_locked(struct clk *c, unsigned long rate) 242int clk_set_rate_locked(struct clk *c, unsigned long rate)
336{ 243{
337 int ret; 244 long new_rate;
338
339 if (rate > c->max_rate)
340 rate = c->max_rate;
341 245
342 if (!c->ops || !c->ops->set_rate) 246 if (!c->ops || !c->ops->set_rate)
343 return -ENOSYS; 247 return -ENOSYS;
344 248
345 ret = c->ops->set_rate(c, rate); 249 if (rate > c->max_rate)
346 250 rate = c->max_rate;
347 if (ret)
348 return ret;
349
350 clk_recalculate_rate(c);
351
352 propagate_rate(c);
353
354 return 0;
355}
356
357int clk_set_rate_cansleep(struct clk *c, unsigned long rate)
358{
359 int ret = 0;
360 unsigned long flags;
361
362 pr_debug("%s: %s\n", __func__, c->name);
363
364 mutex_lock(&dvfs_lock);
365
366 if (rate > c->rate)
367 ret = dvfs_set_rate(c->dvfs, rate);
368 if (ret)
369 goto out;
370 251
371 spin_lock_irqsave(&clock_lock, flags); 252 if (c->ops && c->ops->round_rate) {
372 ret = clk_set_rate_locked(c, rate); 253 new_rate = c->ops->round_rate(c, rate);
373 spin_unlock_irqrestore(&clock_lock, flags);
374 254
375 if (ret) 255 if (new_rate < 0)
376 goto out; 256 return new_rate;
377 257
378 ret = dvfs_set_rate(c->dvfs, rate); 258 rate = new_rate;
259 }
379 260
380out: 261 return c->ops->set_rate(c, rate);
381 mutex_unlock(&dvfs_lock);
382 return ret;
383} 262}
384EXPORT_SYMBOL(clk_set_rate_cansleep);
385 263
386int clk_set_rate(struct clk *c, unsigned long rate) 264int clk_set_rate(struct clk *c, unsigned long rate)
387{ 265{
388 int ret = 0; 266 int ret;
389 unsigned long flags; 267 unsigned long flags;
390 268
391 pr_debug("%s: %s\n", __func__, c->name); 269 spin_lock_irqsave(&c->spinlock, flags);
392
393 if (clk_is_dvfs(c))
394 BUG();
395 270
396 spin_lock_irqsave(&clock_lock, flags);
397 ret = clk_set_rate_locked(c, rate); 271 ret = clk_set_rate_locked(c, rate);
398 spin_unlock_irqrestore(&clock_lock, flags); 272
273 spin_unlock_irqrestore(&c->spinlock, flags);
399 274
400 return ret; 275 return ret;
401} 276}
402EXPORT_SYMBOL(clk_set_rate); 277EXPORT_SYMBOL(clk_set_rate);
403 278
404unsigned long clk_get_rate(struct clk *c)
405{
406 unsigned long flags;
407 unsigned long ret;
408
409 spin_lock_irqsave(&clock_lock, flags);
410 279
411 pr_debug("%s: %s\n", __func__, c->name); 280/* Must be called with clocks lock and all indvidual clock locks held */
281unsigned long clk_get_rate_all_locked(struct clk *c)
282{
283 u64 rate;
284 int mul = 1;
285 int div = 1;
286 struct clk *p = c;
287
288 while (p) {
289 c = p;
290 if (c->mul != 0 && c->div != 0) {
291 mul *= c->mul;
292 div *= c->div;
293 }
294 p = c->parent;
295 }
412 296
413 ret = c->rate; 297 rate = c->rate;
298 rate *= mul;
299 do_div(rate, div);
414 300
415 spin_unlock_irqrestore(&clock_lock, flags); 301 return rate;
416 return ret;
417} 302}
418EXPORT_SYMBOL(clk_get_rate);
419 303
420long clk_round_rate(struct clk *c, unsigned long rate) 304long clk_round_rate(struct clk *c, unsigned long rate)
421{ 305{
422 pr_debug("%s: %s\n", __func__, c->name); 306 unsigned long flags;
307 long ret;
423 308
424 if (!c->ops || !c->ops->round_rate) 309 spin_lock_irqsave(&c->spinlock, flags);
425 return -ENOSYS; 310
311 if (!c->ops || !c->ops->round_rate) {
312 ret = -ENOSYS;
313 goto out;
314 }
426 315
427 if (rate > c->max_rate) 316 if (rate > c->max_rate)
428 rate = c->max_rate; 317 rate = c->max_rate;
429 318
430 return c->ops->round_rate(c, rate); 319 ret = c->ops->round_rate(c, rate);
320
321out:
322 spin_unlock_irqrestore(&c->spinlock, flags);
323 return ret;
431} 324}
432EXPORT_SYMBOL(clk_round_rate); 325EXPORT_SYMBOL(clk_round_rate);
433 326
@@ -509,31 +402,90 @@ void __init tegra_init_clock(void)
509 tegra2_init_clocks(); 402 tegra2_init_clocks();
510} 403}
511 404
512int __init tegra_init_dvfs(void) 405/*
406 * The SDMMC controllers have extra bits in the clock source register that
407 * adjust the delay between the clock and data to compenstate for delays
408 * on the PCB.
409 */
410void tegra_sdmmc_tap_delay(struct clk *c, int delay)
513{ 411{
514 struct clk *c, *safe; 412 unsigned long flags;
413
414 spin_lock_irqsave(&c->spinlock, flags);
415 tegra2_sdmmc_tap_delay(c, delay);
416 spin_unlock_irqrestore(&c->spinlock, flags);
417}
515 418
516 mutex_lock(&dvfs_lock); 419#ifdef CONFIG_DEBUG_FS
517 420
518 list_for_each_entry_safe(c, safe, &clocks, node) 421static int __clk_lock_all_spinlocks(void)
519 if (c->dvfs) 422{
520 dvfs_init(c); 423 struct clk *c;
521 424
522 mutex_unlock(&dvfs_lock); 425 list_for_each_entry(c, &clocks, node)
426 if (!spin_trylock(&c->spinlock))
427 goto unlock_spinlocks;
523 428
524 return 0; 429 return 0;
430
431unlock_spinlocks:
432 list_for_each_entry_continue_reverse(c, &clocks, node)
433 spin_unlock(&c->spinlock);
434
435 return -EAGAIN;
525} 436}
526 437
527late_initcall(tegra_init_dvfs); 438static void __clk_unlock_all_spinlocks(void)
439{
440 struct clk *c;
441
442 list_for_each_entry_reverse(c, &clocks, node)
443 spin_unlock(&c->spinlock);
444}
445
446/*
447 * This function retries until it can take all locks, and may take
448 * an arbitrarily long time to complete.
449 * Must be called with irqs enabled, returns with irqs disabled
450 * Must be called with clock_list_lock held
451 */
452static void clk_lock_all(void)
453{
454 int ret;
455retry:
456 local_irq_disable();
457
458 ret = __clk_lock_all_spinlocks();
459 if (ret)
460 goto failed_spinlocks;
461
462 /* All locks taken successfully, return */
463 return;
464
465failed_spinlocks:
466 local_irq_enable();
467 yield();
468 goto retry;
469}
470
471/*
472 * Unlocks all clocks after a clk_lock_all
473 * Must be called with irqs disabled, returns with irqs enabled
474 * Must be called with clock_list_lock held
475 */
476static void clk_unlock_all(void)
477{
478 __clk_unlock_all_spinlocks();
479
480 local_irq_enable();
481}
528 482
529#ifdef CONFIG_DEBUG_FS
530static struct dentry *clk_debugfs_root; 483static struct dentry *clk_debugfs_root;
531 484
532 485
533static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level) 486static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
534{ 487{
535 struct clk *child; 488 struct clk *child;
536 struct clk *safe;
537 const char *state = "uninit"; 489 const char *state = "uninit";
538 char div[8] = {0}; 490 char div[8] = {0};
539 491
@@ -564,8 +516,12 @@ static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
564 c->rate > c->max_rate ? '!' : ' ', 516 c->rate > c->max_rate ? '!' : ' ',
565 !c->set ? '*' : ' ', 517 !c->set ? '*' : ' ',
566 30 - level * 3, c->name, 518 30 - level * 3, c->name,
567 state, c->refcnt, div, c->rate); 519 state, c->refcnt, div, clk_get_rate_all_locked(c));
568 list_for_each_entry_safe(child, safe, &c->children, sibling) { 520
521 list_for_each_entry(child, &clocks, node) {
522 if (child->parent != c)
523 continue;
524
569 clock_tree_show_one(s, child, level + 1); 525 clock_tree_show_one(s, child, level + 1);
570 } 526 }
571} 527}
@@ -573,14 +529,20 @@ static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
573static int clock_tree_show(struct seq_file *s, void *data) 529static int clock_tree_show(struct seq_file *s, void *data)
574{ 530{
575 struct clk *c; 531 struct clk *c;
576 unsigned long flags;
577 seq_printf(s, " clock state ref div rate\n"); 532 seq_printf(s, " clock state ref div rate\n");
578 seq_printf(s, "--------------------------------------------------------------\n"); 533 seq_printf(s, "--------------------------------------------------------------\n");
579 spin_lock_irqsave(&clock_lock, flags); 534
535 mutex_lock(&clock_list_lock);
536
537 clk_lock_all();
538
580 list_for_each_entry(c, &clocks, node) 539 list_for_each_entry(c, &clocks, node)
581 if (c->parent == NULL) 540 if (c->parent == NULL)
582 clock_tree_show_one(s, c, 0); 541 clock_tree_show_one(s, c, 0);
583 spin_unlock_irqrestore(&clock_lock, flags); 542
543 clk_unlock_all();
544
545 mutex_unlock(&clock_list_lock);
584 return 0; 546 return 0;
585} 547}
586 548
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index 083a4cfc6cf0..688316abc64e 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -20,8 +20,9 @@
20#ifndef __MACH_TEGRA_CLOCK_H 20#ifndef __MACH_TEGRA_CLOCK_H
21#define __MACH_TEGRA_CLOCK_H 21#define __MACH_TEGRA_CLOCK_H
22 22
23#include <linux/list.h>
24#include <linux/clkdev.h> 23#include <linux/clkdev.h>
24#include <linux/list.h>
25#include <linux/spinlock.h>
25 26
26#define DIV_BUS (1 << 0) 27#define DIV_BUS (1 << 0)
27#define DIV_U71 (1 << 1) 28#define DIV_U71 (1 << 1)
@@ -41,36 +42,13 @@
41#define ENABLE_ON_INIT (1 << 28) 42#define ENABLE_ON_INIT (1 << 28)
42 43
43struct clk; 44struct clk;
44struct regulator;
45
46struct dvfs_table {
47 unsigned long rate;
48 int millivolts;
49};
50
51struct dvfs_process_id_table {
52 int process_id;
53 struct dvfs_table *table;
54};
55
56
57struct dvfs {
58 struct regulator *reg;
59 struct dvfs_table *table;
60 int max_millivolts;
61
62 int process_id_table_length;
63 const char *reg_id;
64 bool cpu;
65 struct dvfs_process_id_table process_id_table[];
66};
67 45
68struct clk_mux_sel { 46struct clk_mux_sel {
69 struct clk *input; 47 struct clk *input;
70 u32 value; 48 u32 value;
71}; 49};
72 50
73struct clk_pll_table { 51struct clk_pll_freq_table {
74 unsigned long input_rate; 52 unsigned long input_rate;
75 unsigned long output_rate; 53 unsigned long output_rate;
76 u16 n; 54 u16 n;
@@ -86,6 +64,7 @@ struct clk_ops {
86 int (*set_parent)(struct clk *, struct clk *); 64 int (*set_parent)(struct clk *, struct clk *);
87 int (*set_rate)(struct clk *, unsigned long); 65 int (*set_rate)(struct clk *, unsigned long);
88 long (*round_rate)(struct clk *, unsigned long); 66 long (*round_rate)(struct clk *, unsigned long);
67 void (*reset)(struct clk *, bool);
89}; 68};
90 69
91enum clk_state { 70enum clk_state {
@@ -96,55 +75,64 @@ enum clk_state {
96 75
97struct clk { 76struct clk {
98 /* node for master clocks list */ 77 /* node for master clocks list */
99 struct list_head node; 78 struct list_head node; /* node for list of all clocks */
100 struct list_head children; /* list of children */ 79 struct clk_lookup lookup;
101 struct list_head sibling; /* node for children */ 80
102#ifdef CONFIG_DEBUG_FS
103 struct dentry *dent;
104 struct dentry *parent_dent;
105#endif
106 struct clk_ops *ops;
107 struct clk *parent;
108 struct clk_lookup lookup;
109 unsigned long rate;
110 unsigned long max_rate;
111 u32 flags;
112 u32 refcnt;
113 const char *name;
114 u32 reg;
115 u32 reg_shift;
116 unsigned int clk_num;
117 enum clk_state state;
118#ifdef CONFIG_DEBUG_FS 81#ifdef CONFIG_DEBUG_FS
119 bool set; 82 struct dentry *dent;
120#endif 83#endif
84 bool set;
85 struct clk_ops *ops;
86 unsigned long rate;
87 unsigned long max_rate;
88 unsigned long min_rate;
89 u32 flags;
90 const char *name;
91
92 u32 refcnt;
93 enum clk_state state;
94 struct clk *parent;
95 u32 div;
96 u32 mul;
121 97
122 /* PLL */
123 unsigned long input_min;
124 unsigned long input_max;
125 unsigned long cf_min;
126 unsigned long cf_max;
127 unsigned long vco_min;
128 unsigned long vco_max;
129 const struct clk_pll_table *pll_table;
130
131 /* DIV */
132 u32 div;
133 u32 mul;
134
135 /* MUX */
136 const struct clk_mux_sel *inputs; 98 const struct clk_mux_sel *inputs;
137 u32 sel; 99 u32 reg;
138 u32 reg_mask; 100 u32 reg_shift;
139
140 /* Virtual cpu clock */
141 struct clk *main;
142 struct clk *backup;
143 101
144 struct dvfs *dvfs; 102 struct list_head shared_bus_list;
103
104 union {
105 struct {
106 unsigned int clk_num;
107 } periph;
108 struct {
109 unsigned long input_min;
110 unsigned long input_max;
111 unsigned long cf_min;
112 unsigned long cf_max;
113 unsigned long vco_min;
114 unsigned long vco_max;
115 const struct clk_pll_freq_table *freq_table;
116 int lock_delay;
117 } pll;
118 struct {
119 u32 sel;
120 u32 reg_mask;
121 } mux;
122 struct {
123 struct clk *main;
124 struct clk *backup;
125 } cpu;
126 struct {
127 struct list_head node;
128 bool enabled;
129 unsigned long rate;
130 } shared_bus_user;
131 } u;
132
133 spinlock_t spinlock;
145}; 134};
146 135
147
148struct clk_duplicate { 136struct clk_duplicate {
149 const char *name; 137 const char *name;
150 struct clk_lookup lookup; 138 struct clk_lookup lookup;
@@ -163,11 +151,10 @@ void tegra2_periph_reset_assert(struct clk *c);
163void clk_init(struct clk *clk); 151void clk_init(struct clk *clk);
164struct clk *tegra_get_clock_by_name(const char *name); 152struct clk *tegra_get_clock_by_name(const char *name);
165unsigned long clk_measure_input_freq(void); 153unsigned long clk_measure_input_freq(void);
166void clk_disable_locked(struct clk *c);
167int clk_enable_locked(struct clk *c);
168int clk_set_parent_locked(struct clk *c, struct clk *parent);
169int clk_set_rate_locked(struct clk *c, unsigned long rate);
170int clk_reparent(struct clk *c, struct clk *parent); 154int clk_reparent(struct clk *c, struct clk *parent);
171void tegra_clk_init_from_table(struct tegra_clk_init_table *table); 155void tegra_clk_init_from_table(struct tegra_clk_init_table *table);
156unsigned long clk_get_rate_locked(struct clk *c);
157int clk_set_rate_locked(struct clk *c, unsigned long rate);
158void tegra2_sdmmc_tap_delay(struct clk *c, int delay);
172 159
173#endif 160#endif
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 7c91e2b9d643..d5e3f89b05af 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -25,12 +25,25 @@
25#include <asm/hardware/cache-l2x0.h> 25#include <asm/hardware/cache-l2x0.h>
26 26
27#include <mach/iomap.h> 27#include <mach/iomap.h>
28#include <mach/dma.h> 28#include <mach/system.h>
29 29
30#include "board.h" 30#include "board.h"
31#include "clock.h" 31#include "clock.h"
32#include "fuse.h" 32#include "fuse.h"
33 33
34void (*arch_reset)(char mode, const char *cmd) = tegra_assert_system_reset;
35
36void tegra_assert_system_reset(char mode, const char *cmd)
37{
38 void __iomem *reset = IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x04);
39 u32 reg;
40
41 /* use *_related to avoid spinlock since caches are off */
42 reg = readl_relaxed(reset);
43 reg |= 0x04;
44 writel_relaxed(reg, reset);
45}
46
34static __initdata struct tegra_clk_init_table common_clk_init_table[] = { 47static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
35 /* name parent rate enabled */ 48 /* name parent rate enabled */
36 { "clk_m", NULL, 0, true }, 49 { "clk_m", NULL, 0, true },
@@ -42,6 +55,9 @@ static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
42 { "sclk", "pll_p_out4", 108000000, true }, 55 { "sclk", "pll_p_out4", 108000000, true },
43 { "hclk", "sclk", 108000000, true }, 56 { "hclk", "sclk", 108000000, true },
44 { "pclk", "hclk", 54000000, true }, 57 { "pclk", "hclk", 54000000, true },
58 { "csite", NULL, 0, true },
59 { "emc", NULL, 0, true },
60 { "cpu", NULL, 0, true },
45 { NULL, NULL, 0, 0}, 61 { NULL, NULL, 0, 0},
46}; 62};
47 63
@@ -50,21 +66,18 @@ void __init tegra_init_cache(void)
50#ifdef CONFIG_CACHE_L2X0 66#ifdef CONFIG_CACHE_L2X0
51 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000; 67 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
52 68
53 writel(0x331, p + L2X0_TAG_LATENCY_CTRL); 69 writel_relaxed(0x331, p + L2X0_TAG_LATENCY_CTRL);
54 writel(0x441, p + L2X0_DATA_LATENCY_CTRL); 70 writel_relaxed(0x441, p + L2X0_DATA_LATENCY_CTRL);
55 71
56 l2x0_init(p, 0x6C080001, 0x8200c3fe); 72 l2x0_init(p, 0x6C080001, 0x8200c3fe);
57#endif 73#endif
58 74
59} 75}
60 76
61void __init tegra_common_init(void) 77void __init tegra_init_early(void)
62{ 78{
63 tegra_init_fuse(); 79 tegra_init_fuse();
64 tegra_init_clock(); 80 tegra_init_clock();
65 tegra_clk_init_from_table(common_clk_init_table); 81 tegra_clk_init_from_table(common_clk_init_table);
66 tegra_init_cache(); 82 tegra_init_cache();
67#ifdef CONFIG_TEGRA_SYSTEM_DMA
68 tegra_dma_init();
69#endif
70} 83}
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c
index fea5719c7072..0e1016a827ac 100644
--- a/arch/arm/mach-tegra/cpu-tegra.c
+++ b/arch/arm/mach-tegra/cpu-tegra.c
@@ -28,6 +28,7 @@
28#include <linux/err.h> 28#include <linux/err.h>
29#include <linux/clk.h> 29#include <linux/clk.h>
30#include <linux/io.h> 30#include <linux/io.h>
31#include <linux/suspend.h>
31 32
32#include <asm/system.h> 33#include <asm/system.h>
33 34
@@ -36,21 +37,25 @@
36 37
37/* Frequency table index must be sequential starting at 0 */ 38/* Frequency table index must be sequential starting at 0 */
38static struct cpufreq_frequency_table freq_table[] = { 39static struct cpufreq_frequency_table freq_table[] = {
39 { 0, 312000 }, 40 { 0, 216000 },
40 { 1, 456000 }, 41 { 1, 312000 },
41 { 2, 608000 }, 42 { 2, 456000 },
42 { 3, 760000 }, 43 { 3, 608000 },
43 { 4, 816000 }, 44 { 4, 760000 },
44 { 5, 912000 }, 45 { 5, 816000 },
45 { 6, 1000000 }, 46 { 6, 912000 },
46 { 7, CPUFREQ_TABLE_END }, 47 { 7, 1000000 },
48 { 8, CPUFREQ_TABLE_END },
47}; 49};
48 50
49#define NUM_CPUS 2 51#define NUM_CPUS 2
50 52
51static struct clk *cpu_clk; 53static struct clk *cpu_clk;
54static struct clk *emc_clk;
52 55
53static unsigned long target_cpu_speed[NUM_CPUS]; 56static unsigned long target_cpu_speed[NUM_CPUS];
57static DEFINE_MUTEX(tegra_cpu_lock);
58static bool is_suspended;
54 59
55int tegra_verify_speed(struct cpufreq_policy *policy) 60int tegra_verify_speed(struct cpufreq_policy *policy)
56{ 61{
@@ -68,22 +73,28 @@ unsigned int tegra_getspeed(unsigned int cpu)
68 return rate; 73 return rate;
69} 74}
70 75
71static int tegra_update_cpu_speed(void) 76static int tegra_update_cpu_speed(unsigned long rate)
72{ 77{
73 int i;
74 unsigned long rate = 0;
75 int ret = 0; 78 int ret = 0;
76 struct cpufreq_freqs freqs; 79 struct cpufreq_freqs freqs;
77 80
78 for_each_online_cpu(i)
79 rate = max(rate, target_cpu_speed[i]);
80
81 freqs.old = tegra_getspeed(0); 81 freqs.old = tegra_getspeed(0);
82 freqs.new = rate; 82 freqs.new = rate;
83 83
84 if (freqs.old == freqs.new) 84 if (freqs.old == freqs.new)
85 return ret; 85 return ret;
86 86
87 /*
88 * Vote on memory bus frequency based on cpu frequency
89 * This sets the minimum frequency, display or avp may request higher
90 */
91 if (rate >= 816000)
92 clk_set_rate(emc_clk, 600000000); /* cpu 816 MHz, emc max */
93 else if (rate >= 456000)
94 clk_set_rate(emc_clk, 300000000); /* cpu 456 MHz, emc 150Mhz */
95 else
96 clk_set_rate(emc_clk, 100000000); /* emc 50Mhz */
97
87 for_each_online_cpu(freqs.cpu) 98 for_each_online_cpu(freqs.cpu)
88 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 99 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
89 100
@@ -92,7 +103,7 @@ static int tegra_update_cpu_speed(void)
92 freqs.old, freqs.new); 103 freqs.old, freqs.new);
93#endif 104#endif
94 105
95 ret = clk_set_rate_cansleep(cpu_clk, freqs.new * 1000); 106 ret = clk_set_rate(cpu_clk, freqs.new * 1000);
96 if (ret) { 107 if (ret) {
97 pr_err("cpu-tegra: Failed to set cpu frequency to %d kHz\n", 108 pr_err("cpu-tegra: Failed to set cpu frequency to %d kHz\n",
98 freqs.new); 109 freqs.new);
@@ -105,12 +116,30 @@ static int tegra_update_cpu_speed(void)
105 return 0; 116 return 0;
106} 117}
107 118
119static unsigned long tegra_cpu_highest_speed(void)
120{
121 unsigned long rate = 0;
122 int i;
123
124 for_each_online_cpu(i)
125 rate = max(rate, target_cpu_speed[i]);
126 return rate;
127}
128
108static int tegra_target(struct cpufreq_policy *policy, 129static int tegra_target(struct cpufreq_policy *policy,
109 unsigned int target_freq, 130 unsigned int target_freq,
110 unsigned int relation) 131 unsigned int relation)
111{ 132{
112 int idx; 133 int idx;
113 unsigned int freq; 134 unsigned int freq;
135 int ret = 0;
136
137 mutex_lock(&tegra_cpu_lock);
138
139 if (is_suspended) {
140 ret = -EBUSY;
141 goto out;
142 }
114 143
115 cpufreq_frequency_table_target(policy, freq_table, target_freq, 144 cpufreq_frequency_table_target(policy, freq_table, target_freq,
116 relation, &idx); 145 relation, &idx);
@@ -119,9 +148,34 @@ static int tegra_target(struct cpufreq_policy *policy,
119 148
120 target_cpu_speed[policy->cpu] = freq; 149 target_cpu_speed[policy->cpu] = freq;
121 150
122 return tegra_update_cpu_speed(); 151 ret = tegra_update_cpu_speed(tegra_cpu_highest_speed());
152
153out:
154 mutex_unlock(&tegra_cpu_lock);
155 return ret;
123} 156}
124 157
158static int tegra_pm_notify(struct notifier_block *nb, unsigned long event,
159 void *dummy)
160{
161 mutex_lock(&tegra_cpu_lock);
162 if (event == PM_SUSPEND_PREPARE) {
163 is_suspended = true;
164 pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n",
165 freq_table[0].frequency);
166 tegra_update_cpu_speed(freq_table[0].frequency);
167 } else if (event == PM_POST_SUSPEND) {
168 is_suspended = false;
169 }
170 mutex_unlock(&tegra_cpu_lock);
171
172 return NOTIFY_OK;
173}
174
175static struct notifier_block tegra_cpu_pm_notifier = {
176 .notifier_call = tegra_pm_notify,
177};
178
125static int tegra_cpu_init(struct cpufreq_policy *policy) 179static int tegra_cpu_init(struct cpufreq_policy *policy)
126{ 180{
127 if (policy->cpu >= NUM_CPUS) 181 if (policy->cpu >= NUM_CPUS)
@@ -131,6 +185,15 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
131 if (IS_ERR(cpu_clk)) 185 if (IS_ERR(cpu_clk))
132 return PTR_ERR(cpu_clk); 186 return PTR_ERR(cpu_clk);
133 187
188 emc_clk = clk_get_sys("cpu", "emc");
189 if (IS_ERR(emc_clk)) {
190 clk_put(cpu_clk);
191 return PTR_ERR(emc_clk);
192 }
193
194 clk_enable(emc_clk);
195 clk_enable(cpu_clk);
196
134 cpufreq_frequency_table_cpuinfo(policy, freq_table); 197 cpufreq_frequency_table_cpuinfo(policy, freq_table);
135 cpufreq_frequency_table_get_attr(freq_table, policy->cpu); 198 cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
136 policy->cur = tegra_getspeed(policy->cpu); 199 policy->cur = tegra_getspeed(policy->cpu);
@@ -142,12 +205,17 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
142 policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; 205 policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
143 cpumask_copy(policy->related_cpus, cpu_possible_mask); 206 cpumask_copy(policy->related_cpus, cpu_possible_mask);
144 207
208 if (policy->cpu == 0)
209 register_pm_notifier(&tegra_cpu_pm_notifier);
210
145 return 0; 211 return 0;
146} 212}
147 213
148static int tegra_cpu_exit(struct cpufreq_policy *policy) 214static int tegra_cpu_exit(struct cpufreq_policy *policy)
149{ 215{
150 cpufreq_frequency_table_cpuinfo(policy, freq_table); 216 cpufreq_frequency_table_cpuinfo(policy, freq_table);
217 clk_disable(emc_clk);
218 clk_put(emc_clk);
151 clk_put(cpu_clk); 219 clk_put(cpu_clk);
152 return 0; 220 return 0;
153} 221}
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
new file mode 100644
index 000000000000..1528f9daef1f
--- /dev/null
+++ b/arch/arm/mach-tegra/devices.c
@@ -0,0 +1,575 @@
1/*
2 * Copyright (C) 2010,2011 Google, Inc.
3 *
4 * Author:
5 * Colin Cross <ccross@android.com>
6 * Erik Gilling <ccross@android.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
20#include <linux/resource.h>
21#include <linux/platform_device.h>
22#include <linux/dma-mapping.h>
23#include <linux/fsl_devices.h>
24#include <linux/serial_8250.h>
25#include <asm/pmu.h>
26#include <mach/irqs.h>
27#include <mach/iomap.h>
28#include <mach/dma.h>
29
30static struct resource i2c_resource1[] = {
31 [0] = {
32 .start = INT_I2C,
33 .end = INT_I2C,
34 .flags = IORESOURCE_IRQ,
35 },
36 [1] = {
37 .start = TEGRA_I2C_BASE,
38 .end = TEGRA_I2C_BASE + TEGRA_I2C_SIZE-1,
39 .flags = IORESOURCE_MEM,
40 },
41};
42
43static struct resource i2c_resource2[] = {
44 [0] = {
45 .start = INT_I2C2,
46 .end = INT_I2C2,
47 .flags = IORESOURCE_IRQ,
48 },
49 [1] = {
50 .start = TEGRA_I2C2_BASE,
51 .end = TEGRA_I2C2_BASE + TEGRA_I2C2_SIZE-1,
52 .flags = IORESOURCE_MEM,
53 },
54};
55
56static struct resource i2c_resource3[] = {
57 [0] = {
58 .start = INT_I2C3,
59 .end = INT_I2C3,
60 .flags = IORESOURCE_IRQ,
61 },
62 [1] = {
63 .start = TEGRA_I2C3_BASE,
64 .end = TEGRA_I2C3_BASE + TEGRA_I2C3_SIZE-1,
65 .flags = IORESOURCE_MEM,
66 },
67};
68
69static struct resource i2c_resource4[] = {
70 [0] = {
71 .start = INT_DVC,
72 .end = INT_DVC,
73 .flags = IORESOURCE_IRQ,
74 },
75 [1] = {
76 .start = TEGRA_DVC_BASE,
77 .end = TEGRA_DVC_BASE + TEGRA_DVC_SIZE-1,
78 .flags = IORESOURCE_MEM,
79 },
80};
81
82struct platform_device tegra_i2c_device1 = {
83 .name = "tegra-i2c",
84 .id = 0,
85 .resource = i2c_resource1,
86 .num_resources = ARRAY_SIZE(i2c_resource1),
87 .dev = {
88 .platform_data = 0,
89 },
90};
91
92struct platform_device tegra_i2c_device2 = {
93 .name = "tegra-i2c",
94 .id = 1,
95 .resource = i2c_resource2,
96 .num_resources = ARRAY_SIZE(i2c_resource2),
97 .dev = {
98 .platform_data = 0,
99 },
100};
101
102struct platform_device tegra_i2c_device3 = {
103 .name = "tegra-i2c",
104 .id = 2,
105 .resource = i2c_resource3,
106 .num_resources = ARRAY_SIZE(i2c_resource3),
107 .dev = {
108 .platform_data = 0,
109 },
110};
111
112struct platform_device tegra_i2c_device4 = {
113 .name = "tegra-i2c",
114 .id = 3,
115 .resource = i2c_resource4,
116 .num_resources = ARRAY_SIZE(i2c_resource4),
117 .dev = {
118 .platform_data = 0,
119 },
120};
121
122static struct resource spi_resource1[] = {
123 [0] = {
124 .start = INT_S_LINK1,
125 .end = INT_S_LINK1,
126 .flags = IORESOURCE_IRQ,
127 },
128 [1] = {
129 .start = TEGRA_SPI1_BASE,
130 .end = TEGRA_SPI1_BASE + TEGRA_SPI1_SIZE-1,
131 .flags = IORESOURCE_MEM,
132 },
133};
134
135static struct resource spi_resource2[] = {
136 [0] = {
137 .start = INT_SPI_2,
138 .end = INT_SPI_2,
139 .flags = IORESOURCE_IRQ,
140 },
141 [1] = {
142 .start = TEGRA_SPI2_BASE,
143 .end = TEGRA_SPI2_BASE + TEGRA_SPI2_SIZE-1,
144 .flags = IORESOURCE_MEM,
145 },
146};
147
148static struct resource spi_resource3[] = {
149 [0] = {
150 .start = INT_SPI_3,
151 .end = INT_SPI_3,
152 .flags = IORESOURCE_IRQ,
153 },
154 [1] = {
155 .start = TEGRA_SPI3_BASE,
156 .end = TEGRA_SPI3_BASE + TEGRA_SPI3_SIZE-1,
157 .flags = IORESOURCE_MEM,
158 },
159};
160
161static struct resource spi_resource4[] = {
162 [0] = {
163 .start = INT_SPI_4,
164 .end = INT_SPI_4,
165 .flags = IORESOURCE_IRQ,
166 },
167 [1] = {
168 .start = TEGRA_SPI4_BASE,
169 .end = TEGRA_SPI4_BASE + TEGRA_SPI4_SIZE-1,
170 .flags = IORESOURCE_MEM,
171 },
172};
173
174struct platform_device tegra_spi_device1 = {
175 .name = "spi_tegra",
176 .id = 0,
177 .resource = spi_resource1,
178 .num_resources = ARRAY_SIZE(spi_resource1),
179 .dev = {
180 .coherent_dma_mask = 0xffffffff,
181 },
182};
183
184struct platform_device tegra_spi_device2 = {
185 .name = "spi_tegra",
186 .id = 1,
187 .resource = spi_resource2,
188 .num_resources = ARRAY_SIZE(spi_resource2),
189 .dev = {
190 .coherent_dma_mask = 0xffffffff,
191 },
192};
193
194struct platform_device tegra_spi_device3 = {
195 .name = "spi_tegra",
196 .id = 2,
197 .resource = spi_resource3,
198 .num_resources = ARRAY_SIZE(spi_resource3),
199 .dev = {
200 .coherent_dma_mask = 0xffffffff,
201 },
202};
203
204struct platform_device tegra_spi_device4 = {
205 .name = "spi_tegra",
206 .id = 3,
207 .resource = spi_resource4,
208 .num_resources = ARRAY_SIZE(spi_resource4),
209 .dev = {
210 .coherent_dma_mask = 0xffffffff,
211 },
212};
213
214
215static struct resource sdhci_resource1[] = {
216 [0] = {
217 .start = INT_SDMMC1,
218 .end = INT_SDMMC1,
219 .flags = IORESOURCE_IRQ,
220 },
221 [1] = {
222 .start = TEGRA_SDMMC1_BASE,
223 .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
224 .flags = IORESOURCE_MEM,
225 },
226};
227
228static struct resource sdhci_resource2[] = {
229 [0] = {
230 .start = INT_SDMMC2,
231 .end = INT_SDMMC2,
232 .flags = IORESOURCE_IRQ,
233 },
234 [1] = {
235 .start = TEGRA_SDMMC2_BASE,
236 .end = TEGRA_SDMMC2_BASE + TEGRA_SDMMC2_SIZE-1,
237 .flags = IORESOURCE_MEM,
238 },
239};
240
241static struct resource sdhci_resource3[] = {
242 [0] = {
243 .start = INT_SDMMC3,
244 .end = INT_SDMMC3,
245 .flags = IORESOURCE_IRQ,
246 },
247 [1] = {
248 .start = TEGRA_SDMMC3_BASE,
249 .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
250 .flags = IORESOURCE_MEM,
251 },
252};
253
254static struct resource sdhci_resource4[] = {
255 [0] = {
256 .start = INT_SDMMC4,
257 .end = INT_SDMMC4,
258 .flags = IORESOURCE_IRQ,
259 },
260 [1] = {
261 .start = TEGRA_SDMMC4_BASE,
262 .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
263 .flags = IORESOURCE_MEM,
264 },
265};
266
267/* board files should fill in platform_data register the devices themselvs.
268 * See board-harmony.c for an example
269 */
270struct platform_device tegra_sdhci_device1 = {
271 .name = "sdhci-tegra",
272 .id = 0,
273 .resource = sdhci_resource1,
274 .num_resources = ARRAY_SIZE(sdhci_resource1),
275};
276
277struct platform_device tegra_sdhci_device2 = {
278 .name = "sdhci-tegra",
279 .id = 1,
280 .resource = sdhci_resource2,
281 .num_resources = ARRAY_SIZE(sdhci_resource2),
282};
283
284struct platform_device tegra_sdhci_device3 = {
285 .name = "sdhci-tegra",
286 .id = 2,
287 .resource = sdhci_resource3,
288 .num_resources = ARRAY_SIZE(sdhci_resource3),
289};
290
291struct platform_device tegra_sdhci_device4 = {
292 .name = "sdhci-tegra",
293 .id = 3,
294 .resource = sdhci_resource4,
295 .num_resources = ARRAY_SIZE(sdhci_resource4),
296};
297
298static struct resource tegra_usb1_resources[] = {
299 [0] = {
300 .start = TEGRA_USB_BASE,
301 .end = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1,
302 .flags = IORESOURCE_MEM,
303 },
304 [1] = {
305 .start = INT_USB,
306 .end = INT_USB,
307 .flags = IORESOURCE_IRQ,
308 },
309};
310
311static struct resource tegra_usb2_resources[] = {
312 [0] = {
313 .start = TEGRA_USB2_BASE,
314 .end = TEGRA_USB2_BASE + TEGRA_USB2_SIZE - 1,
315 .flags = IORESOURCE_MEM,
316 },
317 [1] = {
318 .start = INT_USB2,
319 .end = INT_USB2,
320 .flags = IORESOURCE_IRQ,
321 },
322};
323
324static struct resource tegra_usb3_resources[] = {
325 [0] = {
326 .start = TEGRA_USB3_BASE,
327 .end = TEGRA_USB3_BASE + TEGRA_USB3_SIZE - 1,
328 .flags = IORESOURCE_MEM,
329 },
330 [1] = {
331 .start = INT_USB3,
332 .end = INT_USB3,
333 .flags = IORESOURCE_IRQ,
334 },
335};
336
337static u64 tegra_ehci_dmamask = DMA_BIT_MASK(32);
338
339struct platform_device tegra_ehci1_device = {
340 .name = "tegra-ehci",
341 .id = 0,
342 .dev = {
343 .dma_mask = &tegra_ehci_dmamask,
344 .coherent_dma_mask = DMA_BIT_MASK(32),
345 },
346 .resource = tegra_usb1_resources,
347 .num_resources = ARRAY_SIZE(tegra_usb1_resources),
348};
349
350struct platform_device tegra_ehci2_device = {
351 .name = "tegra-ehci",
352 .id = 1,
353 .dev = {
354 .dma_mask = &tegra_ehci_dmamask,
355 .coherent_dma_mask = DMA_BIT_MASK(32),
356 },
357 .resource = tegra_usb2_resources,
358 .num_resources = ARRAY_SIZE(tegra_usb2_resources),
359};
360
361struct platform_device tegra_ehci3_device = {
362 .name = "tegra-ehci",
363 .id = 2,
364 .dev = {
365 .dma_mask = &tegra_ehci_dmamask,
366 .coherent_dma_mask = DMA_BIT_MASK(32),
367 },
368 .resource = tegra_usb3_resources,
369 .num_resources = ARRAY_SIZE(tegra_usb3_resources),
370};
371
372static struct resource tegra_pmu_resources[] = {
373 [0] = {
374 .start = INT_CPU0_PMU_INTR,
375 .end = INT_CPU0_PMU_INTR,
376 .flags = IORESOURCE_IRQ,
377 },
378 [1] = {
379 .start = INT_CPU1_PMU_INTR,
380 .end = INT_CPU1_PMU_INTR,
381 .flags = IORESOURCE_IRQ,
382 },
383};
384
385struct platform_device tegra_pmu_device = {
386 .name = "arm-pmu",
387 .id = ARM_PMU_DEVICE_CPU,
388 .num_resources = ARRAY_SIZE(tegra_pmu_resources),
389 .resource = tegra_pmu_resources,
390};
391
392static struct resource tegra_uarta_resources[] = {
393 [0] = {
394 .start = TEGRA_UARTA_BASE,
395 .end = TEGRA_UARTA_BASE + TEGRA_UARTA_SIZE - 1,
396 .flags = IORESOURCE_MEM,
397 },
398 [1] = {
399 .start = INT_UARTA,
400 .end = INT_UARTA,
401 .flags = IORESOURCE_IRQ,
402 },
403};
404
405static struct resource tegra_uartb_resources[] = {
406 [0] = {
407 .start = TEGRA_UARTB_BASE,
408 .end = TEGRA_UARTB_BASE + TEGRA_UARTB_SIZE - 1,
409 .flags = IORESOURCE_MEM,
410 },
411 [1] = {
412 .start = INT_UARTB,
413 .end = INT_UARTB,
414 .flags = IORESOURCE_IRQ,
415 },
416};
417
418static struct resource tegra_uartc_resources[] = {
419 [0] = {
420 .start = TEGRA_UARTC_BASE,
421 .end = TEGRA_UARTC_BASE + TEGRA_UARTC_SIZE - 1,
422 .flags = IORESOURCE_MEM,
423 },
424 [1] = {
425 .start = INT_UARTC,
426 .end = INT_UARTC,
427 .flags = IORESOURCE_IRQ,
428 },
429};
430
431static struct resource tegra_uartd_resources[] = {
432 [0] = {
433 .start = TEGRA_UARTD_BASE,
434 .end = TEGRA_UARTD_BASE + TEGRA_UARTD_SIZE - 1,
435 .flags = IORESOURCE_MEM,
436 },
437 [1] = {
438 .start = INT_UARTD,
439 .end = INT_UARTD,
440 .flags = IORESOURCE_IRQ,
441 },
442};
443
444static struct resource tegra_uarte_resources[] = {
445 [0] = {
446 .start = TEGRA_UARTE_BASE,
447 .end = TEGRA_UARTE_BASE + TEGRA_UARTE_SIZE - 1,
448 .flags = IORESOURCE_MEM,
449 },
450 [1] = {
451 .start = INT_UARTE,
452 .end = INT_UARTE,
453 .flags = IORESOURCE_IRQ,
454 },
455};
456
457struct platform_device tegra_uarta_device = {
458 .name = "tegra_uart",
459 .id = 0,
460 .num_resources = ARRAY_SIZE(tegra_uarta_resources),
461 .resource = tegra_uarta_resources,
462 .dev = {
463 .coherent_dma_mask = DMA_BIT_MASK(32),
464 },
465};
466
467struct platform_device tegra_uartb_device = {
468 .name = "tegra_uart",
469 .id = 1,
470 .num_resources = ARRAY_SIZE(tegra_uartb_resources),
471 .resource = tegra_uartb_resources,
472 .dev = {
473 .coherent_dma_mask = DMA_BIT_MASK(32),
474 },
475};
476
477struct platform_device tegra_uartc_device = {
478 .name = "tegra_uart",
479 .id = 2,
480 .num_resources = ARRAY_SIZE(tegra_uartc_resources),
481 .resource = tegra_uartc_resources,
482 .dev = {
483 .coherent_dma_mask = DMA_BIT_MASK(32),
484 },
485};
486
487struct platform_device tegra_uartd_device = {
488 .name = "tegra_uart",
489 .id = 3,
490 .num_resources = ARRAY_SIZE(tegra_uartd_resources),
491 .resource = tegra_uartd_resources,
492 .dev = {
493 .coherent_dma_mask = DMA_BIT_MASK(32),
494 },
495};
496
497struct platform_device tegra_uarte_device = {
498 .name = "tegra_uart",
499 .id = 4,
500 .num_resources = ARRAY_SIZE(tegra_uarte_resources),
501 .resource = tegra_uarte_resources,
502 .dev = {
503 .coherent_dma_mask = DMA_BIT_MASK(32),
504 },
505};
506
507static struct resource i2s_resource1[] = {
508 [0] = {
509 .start = INT_I2S1,
510 .end = INT_I2S1,
511 .flags = IORESOURCE_IRQ
512 },
513 [1] = {
514 .start = TEGRA_DMA_REQ_SEL_I2S_1,
515 .end = TEGRA_DMA_REQ_SEL_I2S_1,
516 .flags = IORESOURCE_DMA
517 },
518 [2] = {
519 .start = TEGRA_I2S1_BASE,
520 .end = TEGRA_I2S1_BASE + TEGRA_I2S1_SIZE - 1,
521 .flags = IORESOURCE_MEM
522 }
523};
524
525static struct resource i2s_resource2[] = {
526 [0] = {
527 .start = INT_I2S2,
528 .end = INT_I2S2,
529 .flags = IORESOURCE_IRQ
530 },
531 [1] = {
532 .start = TEGRA_DMA_REQ_SEL_I2S2_1,
533 .end = TEGRA_DMA_REQ_SEL_I2S2_1,
534 .flags = IORESOURCE_DMA
535 },
536 [2] = {
537 .start = TEGRA_I2S2_BASE,
538 .end = TEGRA_I2S2_BASE + TEGRA_I2S2_SIZE - 1,
539 .flags = IORESOURCE_MEM
540 }
541};
542
543struct platform_device tegra_i2s_device1 = {
544 .name = "tegra-i2s",
545 .id = 0,
546 .resource = i2s_resource1,
547 .num_resources = ARRAY_SIZE(i2s_resource1),
548};
549
550struct platform_device tegra_i2s_device2 = {
551 .name = "tegra-i2s",
552 .id = 1,
553 .resource = i2s_resource2,
554 .num_resources = ARRAY_SIZE(i2s_resource2),
555};
556
557static struct resource tegra_das_resources[] = {
558 [0] = {
559 .start = TEGRA_APB_MISC_DAS_BASE,
560 .end = TEGRA_APB_MISC_DAS_BASE + TEGRA_APB_MISC_DAS_SIZE - 1,
561 .flags = IORESOURCE_MEM,
562 },
563};
564
565struct platform_device tegra_das_device = {
566 .name = "tegra-das",
567 .id = -1,
568 .num_resources = ARRAY_SIZE(tegra_das_resources),
569 .resource = tegra_das_resources,
570};
571
572struct platform_device tegra_pcm_device = {
573 .name = "tegra-pcm-audio",
574 .id = -1,
575};
diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h
new file mode 100644
index 000000000000..4a7dc0a097d6
--- /dev/null
+++ b/arch/arm/mach-tegra/devices.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2010,2011 Google, Inc.
3 *
4 * Author:
5 * Colin Cross <ccross@android.com>
6 * Erik Gilling <ccross@android.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#ifndef __MACH_TEGRA_DEVICES_H
20#define __MACH_TEGRA_DEVICES_H
21
22#include <linux/platform_device.h>
23
24extern struct platform_device tegra_sdhci_device1;
25extern struct platform_device tegra_sdhci_device2;
26extern struct platform_device tegra_sdhci_device3;
27extern struct platform_device tegra_sdhci_device4;
28extern struct platform_device tegra_i2c_device1;
29extern struct platform_device tegra_i2c_device2;
30extern struct platform_device tegra_i2c_device3;
31extern struct platform_device tegra_i2c_device4;
32extern struct platform_device tegra_spi_device1;
33extern struct platform_device tegra_spi_device2;
34extern struct platform_device tegra_spi_device3;
35extern struct platform_device tegra_spi_device4;
36extern struct platform_device tegra_ehci1_device;
37extern struct platform_device tegra_ehci2_device;
38extern struct platform_device tegra_ehci3_device;
39extern struct platform_device tegra_uarta_device;
40extern struct platform_device tegra_uartb_device;
41extern struct platform_device tegra_uartc_device;
42extern struct platform_device tegra_uartd_device;
43extern struct platform_device tegra_uarte_device;
44extern struct platform_device tegra_pmu_device;
45extern struct platform_device tegra_i2s_device1;
46extern struct platform_device tegra_i2s_device2;
47extern struct platform_device tegra_das_device;
48extern struct platform_device tegra_pcm_device;
49
50#endif
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
index edda6ec5e925..e945ae28ee77 100644
--- a/arch/arm/mach-tegra/dma.c
+++ b/arch/arm/mach-tegra/dma.c
@@ -27,9 +27,11 @@
27#include <linux/err.h> 27#include <linux/err.h>
28#include <linux/irq.h> 28#include <linux/irq.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/clk.h>
30#include <mach/dma.h> 31#include <mach/dma.h>
31#include <mach/irqs.h> 32#include <mach/irqs.h>
32#include <mach/iomap.h> 33#include <mach/iomap.h>
34#include <mach/suspend.h>
33 35
34#define APB_DMA_GEN 0x000 36#define APB_DMA_GEN 0x000
35#define GEN_ENABLE (1<<31) 37#define GEN_ENABLE (1<<31)
@@ -120,17 +122,14 @@ struct tegra_dma_channel {
120 void __iomem *addr; 122 void __iomem *addr;
121 int mode; 123 int mode;
122 int irq; 124 int irq;
123 125 int req_transfer_count;
124 /* Register shadow */
125 u32 csr;
126 u32 ahb_seq;
127 u32 ahb_ptr;
128 u32 apb_seq;
129 u32 apb_ptr;
130}; 126};
131 127
132#define NV_DMA_MAX_CHANNELS 32 128#define NV_DMA_MAX_CHANNELS 32
133 129
130static bool tegra_dma_initialized;
131static DEFINE_MUTEX(tegra_dma_lock);
132
134static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS); 133static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS);
135static struct tegra_dma_channel dma_channels[NV_DMA_MAX_CHANNELS]; 134static struct tegra_dma_channel dma_channels[NV_DMA_MAX_CHANNELS];
136 135
@@ -138,7 +137,6 @@ static void tegra_dma_update_hw(struct tegra_dma_channel *ch,
138 struct tegra_dma_req *req); 137 struct tegra_dma_req *req);
139static void tegra_dma_update_hw_partial(struct tegra_dma_channel *ch, 138static void tegra_dma_update_hw_partial(struct tegra_dma_channel *ch,
140 struct tegra_dma_req *req); 139 struct tegra_dma_req *req);
141static void tegra_dma_init_hw(struct tegra_dma_channel *ch);
142static void tegra_dma_stop(struct tegra_dma_channel *ch); 140static void tegra_dma_stop(struct tegra_dma_channel *ch);
143 141
144void tegra_dma_flush(struct tegra_dma_channel *ch) 142void tegra_dma_flush(struct tegra_dma_channel *ch)
@@ -150,6 +148,9 @@ void tegra_dma_dequeue(struct tegra_dma_channel *ch)
150{ 148{
151 struct tegra_dma_req *req; 149 struct tegra_dma_req *req;
152 150
151 if (tegra_dma_is_empty(ch))
152 return;
153
153 req = list_entry(ch->list.next, typeof(*req), node); 154 req = list_entry(ch->list.next, typeof(*req), node);
154 155
155 tegra_dma_dequeue_req(ch, req); 156 tegra_dma_dequeue_req(ch, req);
@@ -158,10 +159,10 @@ void tegra_dma_dequeue(struct tegra_dma_channel *ch)
158 159
159void tegra_dma_stop(struct tegra_dma_channel *ch) 160void tegra_dma_stop(struct tegra_dma_channel *ch)
160{ 161{
161 unsigned int csr; 162 u32 csr;
162 unsigned int status; 163 u32 status;
163 164
164 csr = ch->csr; 165 csr = readl(ch->addr + APB_DMA_CHAN_CSR);
165 csr &= ~CSR_IE_EOC; 166 csr &= ~CSR_IE_EOC;
166 writel(csr, ch->addr + APB_DMA_CHAN_CSR); 167 writel(csr, ch->addr + APB_DMA_CHAN_CSR);
167 168
@@ -175,19 +176,16 @@ void tegra_dma_stop(struct tegra_dma_channel *ch)
175 176
176int tegra_dma_cancel(struct tegra_dma_channel *ch) 177int tegra_dma_cancel(struct tegra_dma_channel *ch)
177{ 178{
178 unsigned int csr; 179 u32 csr;
179 unsigned long irq_flags; 180 unsigned long irq_flags;
180 181
181 spin_lock_irqsave(&ch->lock, irq_flags); 182 spin_lock_irqsave(&ch->lock, irq_flags);
182 while (!list_empty(&ch->list)) 183 while (!list_empty(&ch->list))
183 list_del(ch->list.next); 184 list_del(ch->list.next);
184 185
185 csr = ch->csr; 186 csr = readl(ch->addr + APB_DMA_CHAN_CSR);
186 csr &= ~CSR_REQ_SEL_MASK; 187 csr &= ~CSR_REQ_SEL_MASK;
187 csr |= CSR_REQ_SEL_INVALID; 188 csr |= CSR_REQ_SEL_INVALID;
188
189 /* Set the enable as that is not shadowed */
190 csr |= CSR_ENB;
191 writel(csr, ch->addr + APB_DMA_CHAN_CSR); 189 writel(csr, ch->addr + APB_DMA_CHAN_CSR);
192 190
193 tegra_dma_stop(ch); 191 tegra_dma_stop(ch);
@@ -229,18 +227,15 @@ int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
229 * - Finally stop or program the DMA to the next buffer in the 227 * - Finally stop or program the DMA to the next buffer in the
230 * list. 228 * list.
231 */ 229 */
232 csr = ch->csr; 230 csr = readl(ch->addr + APB_DMA_CHAN_CSR);
233 csr &= ~CSR_REQ_SEL_MASK; 231 csr &= ~CSR_REQ_SEL_MASK;
234 csr |= CSR_REQ_SEL_INVALID; 232 csr |= CSR_REQ_SEL_INVALID;
235
236 /* Set the enable as that is not shadowed */
237 csr |= CSR_ENB;
238 writel(csr, ch->addr + APB_DMA_CHAN_CSR); 233 writel(csr, ch->addr + APB_DMA_CHAN_CSR);
239 234
240 /* Get the transfer count */ 235 /* Get the transfer count */
241 status = readl(ch->addr + APB_DMA_CHAN_STA); 236 status = readl(ch->addr + APB_DMA_CHAN_STA);
242 to_transfer = (status & STA_COUNT_MASK) >> STA_COUNT_SHIFT; 237 to_transfer = (status & STA_COUNT_MASK) >> STA_COUNT_SHIFT;
243 req_transfer_count = (ch->csr & CSR_WCOUNT_MASK) >> CSR_WCOUNT_SHIFT; 238 req_transfer_count = ch->req_transfer_count;
244 req_transfer_count += 1; 239 req_transfer_count += 1;
245 to_transfer += 1; 240 to_transfer += 1;
246 241
@@ -318,6 +313,7 @@ int tegra_dma_enqueue_req(struct tegra_dma_channel *ch,
318 struct tegra_dma_req *req) 313 struct tegra_dma_req *req)
319{ 314{
320 unsigned long irq_flags; 315 unsigned long irq_flags;
316 struct tegra_dma_req *_req;
321 int start_dma = 0; 317 int start_dma = 0;
322 318
323 if (req->size > NV_DMA_MAX_TRASFER_SIZE || 319 if (req->size > NV_DMA_MAX_TRASFER_SIZE ||
@@ -328,6 +324,13 @@ int tegra_dma_enqueue_req(struct tegra_dma_channel *ch,
328 324
329 spin_lock_irqsave(&ch->lock, irq_flags); 325 spin_lock_irqsave(&ch->lock, irq_flags);
330 326
327 list_for_each_entry(_req, &ch->list, node) {
328 if (req == _req) {
329 spin_unlock_irqrestore(&ch->lock, irq_flags);
330 return -EEXIST;
331 }
332 }
333
331 req->bytes_transferred = 0; 334 req->bytes_transferred = 0;
332 req->status = 0; 335 req->status = 0;
333 req->buffer_status = 0; 336 req->buffer_status = 0;
@@ -348,7 +351,12 @@ EXPORT_SYMBOL(tegra_dma_enqueue_req);
348struct tegra_dma_channel *tegra_dma_allocate_channel(int mode) 351struct tegra_dma_channel *tegra_dma_allocate_channel(int mode)
349{ 352{
350 int channel; 353 int channel;
351 struct tegra_dma_channel *ch; 354 struct tegra_dma_channel *ch = NULL;
355
356 if (WARN_ON(!tegra_dma_initialized))
357 return NULL;
358
359 mutex_lock(&tegra_dma_lock);
352 360
353 /* first channel is the shared channel */ 361 /* first channel is the shared channel */
354 if (mode & TEGRA_DMA_SHARED) { 362 if (mode & TEGRA_DMA_SHARED) {
@@ -357,11 +365,14 @@ struct tegra_dma_channel *tegra_dma_allocate_channel(int mode)
357 channel = find_first_zero_bit(channel_usage, 365 channel = find_first_zero_bit(channel_usage,
358 ARRAY_SIZE(dma_channels)); 366 ARRAY_SIZE(dma_channels));
359 if (channel >= ARRAY_SIZE(dma_channels)) 367 if (channel >= ARRAY_SIZE(dma_channels))
360 return NULL; 368 goto out;
361 } 369 }
362 __set_bit(channel, channel_usage); 370 __set_bit(channel, channel_usage);
363 ch = &dma_channels[channel]; 371 ch = &dma_channels[channel];
364 ch->mode = mode; 372 ch->mode = mode;
373
374out:
375 mutex_unlock(&tegra_dma_lock);
365 return ch; 376 return ch;
366} 377}
367EXPORT_SYMBOL(tegra_dma_allocate_channel); 378EXPORT_SYMBOL(tegra_dma_allocate_channel);
@@ -371,22 +382,27 @@ void tegra_dma_free_channel(struct tegra_dma_channel *ch)
371 if (ch->mode & TEGRA_DMA_SHARED) 382 if (ch->mode & TEGRA_DMA_SHARED)
372 return; 383 return;
373 tegra_dma_cancel(ch); 384 tegra_dma_cancel(ch);
385 mutex_lock(&tegra_dma_lock);
374 __clear_bit(ch->id, channel_usage); 386 __clear_bit(ch->id, channel_usage);
387 mutex_unlock(&tegra_dma_lock);
375} 388}
376EXPORT_SYMBOL(tegra_dma_free_channel); 389EXPORT_SYMBOL(tegra_dma_free_channel);
377 390
378static void tegra_dma_update_hw_partial(struct tegra_dma_channel *ch, 391static void tegra_dma_update_hw_partial(struct tegra_dma_channel *ch,
379 struct tegra_dma_req *req) 392 struct tegra_dma_req *req)
380{ 393{
394 u32 apb_ptr;
395 u32 ahb_ptr;
396
381 if (req->to_memory) { 397 if (req->to_memory) {
382 ch->apb_ptr = req->source_addr; 398 apb_ptr = req->source_addr;
383 ch->ahb_ptr = req->dest_addr; 399 ahb_ptr = req->dest_addr;
384 } else { 400 } else {
385 ch->apb_ptr = req->dest_addr; 401 apb_ptr = req->dest_addr;
386 ch->ahb_ptr = req->source_addr; 402 ahb_ptr = req->source_addr;
387 } 403 }
388 writel(ch->apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR); 404 writel(apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR);
389 writel(ch->ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR); 405 writel(ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR);
390 406
391 req->status = TEGRA_DMA_REQ_INFLIGHT; 407 req->status = TEGRA_DMA_REQ_INFLIGHT;
392 return; 408 return;
@@ -400,38 +416,39 @@ static void tegra_dma_update_hw(struct tegra_dma_channel *ch,
400 int ahb_bus_width; 416 int ahb_bus_width;
401 int apb_bus_width; 417 int apb_bus_width;
402 int index; 418 int index;
403 unsigned long csr;
404 419
420 u32 ahb_seq;
421 u32 apb_seq;
422 u32 ahb_ptr;
423 u32 apb_ptr;
424 u32 csr;
425
426 csr = CSR_IE_EOC | CSR_FLOW;
427 ahb_seq = AHB_SEQ_INTR_ENB | AHB_SEQ_BURST_1;
428 apb_seq = 0;
405 429
406 ch->csr |= CSR_FLOW; 430 csr |= req->req_sel << CSR_REQ_SEL_SHIFT;
407 ch->csr &= ~CSR_REQ_SEL_MASK;
408 ch->csr |= req->req_sel << CSR_REQ_SEL_SHIFT;
409 ch->ahb_seq &= ~AHB_SEQ_BURST_MASK;
410 ch->ahb_seq |= AHB_SEQ_BURST_1;
411 431
412 /* One shot mode is always single buffered, 432 /* One shot mode is always single buffered,
413 * continuous mode is always double buffered 433 * continuous mode is always double buffered
414 * */ 434 * */
415 if (ch->mode & TEGRA_DMA_MODE_ONESHOT) { 435 if (ch->mode & TEGRA_DMA_MODE_ONESHOT) {
416 ch->csr |= CSR_ONCE; 436 csr |= CSR_ONCE;
417 ch->ahb_seq &= ~AHB_SEQ_DBL_BUF; 437 ch->req_transfer_count = (req->size >> 2) - 1;
418 ch->csr &= ~CSR_WCOUNT_MASK;
419 ch->csr |= ((req->size>>2) - 1) << CSR_WCOUNT_SHIFT;
420 } else { 438 } else {
421 ch->csr &= ~CSR_ONCE; 439 ahb_seq |= AHB_SEQ_DBL_BUF;
422 ch->ahb_seq |= AHB_SEQ_DBL_BUF;
423 440
424 /* In double buffered mode, we set the size to half the 441 /* In double buffered mode, we set the size to half the
425 * requested size and interrupt when half the buffer 442 * requested size and interrupt when half the buffer
426 * is full */ 443 * is full */
427 ch->csr &= ~CSR_WCOUNT_MASK; 444 ch->req_transfer_count = (req->size >> 3) - 1;
428 ch->csr |= ((req->size>>3) - 1) << CSR_WCOUNT_SHIFT;
429 } 445 }
430 446
447 csr |= ch->req_transfer_count << CSR_WCOUNT_SHIFT;
448
431 if (req->to_memory) { 449 if (req->to_memory) {
432 ch->csr &= ~CSR_DIR; 450 apb_ptr = req->source_addr;
433 ch->apb_ptr = req->source_addr; 451 ahb_ptr = req->dest_addr;
434 ch->ahb_ptr = req->dest_addr;
435 452
436 apb_addr_wrap = req->source_wrap; 453 apb_addr_wrap = req->source_wrap;
437 ahb_addr_wrap = req->dest_wrap; 454 ahb_addr_wrap = req->dest_wrap;
@@ -439,9 +456,9 @@ static void tegra_dma_update_hw(struct tegra_dma_channel *ch,
439 ahb_bus_width = req->dest_bus_width; 456 ahb_bus_width = req->dest_bus_width;
440 457
441 } else { 458 } else {
442 ch->csr |= CSR_DIR; 459 csr |= CSR_DIR;
443 ch->apb_ptr = req->dest_addr; 460 apb_ptr = req->dest_addr;
444 ch->ahb_ptr = req->source_addr; 461 ahb_ptr = req->source_addr;
445 462
446 apb_addr_wrap = req->dest_wrap; 463 apb_addr_wrap = req->dest_wrap;
447 ahb_addr_wrap = req->source_wrap; 464 ahb_addr_wrap = req->source_wrap;
@@ -460,8 +477,7 @@ static void tegra_dma_update_hw(struct tegra_dma_channel *ch,
460 index++; 477 index++;
461 } while (index < ARRAY_SIZE(apb_addr_wrap_table)); 478 } while (index < ARRAY_SIZE(apb_addr_wrap_table));
462 BUG_ON(index == ARRAY_SIZE(apb_addr_wrap_table)); 479 BUG_ON(index == ARRAY_SIZE(apb_addr_wrap_table));
463 ch->apb_seq &= ~APB_SEQ_WRAP_MASK; 480 apb_seq |= index << APB_SEQ_WRAP_SHIFT;
464 ch->apb_seq |= index << APB_SEQ_WRAP_SHIFT;
465 481
466 /* set address wrap for AHB size */ 482 /* set address wrap for AHB size */
467 index = 0; 483 index = 0;
@@ -471,55 +487,42 @@ static void tegra_dma_update_hw(struct tegra_dma_channel *ch,
471 index++; 487 index++;
472 } while (index < ARRAY_SIZE(ahb_addr_wrap_table)); 488 } while (index < ARRAY_SIZE(ahb_addr_wrap_table));
473 BUG_ON(index == ARRAY_SIZE(ahb_addr_wrap_table)); 489 BUG_ON(index == ARRAY_SIZE(ahb_addr_wrap_table));
474 ch->ahb_seq &= ~AHB_SEQ_WRAP_MASK; 490 ahb_seq |= index << AHB_SEQ_WRAP_SHIFT;
475 ch->ahb_seq |= index << AHB_SEQ_WRAP_SHIFT;
476 491
477 for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) { 492 for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) {
478 if (bus_width_table[index] == ahb_bus_width) 493 if (bus_width_table[index] == ahb_bus_width)
479 break; 494 break;
480 } 495 }
481 BUG_ON(index == ARRAY_SIZE(bus_width_table)); 496 BUG_ON(index == ARRAY_SIZE(bus_width_table));
482 ch->ahb_seq &= ~AHB_SEQ_BUS_WIDTH_MASK; 497 ahb_seq |= index << AHB_SEQ_BUS_WIDTH_SHIFT;
483 ch->ahb_seq |= index << AHB_SEQ_BUS_WIDTH_SHIFT;
484 498
485 for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) { 499 for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) {
486 if (bus_width_table[index] == apb_bus_width) 500 if (bus_width_table[index] == apb_bus_width)
487 break; 501 break;
488 } 502 }
489 BUG_ON(index == ARRAY_SIZE(bus_width_table)); 503 BUG_ON(index == ARRAY_SIZE(bus_width_table));
490 ch->apb_seq &= ~APB_SEQ_BUS_WIDTH_MASK; 504 apb_seq |= index << APB_SEQ_BUS_WIDTH_SHIFT;
491 ch->apb_seq |= index << APB_SEQ_BUS_WIDTH_SHIFT;
492
493 ch->csr |= CSR_IE_EOC;
494 505
495 /* update hw registers with the shadow */ 506 writel(csr, ch->addr + APB_DMA_CHAN_CSR);
496 writel(ch->csr, ch->addr + APB_DMA_CHAN_CSR); 507 writel(apb_seq, ch->addr + APB_DMA_CHAN_APB_SEQ);
497 writel(ch->apb_seq, ch->addr + APB_DMA_CHAN_APB_SEQ); 508 writel(apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR);
498 writel(ch->apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR); 509 writel(ahb_seq, ch->addr + APB_DMA_CHAN_AHB_SEQ);
499 writel(ch->ahb_seq, ch->addr + APB_DMA_CHAN_AHB_SEQ); 510 writel(ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR);
500 writel(ch->ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR);
501 511
502 csr = ch->csr | CSR_ENB; 512 csr |= CSR_ENB;
503 writel(csr, ch->addr + APB_DMA_CHAN_CSR); 513 writel(csr, ch->addr + APB_DMA_CHAN_CSR);
504 514
505 req->status = TEGRA_DMA_REQ_INFLIGHT; 515 req->status = TEGRA_DMA_REQ_INFLIGHT;
506} 516}
507 517
508static void tegra_dma_init_hw(struct tegra_dma_channel *ch)
509{
510 /* One shot with an interrupt to CPU after transfer */
511 ch->csr = CSR_ONCE | CSR_IE_EOC;
512 ch->ahb_seq = AHB_SEQ_BUS_WIDTH_32 | AHB_SEQ_INTR_ENB;
513 ch->apb_seq = APB_SEQ_BUS_WIDTH_32 | 1 << APB_SEQ_WRAP_SHIFT;
514}
515
516static void handle_oneshot_dma(struct tegra_dma_channel *ch) 518static void handle_oneshot_dma(struct tegra_dma_channel *ch)
517{ 519{
518 struct tegra_dma_req *req; 520 struct tegra_dma_req *req;
521 unsigned long irq_flags;
519 522
520 spin_lock(&ch->lock); 523 spin_lock_irqsave(&ch->lock, irq_flags);
521 if (list_empty(&ch->list)) { 524 if (list_empty(&ch->list)) {
522 spin_unlock(&ch->lock); 525 spin_unlock_irqrestore(&ch->lock, irq_flags);
523 return; 526 return;
524 } 527 }
525 528
@@ -527,8 +530,7 @@ static void handle_oneshot_dma(struct tegra_dma_channel *ch)
527 if (req) { 530 if (req) {
528 int bytes_transferred; 531 int bytes_transferred;
529 532
530 bytes_transferred = 533 bytes_transferred = ch->req_transfer_count;
531 (ch->csr & CSR_WCOUNT_MASK) >> CSR_WCOUNT_SHIFT;
532 bytes_transferred += 1; 534 bytes_transferred += 1;
533 bytes_transferred <<= 2; 535 bytes_transferred <<= 2;
534 536
@@ -536,12 +538,12 @@ static void handle_oneshot_dma(struct tegra_dma_channel *ch)
536 req->bytes_transferred = bytes_transferred; 538 req->bytes_transferred = bytes_transferred;
537 req->status = TEGRA_DMA_REQ_SUCCESS; 539 req->status = TEGRA_DMA_REQ_SUCCESS;
538 540
539 spin_unlock(&ch->lock); 541 spin_unlock_irqrestore(&ch->lock, irq_flags);
540 /* Callback should be called without any lock */ 542 /* Callback should be called without any lock */
541 pr_debug("%s: transferred %d bytes\n", __func__, 543 pr_debug("%s: transferred %d bytes\n", __func__,
542 req->bytes_transferred); 544 req->bytes_transferred);
543 req->complete(req); 545 req->complete(req);
544 spin_lock(&ch->lock); 546 spin_lock_irqsave(&ch->lock, irq_flags);
545 } 547 }
546 548
547 if (!list_empty(&ch->list)) { 549 if (!list_empty(&ch->list)) {
@@ -551,22 +553,55 @@ static void handle_oneshot_dma(struct tegra_dma_channel *ch)
551 if (req->status != TEGRA_DMA_REQ_INFLIGHT) 553 if (req->status != TEGRA_DMA_REQ_INFLIGHT)
552 tegra_dma_update_hw(ch, req); 554 tegra_dma_update_hw(ch, req);
553 } 555 }
554 spin_unlock(&ch->lock); 556 spin_unlock_irqrestore(&ch->lock, irq_flags);
555} 557}
556 558
557static void handle_continuous_dma(struct tegra_dma_channel *ch) 559static void handle_continuous_dma(struct tegra_dma_channel *ch)
558{ 560{
559 struct tegra_dma_req *req; 561 struct tegra_dma_req *req;
562 unsigned long irq_flags;
560 563
561 spin_lock(&ch->lock); 564 spin_lock_irqsave(&ch->lock, irq_flags);
562 if (list_empty(&ch->list)) { 565 if (list_empty(&ch->list)) {
563 spin_unlock(&ch->lock); 566 spin_unlock_irqrestore(&ch->lock, irq_flags);
564 return; 567 return;
565 } 568 }
566 569
567 req = list_entry(ch->list.next, typeof(*req), node); 570 req = list_entry(ch->list.next, typeof(*req), node);
568 if (req) { 571 if (req) {
569 if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_EMPTY) { 572 if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_EMPTY) {
573 bool is_dma_ping_complete;
574 is_dma_ping_complete = (readl(ch->addr + APB_DMA_CHAN_STA)
575 & STA_PING_PONG) ? true : false;
576 if (req->to_memory)
577 is_dma_ping_complete = !is_dma_ping_complete;
578 /* Out of sync - Release current buffer */
579 if (!is_dma_ping_complete) {
580 int bytes_transferred;
581
582 bytes_transferred = ch->req_transfer_count;
583 bytes_transferred += 1;
584 bytes_transferred <<= 3;
585 req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_FULL;
586 req->bytes_transferred = bytes_transferred;
587 req->status = TEGRA_DMA_REQ_SUCCESS;
588 tegra_dma_stop(ch);
589
590 if (!list_is_last(&req->node, &ch->list)) {
591 struct tegra_dma_req *next_req;
592
593 next_req = list_entry(req->node.next,
594 typeof(*next_req), node);
595 tegra_dma_update_hw(ch, next_req);
596 }
597
598 list_del(&req->node);
599
600 /* DMA lock is NOT held when callbak is called */
601 spin_unlock_irqrestore(&ch->lock, irq_flags);
602 req->complete(req);
603 return;
604 }
570 /* Load the next request into the hardware, if available 605 /* Load the next request into the hardware, if available
571 * */ 606 * */
572 if (!list_is_last(&req->node, &ch->list)) { 607 if (!list_is_last(&req->node, &ch->list)) {
@@ -579,7 +614,7 @@ static void handle_continuous_dma(struct tegra_dma_channel *ch)
579 req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL; 614 req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL;
580 req->status = TEGRA_DMA_REQ_SUCCESS; 615 req->status = TEGRA_DMA_REQ_SUCCESS;
581 /* DMA lock is NOT held when callback is called */ 616 /* DMA lock is NOT held when callback is called */
582 spin_unlock(&ch->lock); 617 spin_unlock_irqrestore(&ch->lock, irq_flags);
583 if (likely(req->threshold)) 618 if (likely(req->threshold))
584 req->threshold(req); 619 req->threshold(req);
585 return; 620 return;
@@ -590,8 +625,7 @@ static void handle_continuous_dma(struct tegra_dma_channel *ch)
590 * the second interrupt */ 625 * the second interrupt */
591 int bytes_transferred; 626 int bytes_transferred;
592 627
593 bytes_transferred = 628 bytes_transferred = ch->req_transfer_count;
594 (ch->csr & CSR_WCOUNT_MASK) >> CSR_WCOUNT_SHIFT;
595 bytes_transferred += 1; 629 bytes_transferred += 1;
596 bytes_transferred <<= 3; 630 bytes_transferred <<= 3;
597 631
@@ -601,7 +635,7 @@ static void handle_continuous_dma(struct tegra_dma_channel *ch)
601 list_del(&req->node); 635 list_del(&req->node);
602 636
603 /* DMA lock is NOT held when callbak is called */ 637 /* DMA lock is NOT held when callbak is called */
604 spin_unlock(&ch->lock); 638 spin_unlock_irqrestore(&ch->lock, irq_flags);
605 req->complete(req); 639 req->complete(req);
606 return; 640 return;
607 641
@@ -609,7 +643,7 @@ static void handle_continuous_dma(struct tegra_dma_channel *ch)
609 BUG(); 643 BUG();
610 } 644 }
611 } 645 }
612 spin_unlock(&ch->lock); 646 spin_unlock_irqrestore(&ch->lock, irq_flags);
613} 647}
614 648
615static irqreturn_t dma_isr(int irq, void *data) 649static irqreturn_t dma_isr(int irq, void *data)
@@ -646,6 +680,21 @@ int __init tegra_dma_init(void)
646 int i; 680 int i;
647 unsigned int irq; 681 unsigned int irq;
648 void __iomem *addr; 682 void __iomem *addr;
683 struct clk *c;
684
685 bitmap_fill(channel_usage, NV_DMA_MAX_CHANNELS);
686
687 c = clk_get_sys("tegra-dma", NULL);
688 if (IS_ERR(c)) {
689 pr_err("Unable to get clock for APB DMA\n");
690 ret = PTR_ERR(c);
691 goto fail;
692 }
693 ret = clk_enable(c);
694 if (ret != 0) {
695 pr_err("Unable to enable clock for APB DMA\n");
696 goto fail;
697 }
649 698
650 addr = IO_ADDRESS(TEGRA_APB_DMA_BASE); 699 addr = IO_ADDRESS(TEGRA_APB_DMA_BASE);
651 writel(GEN_ENABLE, addr + APB_DMA_GEN); 700 writel(GEN_ENABLE, addr + APB_DMA_GEN);
@@ -653,18 +702,9 @@ int __init tegra_dma_init(void)
653 writel(0xFFFFFFFFul >> (31 - TEGRA_SYSTEM_DMA_CH_MAX), 702 writel(0xFFFFFFFFul >> (31 - TEGRA_SYSTEM_DMA_CH_MAX),
654 addr + APB_DMA_IRQ_MASK_SET); 703 addr + APB_DMA_IRQ_MASK_SET);
655 704
656 memset(channel_usage, 0, sizeof(channel_usage));
657 memset(dma_channels, 0, sizeof(dma_channels));
658
659 /* Reserve all the channels we are not supposed to touch */
660 for (i = 0; i < TEGRA_SYSTEM_DMA_CH_MIN; i++)
661 __set_bit(i, channel_usage);
662
663 for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) { 705 for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) {
664 struct tegra_dma_channel *ch = &dma_channels[i]; 706 struct tegra_dma_channel *ch = &dma_channels[i];
665 707
666 __clear_bit(i, channel_usage);
667
668 ch->id = i; 708 ch->id = i;
669 snprintf(ch->name, TEGRA_DMA_NAME_SIZE, "dma_channel_%d", i); 709 snprintf(ch->name, TEGRA_DMA_NAME_SIZE, "dma_channel_%d", i);
670 710
@@ -673,7 +713,6 @@ int __init tegra_dma_init(void)
673 713
674 spin_lock_init(&ch->lock); 714 spin_lock_init(&ch->lock);
675 INIT_LIST_HEAD(&ch->list); 715 INIT_LIST_HEAD(&ch->list);
676 tegra_dma_init_hw(ch);
677 716
678 irq = INT_APB_DMA_CH0 + i; 717 irq = INT_APB_DMA_CH0 + i;
679 ret = request_threaded_irq(irq, dma_isr, dma_thread_fn, 0, 718 ret = request_threaded_irq(irq, dma_isr, dma_thread_fn, 0,
@@ -684,14 +723,15 @@ int __init tegra_dma_init(void)
684 goto fail; 723 goto fail;
685 } 724 }
686 ch->irq = irq; 725 ch->irq = irq;
726
727 __clear_bit(i, channel_usage);
687 } 728 }
688 /* mark the shared channel allocated */ 729 /* mark the shared channel allocated */
689 __set_bit(TEGRA_SYSTEM_DMA_CH_MIN, channel_usage); 730 __set_bit(TEGRA_SYSTEM_DMA_CH_MIN, channel_usage);
690 731
691 for (i = TEGRA_SYSTEM_DMA_CH_MAX+1; i < NV_DMA_MAX_CHANNELS; i++) 732 tegra_dma_initialized = true;
692 __set_bit(i, channel_usage);
693 733
694 return ret; 734 return 0;
695fail: 735fail:
696 writel(0, addr + APB_DMA_GEN); 736 writel(0, addr + APB_DMA_GEN);
697 for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) { 737 for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) {
@@ -701,6 +741,7 @@ fail:
701 } 741 }
702 return ret; 742 return ret;
703} 743}
744postcore_initcall(tegra_dma_init);
704 745
705#ifdef CONFIG_PM 746#ifdef CONFIG_PM
706static u32 apb_dma[5*TEGRA_SYSTEM_DMA_CH_NR + 3]; 747static u32 apb_dma[5*TEGRA_SYSTEM_DMA_CH_NR + 3];
diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c
index bd066206e110..12090a2cf3e0 100644
--- a/arch/arm/mach-tegra/gpio.c
+++ b/arch/arm/mach-tegra/gpio.c
@@ -25,6 +25,7 @@
25#include <linux/gpio.h> 25#include <linux/gpio.h>
26 26
27#include <mach/iomap.h> 27#include <mach/iomap.h>
28#include <mach/suspend.h>
28 29
29#define GPIO_BANK(x) ((x) >> 5) 30#define GPIO_BANK(x) ((x) >> 5)
30#define GPIO_PORT(x) (((x) >> 3) & 0x3) 31#define GPIO_PORT(x) (((x) >> 3) & 0x3)
@@ -207,9 +208,9 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
207 spin_unlock_irqrestore(&bank->lvl_lock[port], flags); 208 spin_unlock_irqrestore(&bank->lvl_lock[port], flags);
208 209
209 if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) 210 if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
210 __set_irq_handler_unlocked(irq, handle_level_irq); 211 __set_irq_handler_unlocked(d->irq, handle_level_irq);
211 else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) 212 else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
212 __set_irq_handler_unlocked(irq, handle_edge_irq); 213 __set_irq_handler_unlocked(d->irq, handle_edge_irq);
213 214
214 return 0; 215 return 0;
215} 216}
@@ -380,6 +381,20 @@ static int __init tegra_gpio_init(void)
380 381
381postcore_initcall(tegra_gpio_init); 382postcore_initcall(tegra_gpio_init);
382 383
384void __init tegra_gpio_config(struct tegra_gpio_table *table, int num)
385{
386 int i;
387
388 for (i = 0; i < num; i++) {
389 int gpio = table[i].gpio;
390
391 if (table[i].enable)
392 tegra_gpio_enable(gpio);
393 else
394 tegra_gpio_disable(gpio);
395 }
396}
397
383#ifdef CONFIG_DEBUG_FS 398#ifdef CONFIG_DEBUG_FS
384 399
385#include <linux/debugfs.h> 400#include <linux/debugfs.h>
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h
index d7723955dac7..c8baf8f80d23 100644
--- a/arch/arm/mach-tegra/include/mach/clk.h
+++ b/arch/arm/mach-tegra/include/mach/clk.h
@@ -20,12 +20,12 @@
20#ifndef __MACH_CLK_H 20#ifndef __MACH_CLK_H
21#define __MACH_CLK_H 21#define __MACH_CLK_H
22 22
23struct clk;
24
23void tegra_periph_reset_deassert(struct clk *c); 25void tegra_periph_reset_deassert(struct clk *c);
24void tegra_periph_reset_assert(struct clk *c); 26void tegra_periph_reset_assert(struct clk *c);
25 27
26int clk_enable_cansleep(struct clk *clk); 28unsigned long clk_get_rate_all_locked(struct clk *c);
27void clk_disable_cansleep(struct clk *clk); 29void tegra_sdmmc_tap_delay(struct clk *c, int delay);
28int clk_set_rate_cansleep(struct clk *clk, unsigned long rate);
29int clk_set_parent_cansleep(struct clk *clk, struct clk *parent);
30 30
31#endif 31#endif
diff --git a/arch/arm/mach-tegra/include/mach/clkdev.h b/arch/arm/mach-tegra/include/mach/clkdev.h
index 412f5c63e65a..66cd3f4fc896 100644
--- a/arch/arm/mach-tegra/include/mach/clkdev.h
+++ b/arch/arm/mach-tegra/include/mach/clkdev.h
@@ -20,6 +20,8 @@
20#ifndef __MACH_CLKDEV_H 20#ifndef __MACH_CLKDEV_H
21#define __MACH_CLKDEV_H 21#define __MACH_CLKDEV_H
22 22
23struct clk;
24
23static inline int __clk_get(struct clk *clk) 25static inline int __clk_get(struct clk *clk)
24{ 26{
25 return 1; 27 return 1;
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
index a0e7c12868bd..e0ebe65c1657 100644
--- a/arch/arm/mach-tegra/include/mach/debug-macro.S
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -19,30 +19,15 @@
19 */ 19 */
20 20
21#include <mach/io.h> 21#include <mach/io.h>
22#include <mach/iomap.h>
22 23
23 .macro addruart, rp, rv 24 .macro addruart, rp, rv
24 ldr \rp, =IO_APB_PHYS @ physical 25 ldr \rp, =IO_APB_PHYS @ physical
25 ldr \rv, =IO_APB_VIRT @ virtual 26 ldr \rv, =IO_APB_VIRT @ virtual
26#if defined(CONFIG_TEGRA_DEBUG_UART_NONE) 27 orr \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF)
27#error "A debug UART must be selected in the kernel config to use DEBUG_LL" 28 orr \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
28#elif defined(CONFIG_TEGRA_DEBUG_UARTA) 29 orr \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF)
29 orr \rp, \rp, #0x6000 30 orr \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
30 orr \rv, \rv, #0x6000
31#elif defined(CONFIG_TEGRA_DEBUG_UARTB)
32 orr \rp, \rp, #0x6000
33 orr \rp, \rp, #0x40
34 orr \rv, \rv, #0x6000
35 orr \rv, \rv, #0x40
36#elif defined(CONFIG_TEGRA_DEBUG_UARTC)
37 orr \rp, \rp, #0x6200
38 orr \rv, \rv, #0x6200
39#elif defined(CONFIG_TEGRA_DEBUG_UARTD)
40 orr \rp, \rp, #0x6300
41 orr \rv, \rv, #0x6300
42#elif defined(CONFIG_TEGRA_DEBUG_UARTE)
43 orr \rp, \rp, #0x6400
44 orr \rv, \rv, #0x6400
45#endif
46 .endm 31 .endm
47 32
48#define UART_SHIFT 2 33#define UART_SHIFT 2
diff --git a/arch/arm/mach-tegra/include/mach/gpio.h b/arch/arm/mach-tegra/include/mach/gpio.h
index e31f486d69a2..196f114dc241 100644
--- a/arch/arm/mach-tegra/include/mach/gpio.h
+++ b/arch/arm/mach-tegra/include/mach/gpio.h
@@ -20,6 +20,7 @@
20#ifndef __MACH_TEGRA_GPIO_H 20#ifndef __MACH_TEGRA_GPIO_H
21#define __MACH_TEGRA_GPIO_H 21#define __MACH_TEGRA_GPIO_H
22 22
23#include <linux/init.h>
23#include <mach/irqs.h> 24#include <mach/irqs.h>
24 25
25#define TEGRA_NR_GPIOS INT_GPIO_NR 26#define TEGRA_NR_GPIOS INT_GPIO_NR
@@ -31,7 +32,7 @@
31#define gpio_cansleep __gpio_cansleep 32#define gpio_cansleep __gpio_cansleep
32 33
33#define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio)) 34#define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio))
34#define TEGRA_IRQ_TO_GPIO(irq) ((gpio) - INT_GPIO_BASE) 35#define TEGRA_IRQ_TO_GPIO(irq) ((irq) - INT_GPIO_BASE)
35 36
36static inline int gpio_to_irq(unsigned int gpio) 37static inline int gpio_to_irq(unsigned int gpio)
37{ 38{
@@ -47,6 +48,12 @@ static inline int irq_to_gpio(unsigned int irq)
47 return -EINVAL; 48 return -EINVAL;
48} 49}
49 50
51struct tegra_gpio_table {
52 int gpio; /* GPIO number */
53 bool enable; /* Enable for GPIO at init? */
54};
55
56void tegra_gpio_config(struct tegra_gpio_table *table, int num);
50void tegra_gpio_enable(int gpio); 57void tegra_gpio_enable(int gpio);
51void tegra_gpio_disable(int gpio); 58void tegra_gpio_disable(int gpio);
52 59
diff --git a/arch/arm/mach-tegra/tegra2_dvfs.h b/arch/arm/mach-tegra/include/mach/harmony_audio.h
index f8c1adba96a6..af086500ab7d 100644
--- a/arch/arm/mach-tegra/tegra2_dvfs.h
+++ b/arch/arm/mach-tegra/include/mach/harmony_audio.h
@@ -1,10 +1,7 @@
1/* 1/*
2 * arch/arm/mach-tegra/tegra2_dvfs.h 2 * arch/arm/mach-tegra/include/mach/harmony_audio.h
3 * 3 *
4 * Copyright (C) 2010 Google, Inc. 4 * Copyright 2011 NVIDIA, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 * 5 *
9 * This software is licensed under the terms of the GNU General Public 6 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and 7 * License version 2, as published by the Free Software Foundation, and
@@ -17,4 +14,9 @@
17 * 14 *
18 */ 15 */
19 16
20extern struct dvfs tegra_dvfs_virtual_cpu_dvfs; 17struct harmony_audio_platform_data {
18 int gpio_spkr_en;
19 int gpio_hp_det;
20 int gpio_int_mic_en;
21 int gpio_ext_mic_en;
22};
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
index 44a4f4bcf91f..19dec3ac0854 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -26,6 +26,9 @@
26#define TEGRA_IRAM_BASE 0x40000000 26#define TEGRA_IRAM_BASE 0x40000000
27#define TEGRA_IRAM_SIZE SZ_256K 27#define TEGRA_IRAM_SIZE SZ_256K
28 28
29#define TEGRA_HOST1X_BASE 0x50000000
30#define TEGRA_HOST1X_SIZE 0x24000
31
29#define TEGRA_ARM_PERIF_BASE 0x50040000 32#define TEGRA_ARM_PERIF_BASE 0x50040000
30#define TEGRA_ARM_PERIF_SIZE SZ_8K 33#define TEGRA_ARM_PERIF_SIZE SZ_8K
31 34
@@ -35,12 +38,30 @@
35#define TEGRA_ARM_INT_DIST_BASE 0x50041000 38#define TEGRA_ARM_INT_DIST_BASE 0x50041000
36#define TEGRA_ARM_INT_DIST_SIZE SZ_4K 39#define TEGRA_ARM_INT_DIST_SIZE SZ_4K
37 40
41#define TEGRA_MPE_BASE 0x54040000
42#define TEGRA_MPE_SIZE SZ_256K
43
44#define TEGRA_VI_BASE 0x54080000
45#define TEGRA_VI_SIZE SZ_256K
46
47#define TEGRA_ISP_BASE 0x54100000
48#define TEGRA_ISP_SIZE SZ_256K
49
38#define TEGRA_DISPLAY_BASE 0x54200000 50#define TEGRA_DISPLAY_BASE 0x54200000
39#define TEGRA_DISPLAY_SIZE SZ_256K 51#define TEGRA_DISPLAY_SIZE SZ_256K
40 52
41#define TEGRA_DISPLAY2_BASE 0x54240000 53#define TEGRA_DISPLAY2_BASE 0x54240000
42#define TEGRA_DISPLAY2_SIZE SZ_256K 54#define TEGRA_DISPLAY2_SIZE SZ_256K
43 55
56#define TEGRA_HDMI_BASE 0x54280000
57#define TEGRA_HDMI_SIZE SZ_256K
58
59#define TEGRA_GART_BASE 0x58000000
60#define TEGRA_GART_SIZE SZ_32M
61
62#define TEGRA_RES_SEMA_BASE 0x60001000
63#define TEGRA_RES_SEMA_SIZE SZ_4K
64
44#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000 65#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000
45#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64 66#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64
46 67
@@ -101,6 +122,9 @@
101#define TEGRA_APB_MISC_BASE 0x70000000 122#define TEGRA_APB_MISC_BASE 0x70000000
102#define TEGRA_APB_MISC_SIZE SZ_4K 123#define TEGRA_APB_MISC_SIZE SZ_4K
103 124
125#define TEGRA_APB_MISC_DAS_BASE 0x70000c00
126#define TEGRA_APB_MISC_DAS_SIZE SZ_128
127
104#define TEGRA_AC97_BASE 0x70002000 128#define TEGRA_AC97_BASE 0x70002000
105#define TEGRA_AC97_SIZE SZ_512 129#define TEGRA_AC97_SIZE SZ_512
106 130
@@ -140,6 +164,18 @@
140#define TEGRA_PWFM_BASE 0x7000A000 164#define TEGRA_PWFM_BASE 0x7000A000
141#define TEGRA_PWFM_SIZE SZ_256 165#define TEGRA_PWFM_SIZE SZ_256
142 166
167#define TEGRA_PWFM0_BASE 0x7000A000
168#define TEGRA_PWFM0_SIZE 4
169
170#define TEGRA_PWFM1_BASE 0x7000A010
171#define TEGRA_PWFM1_SIZE 4
172
173#define TEGRA_PWFM2_BASE 0x7000A020
174#define TEGRA_PWFM2_SIZE 4
175
176#define TEGRA_PWFM3_BASE 0x7000A030
177#define TEGRA_PWFM3_SIZE 4
178
143#define TEGRA_MIPI_BASE 0x7000B000 179#define TEGRA_MIPI_BASE 0x7000B000
144#define TEGRA_MIPI_SIZE SZ_256 180#define TEGRA_MIPI_SIZE SZ_256
145 181
@@ -221,4 +257,18 @@
221#define TEGRA_SDMMC4_BASE 0xC8000600 257#define TEGRA_SDMMC4_BASE 0xC8000600
222#define TEGRA_SDMMC4_SIZE SZ_512 258#define TEGRA_SDMMC4_SIZE SZ_512
223 259
260#if defined(CONFIG_TEGRA_DEBUG_UART_NONE)
261# define TEGRA_DEBUG_UART_BASE 0
262#elif defined(CONFIG_TEGRA_DEBUG_UARTA)
263# define TEGRA_DEBUG_UART_BASE TEGRA_UARTA_BASE
264#elif defined(CONFIG_TEGRA_DEBUG_UARTB)
265# define TEGRA_DEBUG_UART_BASE TEGRA_UARTB_BASE
266#elif defined(CONFIG_TEGRA_DEBUG_UARTC)
267# define TEGRA_DEBUG_UART_BASE TEGRA_UARTC_BASE
268#elif defined(CONFIG_TEGRA_DEBUG_UARTD)
269# define TEGRA_DEBUG_UART_BASE TEGRA_UARTD_BASE
270#elif defined(CONFIG_TEGRA_DEBUG_UARTE)
271# define TEGRA_DEBUG_UART_BASE TEGRA_UARTE_BASE
272#endif
273
224#endif 274#endif
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
index 71bbf3422953..73265af4dda3 100644
--- a/arch/arm/mach-tegra/include/mach/irqs.h
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -88,7 +88,7 @@
88#define INT_SYS_STATS_MON (INT_SEC_BASE + 22) 88#define INT_SYS_STATS_MON (INT_SEC_BASE + 22)
89#define INT_GPIO5 (INT_SEC_BASE + 23) 89#define INT_GPIO5 (INT_SEC_BASE + 23)
90#define INT_CPU0_PMU_INTR (INT_SEC_BASE + 24) 90#define INT_CPU0_PMU_INTR (INT_SEC_BASE + 24)
91#define INT_CPU2_PMU_INTR (INT_SEC_BASE + 25) 91#define INT_CPU1_PMU_INTR (INT_SEC_BASE + 25)
92#define INT_SEC_RES_26 (INT_SEC_BASE + 26) 92#define INT_SEC_RES_26 (INT_SEC_BASE + 26)
93#define INT_S_LINK1 (INT_SEC_BASE + 27) 93#define INT_S_LINK1 (INT_SEC_BASE + 27)
94#define INT_APB_DMA_COP (INT_SEC_BASE + 28) 94#define INT_APB_DMA_COP (INT_SEC_BASE + 28)
@@ -166,10 +166,18 @@
166#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30) 166#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30)
167#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31) 167#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31)
168 168
169#define INT_GPIO_BASE (INT_QUAD_BASE + 32) 169#define INT_MAIN_NR (INT_QUAD_BASE + 32 - INT_PRI_BASE)
170
171#define INT_GPIO_BASE (INT_PRI_BASE + INT_MAIN_NR)
172
170#define INT_GPIO_NR (28 * 8) 173#define INT_GPIO_NR (28 * 8)
171 174
172#define NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR) 175#define TEGRA_NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR)
176
177#define INT_BOARD_BASE TEGRA_NR_IRQS
178#define NR_BOARD_IRQS 32
179
180#define NR_IRQS (INT_BOARD_BASE + NR_BOARD_IRQS)
173#endif 181#endif
174 182
175#endif 183#endif
diff --git a/arch/arm/mach-tegra/include/mach/kbc.h b/arch/arm/mach-tegra/include/mach/kbc.h
new file mode 100644
index 000000000000..04c779832c78
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/kbc.h
@@ -0,0 +1,62 @@
1/*
2 * Platform definitions for tegra-kbc keyboard input driver
3 *
4 * Copyright (c) 2010-2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifndef ASMARM_ARCH_TEGRA_KBC_H
22#define ASMARM_ARCH_TEGRA_KBC_H
23
24#include <linux/types.h>
25#include <linux/input/matrix_keypad.h>
26
27#ifdef CONFIG_ARCH_TEGRA_2x_SOC
28#define KBC_MAX_GPIO 24
29#define KBC_MAX_KPENT 8
30#else
31#define KBC_MAX_GPIO 20
32#define KBC_MAX_KPENT 7
33#endif
34
35#define KBC_MAX_ROW 16
36#define KBC_MAX_COL 8
37#define KBC_MAX_KEY (KBC_MAX_ROW * KBC_MAX_COL)
38
39struct tegra_kbc_pin_cfg {
40 bool is_row;
41 unsigned char num;
42};
43
44struct tegra_kbc_wake_key {
45 u8 row:4;
46 u8 col:4;
47};
48
49struct tegra_kbc_platform_data {
50 unsigned int debounce_cnt;
51 unsigned int repeat_cnt;
52
53 unsigned int wake_cnt; /* 0:wake on any key >1:wake on wake_cfg */
54 const struct tegra_kbc_wake_key *wake_cfg;
55
56 struct tegra_kbc_pin_cfg pin_cfg[KBC_MAX_GPIO];
57 const struct matrix_keymap_data *keymap_data;
58
59 bool wakeup;
60 bool use_fn_map;
61};
62#endif
diff --git a/arch/arm/mach-tegra/include/mach/legacy_irq.h b/arch/arm/mach-tegra/include/mach/legacy_irq.h
index db1eb3dd04c8..d898c0e3d905 100644
--- a/arch/arm/mach-tegra/include/mach/legacy_irq.h
+++ b/arch/arm/mach-tegra/include/mach/legacy_irq.h
@@ -27,5 +27,9 @@ int tegra_legacy_force_irq_status(unsigned int irq);
27void tegra_legacy_select_fiq(unsigned int irq, bool fiq); 27void tegra_legacy_select_fiq(unsigned int irq, bool fiq);
28unsigned long tegra_legacy_vfiq(int nr); 28unsigned long tegra_legacy_vfiq(int nr);
29unsigned long tegra_legacy_class(int nr); 29unsigned long tegra_legacy_class(int nr);
30int tegra_legacy_irq_set_wake(int irq, int enable);
31void tegra_legacy_irq_set_lp1_wake_mask(void);
32void tegra_legacy_irq_restore_mask(void);
33void tegra_init_legacy_irq(void);
30 34
31#endif 35#endif
diff --git a/arch/arm/mach-tegra/include/mach/memory.h b/arch/arm/mach-tegra/include/mach/memory.h
index 6151bab62af2..537db3aa81a7 100644
--- a/arch/arm/mach-tegra/include/mach/memory.h
+++ b/arch/arm/mach-tegra/include/mach/memory.h
@@ -22,7 +22,7 @@
22#define __MACH_TEGRA_MEMORY_H 22#define __MACH_TEGRA_MEMORY_H
23 23
24/* physical offset of RAM */ 24/* physical offset of RAM */
25#define PHYS_OFFSET UL(0) 25#define PLAT_PHYS_OFFSET UL(0)
26 26
27#endif 27#endif
28 28
diff --git a/arch/arm/mach-tegra/include/mach/pinmux-t2.h b/arch/arm/mach-tegra/include/mach/pinmux-t2.h
index e5b9d740f973..4c2626347263 100644
--- a/arch/arm/mach-tegra/include/mach/pinmux-t2.h
+++ b/arch/arm/mach-tegra/include/mach/pinmux-t2.h
@@ -167,6 +167,16 @@ enum tegra_drive_pingroup {
167 TEGRA_DRIVE_PINGROUP_XM2D, 167 TEGRA_DRIVE_PINGROUP_XM2D,
168 TEGRA_DRIVE_PINGROUP_XM2CLK, 168 TEGRA_DRIVE_PINGROUP_XM2CLK,
169 TEGRA_DRIVE_PINGROUP_MEMCOMP, 169 TEGRA_DRIVE_PINGROUP_MEMCOMP,
170 TEGRA_DRIVE_PINGROUP_SDIO1,
171 TEGRA_DRIVE_PINGROUP_CRT,
172 TEGRA_DRIVE_PINGROUP_DDC,
173 TEGRA_DRIVE_PINGROUP_GMA,
174 TEGRA_DRIVE_PINGROUP_GMB,
175 TEGRA_DRIVE_PINGROUP_GMC,
176 TEGRA_DRIVE_PINGROUP_GMD,
177 TEGRA_DRIVE_PINGROUP_GME,
178 TEGRA_DRIVE_PINGROUP_OWR,
179 TEGRA_DRIVE_PINGROUP_UAD,
170 TEGRA_MAX_DRIVE_PINGROUP, 180 TEGRA_MAX_DRIVE_PINGROUP,
171}; 181};
172 182
diff --git a/arch/arm/mach-tegra/include/mach/powergate.h b/arch/arm/mach-tegra/include/mach/powergate.h
new file mode 100644
index 000000000000..401d1b725291
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/powergate.h
@@ -0,0 +1,40 @@
1/*
2 * drivers/regulator/tegra-regulator.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#ifndef _MACH_TEGRA_POWERGATE_H_
21#define _MACH_TEGRA_POWERGATE_H_
22
23#define TEGRA_POWERGATE_CPU 0
24#define TEGRA_POWERGATE_3D 1
25#define TEGRA_POWERGATE_VENC 2
26#define TEGRA_POWERGATE_PCIE 3
27#define TEGRA_POWERGATE_VDEC 4
28#define TEGRA_POWERGATE_L2 5
29#define TEGRA_POWERGATE_MPE 6
30#define TEGRA_NUM_POWERGATE 7
31
32int tegra_powergate_power_on(int id);
33int tegra_powergate_power_off(int id);
34bool tegra_powergate_is_powered(int id);
35int tegra_powergate_remove_clamping(int id);
36
37/* Must be called with clk disabled, and returns with clk enabled */
38int tegra_powergate_sequence_power_up(int id, struct clk *clk);
39
40#endif /* _MACH_TEGRA_POWERGATE_H_ */
diff --git a/arch/arm/mach-tegra/include/mach/suspend.h b/arch/arm/mach-tegra/include/mach/suspend.h
new file mode 100644
index 000000000000..5af8715d2e1e
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/suspend.h
@@ -0,0 +1,38 @@
1/*
2 * arch/arm/mach-tegra/include/mach/suspend.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
21#ifndef _MACH_TEGRA_SUSPEND_H_
22#define _MACH_TEGRA_SUSPEND_H_
23
24void tegra_pinmux_suspend(void);
25void tegra_irq_suspend(void);
26void tegra_gpio_suspend(void);
27void tegra_clk_suspend(void);
28void tegra_dma_suspend(void);
29void tegra_timer_suspend(void);
30
31void tegra_pinmux_resume(void);
32void tegra_irq_resume(void);
33void tegra_gpio_resume(void);
34void tegra_clk_resume(void);
35void tegra_dma_resume(void);
36void tegra_timer_resume(void);
37
38#endif /* _MACH_TEGRA_SUSPEND_H_ */
diff --git a/arch/arm/mach-tegra/include/mach/system.h b/arch/arm/mach-tegra/include/mach/system.h
index 84d5d46113f7..d0183d876c3b 100644
--- a/arch/arm/mach-tegra/include/mach/system.h
+++ b/arch/arm/mach-tegra/include/mach/system.h
@@ -24,16 +24,10 @@
24#include <mach/hardware.h> 24#include <mach/hardware.h>
25#include <mach/iomap.h> 25#include <mach/iomap.h>
26 26
27static inline void arch_idle(void) 27extern void (*arch_reset)(char mode, const char *cmd);
28{
29}
30 28
31static inline void arch_reset(char mode, const char *cmd) 29static inline void arch_idle(void)
32{ 30{
33 void __iomem *reset = IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x04);
34 u32 reg = readl(reset);
35 reg |= 0x04;
36 writel(reg, reset);
37} 31}
38 32
39#endif 33#endif
diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h
index 6c4dd815abd7..4e8323770c79 100644
--- a/arch/arm/mach-tegra/include/mach/uncompress.h
+++ b/arch/arm/mach-tegra/include/mach/uncompress.h
@@ -26,23 +26,9 @@
26 26
27#include <mach/iomap.h> 27#include <mach/iomap.h>
28 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) 29static void putc(int c)
44{ 30{
45 volatile u8 *uart = (volatile u8 *)DEBUG_UART_BASE; 31 volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
46 int shift = 2; 32 int shift = 2;
47 33
48 if (uart == NULL) 34 if (uart == NULL)
@@ -59,7 +45,7 @@ static inline void flush(void)
59 45
60static inline void arch_decomp_setup(void) 46static inline void arch_decomp_setup(void)
61{ 47{
62 volatile u8 *uart = (volatile u8 *)DEBUG_UART_BASE; 48 volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
63 int shift = 2; 49 int shift = 2;
64 50
65 if (uart == NULL) 51 if (uart == NULL)
diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h
new file mode 100644
index 000000000000..d4b8f9e298a8
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/usb_phy.h
@@ -0,0 +1,86 @@
1/*
2 * arch/arm/mach-tegra/include/mach/usb_phy.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_USB_PHY_H
18#define __MACH_USB_PHY_H
19
20#include <linux/clk.h>
21#include <linux/usb/otg.h>
22
23struct tegra_utmip_config {
24 u8 hssync_start_delay;
25 u8 elastic_limit;
26 u8 idle_wait_delay;
27 u8 term_range_adj;
28 u8 xcvr_setup;
29 u8 xcvr_lsfslew;
30 u8 xcvr_lsrslew;
31};
32
33struct tegra_ulpi_config {
34 int reset_gpio;
35 const char *clk;
36};
37
38enum tegra_usb_phy_port_speed {
39 TEGRA_USB_PHY_PORT_SPEED_FULL = 0,
40 TEGRA_USB_PHY_PORT_SPEED_LOW,
41 TEGRA_USB_PHY_PORT_SPEED_HIGH,
42};
43
44enum tegra_usb_phy_mode {
45 TEGRA_USB_PHY_MODE_DEVICE,
46 TEGRA_USB_PHY_MODE_HOST,
47};
48
49struct tegra_xtal_freq;
50
51struct tegra_usb_phy {
52 int instance;
53 const struct tegra_xtal_freq *freq;
54 void __iomem *regs;
55 void __iomem *pad_regs;
56 struct clk *clk;
57 struct clk *pll_u;
58 struct clk *pad_clk;
59 enum tegra_usb_phy_mode mode;
60 void *config;
61 struct otg_transceiver *ulpi;
62};
63
64struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
65 void *config, enum tegra_usb_phy_mode phy_mode);
66
67int tegra_usb_phy_power_on(struct tegra_usb_phy *phy);
68
69void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy);
70
71void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy);
72
73void tegra_usb_phy_power_off(struct tegra_usb_phy *phy);
74
75void tegra_usb_phy_preresume(struct tegra_usb_phy *phy);
76
77void tegra_usb_phy_postresume(struct tegra_usb_phy *phy);
78
79void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy,
80 enum tegra_usb_phy_port_speed port_speed);
81
82void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy);
83
84void tegra_usb_phy_close(struct tegra_usb_phy *phy);
85
86#endif /* __MACH_USB_PHY_H */
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index de7dfad6f769..dfbc219ea492 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/delay.h>
21#include <linux/init.h> 22#include <linux/init.h>
22#include <linux/interrupt.h> 23#include <linux/interrupt.h>
23#include <linux/irq.h> 24#include <linux/irq.h>
@@ -26,146 +27,135 @@
26#include <asm/hardware/gic.h> 27#include <asm/hardware/gic.h>
27 28
28#include <mach/iomap.h> 29#include <mach/iomap.h>
30#include <mach/legacy_irq.h>
31#include <mach/suspend.h>
29 32
30#include "board.h" 33#include "board.h"
31 34
32#define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE) 35#define PMC_CTRL 0x0
33#define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE) 36#define PMC_CTRL_LATCH_WAKEUPS (1 << 5)
34#define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ) 37#define PMC_WAKE_MASK 0xc
38#define PMC_WAKE_LEVEL 0x10
39#define PMC_WAKE_STATUS 0x14
40#define PMC_SW_WAKE_STATUS 0x18
41#define PMC_DPD_SAMPLE 0x20
35 42
36#define APBDMA_IRQ_STA_CPU 0x14 43static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
37#define APBDMA_IRQ_MASK_SET 0x20
38#define APBDMA_IRQ_MASK_CLR 0x24
39 44
40#define ICTLR_CPU_IER 0x20 45static u32 tegra_lp0_wake_enb;
41#define ICTLR_CPU_IER_SET 0x24 46static u32 tegra_lp0_wake_level;
42#define ICTLR_CPU_IER_CLR 0x28 47static u32 tegra_lp0_wake_level_any;
43#define ICTLR_CPU_IEP_CLASS 0x2c
44#define ICTLR_COP_IER 0x30
45#define ICTLR_COP_IER_SET 0x34
46#define ICTLR_COP_IER_CLR 0x38
47#define ICTLR_COP_IEP_CLASS 0x3c
48 48
49static void (*gic_mask_irq)(struct irq_data *d); 49static void (*tegra_gic_mask_irq)(struct irq_data *d);
50static void (*gic_unmask_irq)(struct irq_data *d); 50static void (*tegra_gic_unmask_irq)(struct irq_data *d);
51static void (*tegra_gic_ack_irq)(struct irq_data *d);
51 52
52#define irq_to_ictlr(irq) (((irq)-32) >> 5) 53/* ensures that sufficient time is passed for a register write to
53static void __iomem *tegra_ictlr_base = IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE); 54 * serialize into the 32KHz domain */
54#define ictlr_to_virt(ictlr) (tegra_ictlr_base + (ictlr)*0x100) 55static void pmc_32kwritel(u32 val, unsigned long offs)
56{
57 writel(val, pmc + offs);
58 udelay(130);
59}
60
61int tegra_set_lp1_wake(int irq, int enable)
62{
63 return tegra_legacy_irq_set_wake(irq, enable);
64}
65
66void tegra_set_lp0_wake_pads(u32 wake_enb, u32 wake_level, u32 wake_any)
67{
68 u32 temp;
69 u32 status;
70 u32 lvl;
71
72 wake_level &= wake_enb;
73 wake_any &= wake_enb;
74
75 wake_level |= (tegra_lp0_wake_level & tegra_lp0_wake_enb);
76 wake_any |= (tegra_lp0_wake_level_any & tegra_lp0_wake_enb);
77
78 wake_enb |= tegra_lp0_wake_enb;
79
80 pmc_32kwritel(0, PMC_SW_WAKE_STATUS);
81 temp = readl(pmc + PMC_CTRL);
82 temp |= PMC_CTRL_LATCH_WAKEUPS;
83 pmc_32kwritel(temp, PMC_CTRL);
84 temp &= ~PMC_CTRL_LATCH_WAKEUPS;
85 pmc_32kwritel(temp, PMC_CTRL);
86 status = readl(pmc + PMC_SW_WAKE_STATUS);
87 lvl = readl(pmc + PMC_WAKE_LEVEL);
88
89 /* flip the wakeup trigger for any-edge triggered pads
90 * which are currently asserting as wakeups */
91 lvl ^= status;
92 lvl &= wake_any;
93
94 wake_level |= lvl;
95
96 writel(wake_level, pmc + PMC_WAKE_LEVEL);
97 /* Enable DPD sample to trigger sampling pads data and direction
98 * in which pad will be driven during lp0 mode*/
99 writel(0x1, pmc + PMC_DPD_SAMPLE);
100
101 writel(wake_enb, pmc + PMC_WAKE_MASK);
102}
55 103
56static void tegra_mask(struct irq_data *d) 104static void tegra_mask(struct irq_data *d)
57{ 105{
58 void __iomem *addr = ictlr_to_virt(irq_to_ictlr(d->irq)); 106 tegra_gic_mask_irq(d);
59 gic_mask_irq(d); 107 tegra_legacy_mask_irq(d->irq);
60 writel(1<<(d->irq&31), addr+ICTLR_CPU_IER_CLR);
61} 108}
62 109
63static void tegra_unmask(struct irq_data *d) 110static void tegra_unmask(struct irq_data *d)
64{ 111{
65 void __iomem *addr = ictlr_to_virt(irq_to_ictlr(d->irq)); 112 tegra_gic_unmask_irq(d);
66 gic_unmask_irq(d); 113 tegra_legacy_unmask_irq(d->irq);
67 writel(1<<(d->irq&31), addr+ICTLR_CPU_IER_SET);
68} 114}
69 115
70#ifdef CONFIG_PM 116static void tegra_ack(struct irq_data *d)
117{
118 tegra_legacy_force_irq_clr(d->irq);
119 tegra_gic_ack_irq(d);
120}
71 121
72static int tegra_set_wake(struct irq_data *d, unsigned int on) 122static int tegra_retrigger(struct irq_data *d)
73{ 123{
74 return 0; 124 tegra_legacy_force_irq_set(d->irq);
125 return 1;
75} 126}
76#endif
77 127
78static struct irq_chip tegra_irq = { 128static struct irq_chip tegra_irq = {
79 .name = "PPI", 129 .name = "PPI",
80 .irq_mask = tegra_mask, 130 .irq_ack = tegra_ack,
81 .irq_unmask = tegra_unmask, 131 .irq_mask = tegra_mask,
82#ifdef CONFIG_PM 132 .irq_unmask = tegra_unmask,
83 .irq_set_wake = tegra_set_wake, 133 .irq_retrigger = tegra_retrigger,
84#endif
85}; 134};
86 135
87void __init tegra_init_irq(void) 136void __init tegra_init_irq(void)
88{ 137{
89 struct irq_chip *gic; 138 struct irq_chip *gic;
90 unsigned int i; 139 unsigned int i;
140 int irq;
91 141
92 for (i = 0; i < PPI_NR; i++) { 142 tegra_init_legacy_irq();
93 writel(~0, ictlr_to_virt(i) + ICTLR_CPU_IER_CLR);
94 writel(0, ictlr_to_virt(i) + ICTLR_CPU_IEP_CLASS);
95 }
96 143
97 gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 144 gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
98 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); 145 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
99 146
100 gic = get_irq_chip(29); 147 gic = get_irq_chip(29);
101 gic_unmask_irq = gic->irq_unmask; 148 tegra_gic_unmask_irq = gic->irq_unmask;
102 gic_mask_irq = gic->irq_mask; 149 tegra_gic_mask_irq = gic->irq_mask;
103 tegra_irq.irq_ack = gic->irq_ack; 150 tegra_gic_ack_irq = gic->irq_ack;
104#ifdef CONFIG_SMP 151#ifdef CONFIG_SMP
105 tegra_irq.irq_set_affinity = gic->irq_set_affinity; 152 tegra_irq.irq_set_affinity = gic->irq_set_affinity;
106#endif 153#endif
107 154
108 for (i = INT_PRI_BASE; i < INT_GPIO_BASE; i++) { 155 for (i = 0; i < INT_MAIN_NR; i++) {
109 set_irq_chip(i, &tegra_irq); 156 irq = INT_PRI_BASE + i;
110 set_irq_handler(i, handle_level_irq); 157 set_irq_chip(irq, &tegra_irq);
111 set_irq_flags(i, IRQF_VALID); 158 set_irq_handler(irq, handle_level_irq);
159 set_irq_flags(irq, IRQF_VALID);
112 } 160 }
113} 161}
114
115#ifdef CONFIG_PM
116static u32 cop_ier[PPI_NR];
117static u32 cpu_ier[PPI_NR];
118static u32 cpu_iep[PPI_NR];
119
120void tegra_irq_suspend(void)
121{
122 unsigned long flags;
123 int i;
124
125 for (i = INT_PRI_BASE; i < INT_GPIO_BASE; i++) {
126 struct irq_desc *desc = irq_to_desc(i);
127 if (!desc)
128 continue;
129 if (desc->status & IRQ_WAKEUP) {
130 pr_debug("irq %d is wakeup\n", i);
131 continue;
132 }
133 disable_irq(i);
134 }
135
136 local_irq_save(flags);
137 for (i = 0; i < PPI_NR; i++) {
138 void __iomem *ictlr = ictlr_to_virt(i);
139 cpu_ier[i] = readl(ictlr + ICTLR_CPU_IER);
140 cpu_iep[i] = readl(ictlr + ICTLR_CPU_IEP_CLASS);
141 cop_ier[i] = readl(ictlr + ICTLR_COP_IER);
142 writel(~0, ictlr + ICTLR_COP_IER_CLR);
143 }
144 local_irq_restore(flags);
145}
146
147void tegra_irq_resume(void)
148{
149 unsigned long flags;
150 int i;
151
152 local_irq_save(flags);
153 for (i = 0; i < PPI_NR; i++) {
154 void __iomem *ictlr = ictlr_to_virt(i);
155 writel(cpu_iep[i], ictlr + ICTLR_CPU_IEP_CLASS);
156 writel(~0ul, ictlr + ICTLR_CPU_IER_CLR);
157 writel(cpu_ier[i], ictlr + ICTLR_CPU_IER_SET);
158 writel(0, ictlr + ICTLR_COP_IEP_CLASS);
159 writel(~0ul, ictlr + ICTLR_COP_IER_CLR);
160 writel(cop_ier[i], ictlr + ICTLR_COP_IER_SET);
161 }
162 local_irq_restore(flags);
163
164 for (i = INT_PRI_BASE; i < INT_GPIO_BASE; i++) {
165 struct irq_desc *desc = irq_to_desc(i);
166 if (!desc || (desc->status & IRQ_WAKEUP))
167 continue;
168 enable_irq(i);
169 }
170}
171#endif
diff --git a/arch/arm/mach-tegra/legacy_irq.c b/arch/arm/mach-tegra/legacy_irq.c
index 7cc8601c19ff..38eb719a4f53 100644
--- a/arch/arm/mach-tegra/legacy_irq.c
+++ b/arch/arm/mach-tegra/legacy_irq.c
@@ -18,17 +18,30 @@
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <mach/iomap.h> 20#include <mach/iomap.h>
21#include <mach/irqs.h>
21#include <mach/legacy_irq.h> 22#include <mach/legacy_irq.h>
22 23
23#define ICTLR_CPU_IER 0x20 24#define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE)
24#define ICTLR_CPU_IER_SET 0x24 25#define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE)
25#define ICTLR_CPU_IER_CLR 0x28 26#define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ)
26#define ICTLR_CPU_IEP_CLASS 0x2C 27
27#define ICTLR_CPU_IEP_VFIQ 0x08 28#define ICTLR_CPU_IEP_VFIQ 0x08
28#define ICTLR_CPU_IEP_FIR 0x14 29#define ICTLR_CPU_IEP_FIR 0x14
29#define ICTLR_CPU_IEP_FIR_SET 0x18 30#define ICTLR_CPU_IEP_FIR_SET 0x18
30#define ICTLR_CPU_IEP_FIR_CLR 0x1c 31#define ICTLR_CPU_IEP_FIR_CLR 0x1c
31 32
33#define ICTLR_CPU_IER 0x20
34#define ICTLR_CPU_IER_SET 0x24
35#define ICTLR_CPU_IER_CLR 0x28
36#define ICTLR_CPU_IEP_CLASS 0x2C
37
38#define ICTLR_COP_IER 0x30
39#define ICTLR_COP_IER_SET 0x34
40#define ICTLR_COP_IER_CLR 0x38
41#define ICTLR_COP_IEP_CLASS 0x3c
42
43#define NUM_ICTLRS 4
44
32static void __iomem *ictlr_reg_base[] = { 45static void __iomem *ictlr_reg_base[] = {
33 IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), 46 IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
34 IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), 47 IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
@@ -36,6 +49,9 @@ static void __iomem *ictlr_reg_base[] = {
36 IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), 49 IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
37}; 50};
38 51
52static u32 tegra_legacy_wake_mask[4];
53static u32 tegra_legacy_saved_mask[4];
54
39/* When going into deep sleep, the CPU is powered down, taking the GIC with it 55/* When going into deep sleep, the CPU is powered down, taking the GIC with it
40 In order to wake, the wake interrupts need to be enabled in the legacy 56 In order to wake, the wake interrupts need to be enabled in the legacy
41 interrupt controller. */ 57 interrupt controller. */
@@ -112,3 +128,88 @@ unsigned long tegra_legacy_class(int nr)
112 base = ictlr_reg_base[nr]; 128 base = ictlr_reg_base[nr];
113 return readl(base + ICTLR_CPU_IEP_CLASS); 129 return readl(base + ICTLR_CPU_IEP_CLASS);
114} 130}
131
132int tegra_legacy_irq_set_wake(int irq, int enable)
133{
134 irq -= 32;
135 if (enable)
136 tegra_legacy_wake_mask[irq >> 5] |= 1 << (irq & 31);
137 else
138 tegra_legacy_wake_mask[irq >> 5] &= ~(1 << (irq & 31));
139
140 return 0;
141}
142
143void tegra_legacy_irq_set_lp1_wake_mask(void)
144{
145 void __iomem *base;
146 int i;
147
148 for (i = 0; i < NUM_ICTLRS; i++) {
149 base = ictlr_reg_base[i];
150 tegra_legacy_saved_mask[i] = readl(base + ICTLR_CPU_IER);
151 writel(tegra_legacy_wake_mask[i], base + ICTLR_CPU_IER);
152 }
153}
154
155void tegra_legacy_irq_restore_mask(void)
156{
157 void __iomem *base;
158 int i;
159
160 for (i = 0; i < NUM_ICTLRS; i++) {
161 base = ictlr_reg_base[i];
162 writel(tegra_legacy_saved_mask[i], base + ICTLR_CPU_IER);
163 }
164}
165
166void tegra_init_legacy_irq(void)
167{
168 int i;
169
170 for (i = 0; i < NUM_ICTLRS; i++) {
171 void __iomem *ictlr = ictlr_reg_base[i];
172 writel(~0, ictlr + ICTLR_CPU_IER_CLR);
173 writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
174 }
175}
176
177#ifdef CONFIG_PM
178static u32 cop_ier[NUM_ICTLRS];
179static u32 cpu_ier[NUM_ICTLRS];
180static u32 cpu_iep[NUM_ICTLRS];
181
182void tegra_irq_suspend(void)
183{
184 unsigned long flags;
185 int i;
186
187 local_irq_save(flags);
188 for (i = 0; i < NUM_ICTLRS; i++) {
189 void __iomem *ictlr = ictlr_reg_base[i];
190 cpu_ier[i] = readl(ictlr + ICTLR_CPU_IER);
191 cpu_iep[i] = readl(ictlr + ICTLR_CPU_IEP_CLASS);
192 cop_ier[i] = readl(ictlr + ICTLR_COP_IER);
193 writel(~0, ictlr + ICTLR_COP_IER_CLR);
194 }
195 local_irq_restore(flags);
196}
197
198void tegra_irq_resume(void)
199{
200 unsigned long flags;
201 int i;
202
203 local_irq_save(flags);
204 for (i = 0; i < NUM_ICTLRS; i++) {
205 void __iomem *ictlr = ictlr_reg_base[i];
206 writel(cpu_iep[i], ictlr + ICTLR_CPU_IEP_CLASS);
207 writel(~0ul, ictlr + ICTLR_CPU_IER_CLR);
208 writel(cpu_ier[i], ictlr + ICTLR_CPU_IER_SET);
209 writel(0, ictlr + ICTLR_COP_IEP_CLASS);
210 writel(~0ul, ictlr + ICTLR_COP_IER_CLR);
211 writel(cop_ier[i], ictlr + ICTLR_COP_IER_SET);
212 }
213 local_irq_restore(flags);
214}
215#endif
diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c
index f81ca7cbbc1f..e91d681d45a2 100644
--- a/arch/arm/mach-tegra/localtimer.c
+++ b/arch/arm/mach-tegra/localtimer.c
@@ -18,8 +18,9 @@
18/* 18/*
19 * Setup the local clock events for a CPU. 19 * Setup the local clock events for a CPU.
20 */ 20 */
21void __cpuinit local_timer_setup(struct clock_event_device *evt) 21int __cpuinit local_timer_setup(struct clock_event_device *evt)
22{ 22{
23 evt->irq = IRQ_LOCALTIMER; 23 evt->irq = IRQ_LOCALTIMER;
24 twd_timer_setup(evt); 24 twd_timer_setup(evt);
25 return 0;
25} 26}
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index 53f5fa37014a..2941212b853c 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -39,6 +39,7 @@
39#include <mach/pinmux.h> 39#include <mach/pinmux.h>
40#include <mach/iomap.h> 40#include <mach/iomap.h>
41#include <mach/clk.h> 41#include <mach/clk.h>
42#include <mach/powergate.h>
42 43
43/* register definitions */ 44/* register definitions */
44#define AFI_OFFSET 0x3800 45#define AFI_OFFSET 0x3800
@@ -682,24 +683,41 @@ static void tegra_pcie_xclk_clamp(bool clamp)
682 pmc_writel(reg, PMC_SCRATCH42); 683 pmc_writel(reg, PMC_SCRATCH42);
683} 684}
684 685
685static int tegra_pcie_power_on(void) 686static void tegra_pcie_power_off(void)
686{ 687{
687 tegra_pcie_xclk_clamp(true);
688 tegra_periph_reset_assert(tegra_pcie.pcie_xclk); 688 tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
689 tegra_pcie_xclk_clamp(false); 689 tegra_periph_reset_assert(tegra_pcie.afi_clk);
690 tegra_periph_reset_assert(tegra_pcie.pex_clk);
690 691
691 clk_enable(tegra_pcie.afi_clk); 692 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
692 clk_enable(tegra_pcie.pex_clk); 693 tegra_pcie_xclk_clamp(true);
693 return clk_enable(tegra_pcie.pll_e);
694} 694}
695 695
696static void tegra_pcie_power_off(void) 696static int tegra_pcie_power_regate(void)
697{ 697{
698 int err;
699
700 tegra_pcie_power_off();
701
702 tegra_pcie_xclk_clamp(true);
703
698 tegra_periph_reset_assert(tegra_pcie.pcie_xclk); 704 tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
699 tegra_periph_reset_assert(tegra_pcie.afi_clk); 705 tegra_periph_reset_assert(tegra_pcie.afi_clk);
700 tegra_periph_reset_assert(tegra_pcie.pex_clk);
701 706
702 tegra_pcie_xclk_clamp(true); 707 err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
708 tegra_pcie.pex_clk);
709 if (err) {
710 pr_err("PCIE: powerup sequence failed: %d\n", err);
711 return err;
712 }
713
714 tegra_periph_reset_deassert(tegra_pcie.afi_clk);
715
716 tegra_pcie_xclk_clamp(false);
717
718 clk_enable(tegra_pcie.afi_clk);
719 clk_enable(tegra_pcie.pex_clk);
720 return clk_enable(tegra_pcie.pll_e);
703} 721}
704 722
705static int tegra_pcie_clocks_get(void) 723static int tegra_pcie_clocks_get(void)
@@ -759,7 +777,7 @@ static int __init tegra_pcie_get_resources(void)
759 return err; 777 return err;
760 } 778 }
761 779
762 err = tegra_pcie_power_on(); 780 err = tegra_pcie_power_regate();
763 if (err) { 781 if (err) {
764 pr_err("PCIE: failed to power up: %d\n", err); 782 pr_err("PCIE: failed to power up: %d\n", err);
765 goto err_pwr_on; 783 goto err_pwr_on;
diff --git a/arch/arm/mach-tegra/pinmux-t2-tables.c b/arch/arm/mach-tegra/pinmux-t2-tables.c
index a6ea34e782dc..a475367befa3 100644
--- a/arch/arm/mach-tegra/pinmux-t2-tables.c
+++ b/arch/arm/mach-tegra/pinmux-t2-tables.c
@@ -29,6 +29,7 @@
29 29
30#include <mach/iomap.h> 30#include <mach/iomap.h>
31#include <mach/pinmux.h> 31#include <mach/pinmux.h>
32#include <mach/suspend.h>
32 33
33#define DRIVE_PINGROUP(pg_name, r) \ 34#define DRIVE_PINGROUP(pg_name, r) \
34 [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \ 35 [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \
@@ -65,6 +66,16 @@ const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE
65 DRIVE_PINGROUP(XM2D, 0x8cc), 66 DRIVE_PINGROUP(XM2D, 0x8cc),
66 DRIVE_PINGROUP(XM2CLK, 0x8d0), 67 DRIVE_PINGROUP(XM2CLK, 0x8d0),
67 DRIVE_PINGROUP(MEMCOMP, 0x8d4), 68 DRIVE_PINGROUP(MEMCOMP, 0x8d4),
69 DRIVE_PINGROUP(SDIO1, 0x8e0),
70 DRIVE_PINGROUP(CRT, 0x8ec),
71 DRIVE_PINGROUP(DDC, 0x8f0),
72 DRIVE_PINGROUP(GMA, 0x8f4),
73 DRIVE_PINGROUP(GMB, 0x8f8),
74 DRIVE_PINGROUP(GMC, 0x8fc),
75 DRIVE_PINGROUP(GMD, 0x900),
76 DRIVE_PINGROUP(GME, 0x904),
77 DRIVE_PINGROUP(OWR, 0x908),
78 DRIVE_PINGROUP(UAD, 0x90c),
68}; 79};
69 80
70#define PINGROUP(pg_name, vdd, f0, f1, f2, f3, f_safe, \ 81#define PINGROUP(pg_name, vdd, f0, f1, f2, f3, f_safe, \
@@ -216,7 +227,8 @@ const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = {
216#define PULLUPDOWN_REG_NUM 5 227#define PULLUPDOWN_REG_NUM 5
217 228
218static u32 pinmux_reg[TRISTATE_REG_NUM + PIN_MUX_CTL_REG_NUM + 229static u32 pinmux_reg[TRISTATE_REG_NUM + PIN_MUX_CTL_REG_NUM +
219 PULLUPDOWN_REG_NUM]; 230 PULLUPDOWN_REG_NUM +
231 ARRAY_SIZE(tegra_soc_drive_pingroups)];
220 232
221static inline unsigned long pg_readl(unsigned long offset) 233static inline unsigned long pg_readl(unsigned long offset)
222{ 234{
@@ -233,14 +245,17 @@ void tegra_pinmux_suspend(void)
233 unsigned int i; 245 unsigned int i;
234 u32 *ctx = pinmux_reg; 246 u32 *ctx = pinmux_reg;
235 247
236 for (i = 0; i < TRISTATE_REG_NUM; i++)
237 *ctx++ = pg_readl(TRISTATE_REG_A + i*4);
238
239 for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++) 248 for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++)
240 *ctx++ = pg_readl(PIN_MUX_CTL_REG_A + i*4); 249 *ctx++ = pg_readl(PIN_MUX_CTL_REG_A + i*4);
241 250
242 for (i = 0; i < PULLUPDOWN_REG_NUM; i++) 251 for (i = 0; i < PULLUPDOWN_REG_NUM; i++)
243 *ctx++ = pg_readl(PULLUPDOWN_REG_A + i*4); 252 *ctx++ = pg_readl(PULLUPDOWN_REG_A + i*4);
253
254 for (i = 0; i < TRISTATE_REG_NUM; i++)
255 *ctx++ = pg_readl(TRISTATE_REG_A + i*4);
256
257 for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++)
258 *ctx++ = pg_readl(tegra_soc_drive_pingroups[i].reg);
244} 259}
245 260
246void tegra_pinmux_resume(void) 261void tegra_pinmux_resume(void)
@@ -256,5 +271,8 @@ void tegra_pinmux_resume(void)
256 271
257 for (i = 0; i < TRISTATE_REG_NUM; i++) 272 for (i = 0; i < TRISTATE_REG_NUM; i++)
258 pg_writel(*ctx++, TRISTATE_REG_A + i*4); 273 pg_writel(*ctx++, TRISTATE_REG_A + i*4);
274
275 for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++)
276 pg_writel(*ctx++, tegra_soc_drive_pingroups[i].reg);
259} 277}
260#endif 278#endif
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c
new file mode 100644
index 000000000000..3cee9aa1f2c8
--- /dev/null
+++ b/arch/arm/mach-tegra/powergate.c
@@ -0,0 +1,212 @@
1/*
2 * drivers/powergate/tegra-powergate.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/clk.h>
22#include <linux/debugfs.h>
23#include <linux/delay.h>
24#include <linux/err.h>
25#include <linux/init.h>
26#include <linux/io.h>
27#include <linux/seq_file.h>
28#include <linux/spinlock.h>
29
30#include <mach/clk.h>
31#include <mach/iomap.h>
32#include <mach/powergate.h>
33
34#define PWRGATE_TOGGLE 0x30
35#define PWRGATE_TOGGLE_START (1 << 8)
36
37#define REMOVE_CLAMPING 0x34
38
39#define PWRGATE_STATUS 0x38
40
41static DEFINE_SPINLOCK(tegra_powergate_lock);
42
43static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
44
45static u32 pmc_read(unsigned long reg)
46{
47 return readl(pmc + reg);
48}
49
50static void pmc_write(u32 val, unsigned long reg)
51{
52 writel(val, pmc + reg);
53}
54
55static int tegra_powergate_set(int id, bool new_state)
56{
57 bool status;
58 unsigned long flags;
59
60 spin_lock_irqsave(&tegra_powergate_lock, flags);
61
62 status = pmc_read(PWRGATE_STATUS) & (1 << id);
63
64 if (status == new_state) {
65 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
66 return -EINVAL;
67 }
68
69 pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
70
71 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
72
73 return 0;
74}
75
76int tegra_powergate_power_on(int id)
77{
78 if (id < 0 || id >= TEGRA_NUM_POWERGATE)
79 return -EINVAL;
80
81 return tegra_powergate_set(id, true);
82}
83
84int tegra_powergate_power_off(int id)
85{
86 if (id < 0 || id >= TEGRA_NUM_POWERGATE)
87 return -EINVAL;
88
89 return tegra_powergate_set(id, false);
90}
91
92bool tegra_powergate_is_powered(int id)
93{
94 u32 status;
95
96 if (id < 0 || id >= TEGRA_NUM_POWERGATE)
97 return -EINVAL;
98
99 status = pmc_read(PWRGATE_STATUS) & (1 << id);
100 return !!status;
101}
102
103int tegra_powergate_remove_clamping(int id)
104{
105 u32 mask;
106
107 if (id < 0 || id >= TEGRA_NUM_POWERGATE)
108 return -EINVAL;
109
110 /*
111 * Tegra 2 has a bug where PCIE and VDE clamping masks are
112 * swapped relatively to the partition ids
113 */
114 if (id == TEGRA_POWERGATE_VDEC)
115 mask = (1 << TEGRA_POWERGATE_PCIE);
116 else if (id == TEGRA_POWERGATE_PCIE)
117 mask = (1 << TEGRA_POWERGATE_VDEC);
118 else
119 mask = (1 << id);
120
121 pmc_write(mask, REMOVE_CLAMPING);
122
123 return 0;
124}
125
126/* Must be called with clk disabled, and returns with clk enabled */
127int tegra_powergate_sequence_power_up(int id, struct clk *clk)
128{
129 int ret;
130
131 tegra_periph_reset_assert(clk);
132
133 ret = tegra_powergate_power_on(id);
134 if (ret)
135 goto err_power;
136
137 ret = clk_enable(clk);
138 if (ret)
139 goto err_clk;
140
141 udelay(10);
142
143 ret = tegra_powergate_remove_clamping(id);
144 if (ret)
145 goto err_clamp;
146
147 udelay(10);
148 tegra_periph_reset_deassert(clk);
149
150 return 0;
151
152err_clamp:
153 clk_disable(clk);
154err_clk:
155 tegra_powergate_power_off(id);
156err_power:
157 return ret;
158}
159
160#ifdef CONFIG_DEBUG_FS
161
162static const char * const powergate_name[] = {
163 [TEGRA_POWERGATE_CPU] = "cpu",
164 [TEGRA_POWERGATE_3D] = "3d",
165 [TEGRA_POWERGATE_VENC] = "venc",
166 [TEGRA_POWERGATE_VDEC] = "vdec",
167 [TEGRA_POWERGATE_PCIE] = "pcie",
168 [TEGRA_POWERGATE_L2] = "l2",
169 [TEGRA_POWERGATE_MPE] = "mpe",
170};
171
172static int powergate_show(struct seq_file *s, void *data)
173{
174 int i;
175
176 seq_printf(s, " powergate powered\n");
177 seq_printf(s, "------------------\n");
178
179 for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
180 seq_printf(s, " %9s %7s\n", powergate_name[i],
181 tegra_powergate_is_powered(i) ? "yes" : "no");
182 return 0;
183}
184
185static int powergate_open(struct inode *inode, struct file *file)
186{
187 return single_open(file, powergate_show, inode->i_private);
188}
189
190static const struct file_operations powergate_fops = {
191 .open = powergate_open,
192 .read = seq_read,
193 .llseek = seq_lseek,
194 .release = single_release,
195};
196
197static int __init powergate_debugfs_init(void)
198{
199 struct dentry *d;
200 int err = -ENOMEM;
201
202 d = debugfs_create_file("powergate", S_IRUGO, NULL, NULL,
203 &powergate_fops);
204 if (!d)
205 return -ENOMEM;
206
207 return err;
208}
209
210late_initcall(powergate_debugfs_init);
211
212#endif
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index f0dae6d8ba52..6d7c4eea4dcb 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -23,14 +23,15 @@
23#include <linux/spinlock.h> 23#include <linux/spinlock.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/hrtimer.h>
27#include <linux/clkdev.h> 26#include <linux/clkdev.h>
27#include <linux/clk.h>
28 28
29#include <mach/iomap.h> 29#include <mach/iomap.h>
30#include <mach/suspend.h>
30 31
31#include "clock.h" 32#include "clock.h"
32#include "fuse.h" 33#include "fuse.h"
33#include "tegra2_dvfs.h" 34#include "tegra2_emc.h"
34 35
35#define RST_DEVICES 0x004 36#define RST_DEVICES 0x004
36#define RST_DEVICES_SET 0x300 37#define RST_DEVICES_SET 0x300
@@ -51,7 +52,7 @@
51#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30) 52#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30)
52#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30) 53#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30)
53#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30) 54#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
54#define OSC_CTRL_MASK 0x3f2 55#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
55 56
56#define OSC_FREQ_DET 0x58 57#define OSC_FREQ_DET 0x58
57#define OSC_FREQ_DET_TRIG (1<<31) 58#define OSC_FREQ_DET_TRIG (1<<31)
@@ -73,12 +74,15 @@
73#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF 74#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF
74#define PERIPH_CLK_SOURCE_DIV_SHIFT 0 75#define PERIPH_CLK_SOURCE_DIV_SHIFT 0
75 76
77#define SDMMC_CLK_INT_FB_SEL (1 << 23)
78#define SDMMC_CLK_INT_FB_DLY_SHIFT 16
79#define SDMMC_CLK_INT_FB_DLY_MASK (0xF << SDMMC_CLK_INT_FB_DLY_SHIFT)
80
76#define PLL_BASE 0x0 81#define PLL_BASE 0x0
77#define PLL_BASE_BYPASS (1<<31) 82#define PLL_BASE_BYPASS (1<<31)
78#define PLL_BASE_ENABLE (1<<30) 83#define PLL_BASE_ENABLE (1<<30)
79#define PLL_BASE_REF_ENABLE (1<<29) 84#define PLL_BASE_REF_ENABLE (1<<29)
80#define PLL_BASE_OVERRIDE (1<<28) 85#define PLL_BASE_OVERRIDE (1<<28)
81#define PLL_BASE_LOCK (1<<27)
82#define PLL_BASE_DIVP_MASK (0x7<<20) 86#define PLL_BASE_DIVP_MASK (0x7<<20)
83#define PLL_BASE_DIVP_SHIFT 20 87#define PLL_BASE_DIVP_SHIFT 20
84#define PLL_BASE_DIVN_MASK (0x3FF<<8) 88#define PLL_BASE_DIVN_MASK (0x3FF<<8)
@@ -93,7 +97,6 @@
93#define PLL_OUT_RESET_DISABLE (1<<0) 97#define PLL_OUT_RESET_DISABLE (1<<0)
94 98
95#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc) 99#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
96#define PLL_MISC_LOCK_ENABLE(c) (((c)->flags & PLLU) ? (1<<22) : (1<<18))
97 100
98#define PLL_MISC_DCCON_SHIFT 20 101#define PLL_MISC_DCCON_SHIFT 20
99#define PLL_MISC_CPCON_SHIFT 8 102#define PLL_MISC_CPCON_SHIFT 8
@@ -111,9 +114,9 @@
111 114
112#define PLLE_MISC_READY (1 << 15) 115#define PLLE_MISC_READY (1 << 15)
113 116
114#define PERIPH_CLK_TO_ENB_REG(c) ((c->clk_num / 32) * 4) 117#define PERIPH_CLK_TO_ENB_REG(c) ((c->u.periph.clk_num / 32) * 4)
115#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->clk_num / 32) * 8) 118#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->u.periph.clk_num / 32) * 8)
116#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->clk_num % 32)) 119#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->u.periph.clk_num % 32))
117 120
118#define SUPER_CLK_MUX 0x00 121#define SUPER_CLK_MUX 0x00
119#define SUPER_STATE_SHIFT 28 122#define SUPER_STATE_SHIFT 28
@@ -134,12 +137,42 @@
134#define BUS_CLK_DISABLE (1<<3) 137#define BUS_CLK_DISABLE (1<<3)
135#define BUS_CLK_DIV_MASK 0x3 138#define BUS_CLK_DIV_MASK 0x3
136 139
140#define PMC_CTRL 0x0
141 #define PMC_CTRL_BLINK_ENB (1 << 7)
142
143#define PMC_DPD_PADS_ORIDE 0x1c
144 #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20)
145
146#define PMC_BLINK_TIMER_DATA_ON_SHIFT 0
147#define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff
148#define PMC_BLINK_TIMER_ENB (1 << 15)
149#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
150#define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff
151
137static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE); 152static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
153static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
154
155/*
156 * Some clocks share a register with other clocks. Any clock op that
157 * non-atomically modifies a register used by another clock must lock
158 * clock_register_lock first.
159 */
160static DEFINE_SPINLOCK(clock_register_lock);
161
162/*
163 * Some peripheral clocks share an enable bit, so refcount the enable bits
164 * in registers CLK_ENABLE_L, CLK_ENABLE_H, and CLK_ENABLE_U
165 */
166static int tegra_periph_clk_enable_refcount[3 * 32];
138 167
139#define clk_writel(value, reg) \ 168#define clk_writel(value, reg) \
140 __raw_writel(value, (u32)reg_clk_base + (reg)) 169 __raw_writel(value, (u32)reg_clk_base + (reg))
141#define clk_readl(reg) \ 170#define clk_readl(reg) \
142 __raw_readl((u32)reg_clk_base + (reg)) 171 __raw_readl((u32)reg_clk_base + (reg))
172#define pmc_writel(value, reg) \
173 __raw_writel(value, (u32)reg_pmc_base + (reg))
174#define pmc_readl(reg) \
175 __raw_readl((u32)reg_pmc_base + (reg))
143 176
144unsigned long clk_measure_input_freq(void) 177unsigned long clk_measure_input_freq(void)
145{ 178{
@@ -245,6 +278,18 @@ static struct clk_ops tegra_clk_m_ops = {
245 .disable = tegra2_clk_m_disable, 278 .disable = tegra2_clk_m_disable,
246}; 279};
247 280
281void tegra2_periph_reset_assert(struct clk *c)
282{
283 BUG_ON(!c->ops->reset);
284 c->ops->reset(c, true);
285}
286
287void tegra2_periph_reset_deassert(struct clk *c)
288{
289 BUG_ON(!c->ops->reset);
290 c->ops->reset(c, false);
291}
292
248/* super clock functions */ 293/* super clock functions */
249/* "super clocks" on tegra have two-stage muxes and a clock skipping 294/* "super clocks" on tegra have two-stage muxes and a clock skipping
250 * super divider. We will ignore the clock skipping divider, since we 295 * super divider. We will ignore the clock skipping divider, since we
@@ -303,12 +348,12 @@ static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p)
303 val |= sel->value << shift; 348 val |= sel->value << shift;
304 349
305 if (c->refcnt) 350 if (c->refcnt)
306 clk_enable_locked(p); 351 clk_enable(p);
307 352
308 clk_writel(val, c->reg); 353 clk_writel(val, c->reg);
309 354
310 if (c->refcnt && c->parent) 355 if (c->refcnt && c->parent)
311 clk_disable_locked(c->parent); 356 clk_disable(c->parent);
312 357
313 clk_reparent(c, p); 358 clk_reparent(c, p);
314 return 0; 359 return 0;
@@ -317,11 +362,24 @@ static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p)
317 return -EINVAL; 362 return -EINVAL;
318} 363}
319 364
365/*
366 * Super clocks have "clock skippers" instead of dividers. Dividing using
367 * a clock skipper does not allow the voltage to be scaled down, so instead
368 * adjust the rate of the parent clock. This requires that the parent of a
369 * super clock have no other children, otherwise the rate will change
370 * underneath the other children.
371 */
372static int tegra2_super_clk_set_rate(struct clk *c, unsigned long rate)
373{
374 return clk_set_rate(c->parent, rate);
375}
376
320static struct clk_ops tegra_super_ops = { 377static struct clk_ops tegra_super_ops = {
321 .init = tegra2_super_clk_init, 378 .init = tegra2_super_clk_init,
322 .enable = tegra2_super_clk_enable, 379 .enable = tegra2_super_clk_enable,
323 .disable = tegra2_super_clk_disable, 380 .disable = tegra2_super_clk_disable,
324 .set_parent = tegra2_super_clk_set_parent, 381 .set_parent = tegra2_super_clk_set_parent,
382 .set_rate = tegra2_super_clk_set_rate,
325}; 383};
326 384
327/* virtual cpu clock functions */ 385/* virtual cpu clock functions */
@@ -351,25 +409,36 @@ static void tegra2_cpu_clk_disable(struct clk *c)
351static int tegra2_cpu_clk_set_rate(struct clk *c, unsigned long rate) 409static int tegra2_cpu_clk_set_rate(struct clk *c, unsigned long rate)
352{ 410{
353 int ret; 411 int ret;
354 ret = clk_set_parent_locked(c->parent, c->backup); 412 /*
413 * Take an extra reference to the main pll so it doesn't turn
414 * off when we move the cpu off of it
415 */
416 clk_enable(c->u.cpu.main);
417
418 ret = clk_set_parent(c->parent, c->u.cpu.backup);
355 if (ret) { 419 if (ret) {
356 pr_err("Failed to switch cpu to clock %s\n", c->backup->name); 420 pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.backup->name);
357 return ret; 421 goto out;
358 } 422 }
359 423
360 ret = clk_set_rate_locked(c->main, rate); 424 if (rate == clk_get_rate(c->u.cpu.backup))
425 goto out;
426
427 ret = clk_set_rate(c->u.cpu.main, rate);
361 if (ret) { 428 if (ret) {
362 pr_err("Failed to change cpu pll to %lu\n", rate); 429 pr_err("Failed to change cpu pll to %lu\n", rate);
363 return ret; 430 goto out;
364 } 431 }
365 432
366 ret = clk_set_parent_locked(c->parent, c->main); 433 ret = clk_set_parent(c->parent, c->u.cpu.main);
367 if (ret) { 434 if (ret) {
368 pr_err("Failed to switch cpu to clock %s\n", c->main->name); 435 pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.main->name);
369 return ret; 436 goto out;
370 } 437 }
371 438
372 return 0; 439out:
440 clk_disable(c->u.cpu.main);
441 return ret;
373} 442}
374 443
375static struct clk_ops tegra_cpu_ops = { 444static struct clk_ops tegra_cpu_ops = {
@@ -379,6 +448,20 @@ static struct clk_ops tegra_cpu_ops = {
379 .set_rate = tegra2_cpu_clk_set_rate, 448 .set_rate = tegra2_cpu_clk_set_rate,
380}; 449};
381 450
451/* virtual cop clock functions. Used to acquire the fake 'cop' clock to
452 * reset the COP block (i.e. AVP) */
453static void tegra2_cop_clk_reset(struct clk *c, bool assert)
454{
455 unsigned long reg = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
456
457 pr_debug("%s %s\n", __func__, assert ? "assert" : "deassert");
458 clk_writel(1 << 1, reg);
459}
460
461static struct clk_ops tegra_cop_ops = {
462 .reset = tegra2_cop_clk_reset,
463};
464
382/* bus clock functions */ 465/* bus clock functions */
383static void tegra2_bus_clk_init(struct clk *c) 466static void tegra2_bus_clk_init(struct clk *c)
384{ 467{
@@ -390,24 +473,45 @@ static void tegra2_bus_clk_init(struct clk *c)
390 473
391static int tegra2_bus_clk_enable(struct clk *c) 474static int tegra2_bus_clk_enable(struct clk *c)
392{ 475{
393 u32 val = clk_readl(c->reg); 476 u32 val;
477 unsigned long flags;
478
479 spin_lock_irqsave(&clock_register_lock, flags);
480
481 val = clk_readl(c->reg);
394 val &= ~(BUS_CLK_DISABLE << c->reg_shift); 482 val &= ~(BUS_CLK_DISABLE << c->reg_shift);
395 clk_writel(val, c->reg); 483 clk_writel(val, c->reg);
484
485 spin_unlock_irqrestore(&clock_register_lock, flags);
486
396 return 0; 487 return 0;
397} 488}
398 489
399static void tegra2_bus_clk_disable(struct clk *c) 490static void tegra2_bus_clk_disable(struct clk *c)
400{ 491{
401 u32 val = clk_readl(c->reg); 492 u32 val;
493 unsigned long flags;
494
495 spin_lock_irqsave(&clock_register_lock, flags);
496
497 val = clk_readl(c->reg);
402 val |= BUS_CLK_DISABLE << c->reg_shift; 498 val |= BUS_CLK_DISABLE << c->reg_shift;
403 clk_writel(val, c->reg); 499 clk_writel(val, c->reg);
500
501 spin_unlock_irqrestore(&clock_register_lock, flags);
404} 502}
405 503
406static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate) 504static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate)
407{ 505{
408 u32 val = clk_readl(c->reg); 506 u32 val;
409 unsigned long parent_rate = c->parent->rate; 507 unsigned long parent_rate = clk_get_rate(c->parent);
508 unsigned long flags;
509 int ret = -EINVAL;
410 int i; 510 int i;
511
512 spin_lock_irqsave(&clock_register_lock, flags);
513
514 val = clk_readl(c->reg);
411 for (i = 1; i <= 4; i++) { 515 for (i = 1; i <= 4; i++) {
412 if (rate == parent_rate / i) { 516 if (rate == parent_rate / i) {
413 val &= ~(BUS_CLK_DIV_MASK << c->reg_shift); 517 val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
@@ -415,10 +519,14 @@ static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate)
415 clk_writel(val, c->reg); 519 clk_writel(val, c->reg);
416 c->div = i; 520 c->div = i;
417 c->mul = 1; 521 c->mul = 1;
418 return 0; 522 ret = 0;
523 break;
419 } 524 }
420 } 525 }
421 return -EINVAL; 526
527 spin_unlock_irqrestore(&clock_register_lock, flags);
528
529 return ret;
422} 530}
423 531
424static struct clk_ops tegra_bus_ops = { 532static struct clk_ops tegra_bus_ops = {
@@ -428,24 +536,96 @@ static struct clk_ops tegra_bus_ops = {
428 .set_rate = tegra2_bus_clk_set_rate, 536 .set_rate = tegra2_bus_clk_set_rate,
429}; 537};
430 538
431/* PLL Functions */ 539/* Blink output functions */
432static int tegra2_pll_clk_wait_for_lock(struct clk *c) 540
541static void tegra2_blink_clk_init(struct clk *c)
433{ 542{
434 ktime_t before; 543 u32 val;
435 544
436 before = ktime_get(); 545 val = pmc_readl(PMC_CTRL);
546 c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
547 c->mul = 1;
548 val = pmc_readl(c->reg);
549
550 if (val & PMC_BLINK_TIMER_ENB) {
551 unsigned int on_off;
552
553 on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
554 PMC_BLINK_TIMER_DATA_ON_MASK;
555 val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
556 val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
557 on_off += val;
558 /* each tick in the blink timer is 4 32KHz clocks */
559 c->div = on_off * 4;
560 } else {
561 c->div = 1;
562 }
563}
437 564
438 while (!(clk_readl(c->reg + PLL_BASE) & PLL_BASE_LOCK)) { 565static int tegra2_blink_clk_enable(struct clk *c)
439 if (ktime_us_delta(ktime_get(), before) > 5000) { 566{
440 pr_err("Timed out waiting for lock bit on pll %s", 567 u32 val;
441 c->name); 568
442 return -1; 569 val = pmc_readl(PMC_DPD_PADS_ORIDE);
443 } 570 pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
571
572 val = pmc_readl(PMC_CTRL);
573 pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
574
575 return 0;
576}
577
578static void tegra2_blink_clk_disable(struct clk *c)
579{
580 u32 val;
581
582 val = pmc_readl(PMC_CTRL);
583 pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
584
585 val = pmc_readl(PMC_DPD_PADS_ORIDE);
586 pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
587}
588
589static int tegra2_blink_clk_set_rate(struct clk *c, unsigned long rate)
590{
591 unsigned long parent_rate = clk_get_rate(c->parent);
592 if (rate >= parent_rate) {
593 c->div = 1;
594 pmc_writel(0, c->reg);
595 } else {
596 unsigned int on_off;
597 u32 val;
598
599 on_off = DIV_ROUND_UP(parent_rate / 8, rate);
600 c->div = on_off * 8;
601
602 val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
603 PMC_BLINK_TIMER_DATA_ON_SHIFT;
604 on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
605 on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
606 val |= on_off;
607 val |= PMC_BLINK_TIMER_ENB;
608 pmc_writel(val, c->reg);
444 } 609 }
445 610
446 return 0; 611 return 0;
447} 612}
448 613
614static struct clk_ops tegra_blink_clk_ops = {
615 .init = &tegra2_blink_clk_init,
616 .enable = &tegra2_blink_clk_enable,
617 .disable = &tegra2_blink_clk_disable,
618 .set_rate = &tegra2_blink_clk_set_rate,
619};
620
621/* PLL Functions */
622static int tegra2_pll_clk_wait_for_lock(struct clk *c)
623{
624 udelay(c->u.pll.lock_delay);
625
626 return 0;
627}
628
449static void tegra2_pll_clk_init(struct clk *c) 629static void tegra2_pll_clk_init(struct clk *c)
450{ 630{
451 u32 val = clk_readl(c->reg + PLL_BASE); 631 u32 val = clk_readl(c->reg + PLL_BASE);
@@ -479,10 +659,6 @@ static int tegra2_pll_clk_enable(struct clk *c)
479 val |= PLL_BASE_ENABLE; 659 val |= PLL_BASE_ENABLE;
480 clk_writel(val, c->reg + PLL_BASE); 660 clk_writel(val, c->reg + PLL_BASE);
481 661
482 val = clk_readl(c->reg + PLL_MISC(c));
483 val |= PLL_MISC_LOCK_ENABLE(c);
484 clk_writel(val, c->reg + PLL_MISC(c));
485
486 tegra2_pll_clk_wait_for_lock(c); 662 tegra2_pll_clk_wait_for_lock(c);
487 663
488 return 0; 664 return 0;
@@ -502,13 +678,12 @@ static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate)
502{ 678{
503 u32 val; 679 u32 val;
504 unsigned long input_rate; 680 unsigned long input_rate;
505 const struct clk_pll_table *sel; 681 const struct clk_pll_freq_table *sel;
506 682
507 pr_debug("%s: %s %lu\n", __func__, c->name, rate); 683 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
508 BUG_ON(c->refcnt != 0);
509 684
510 input_rate = c->parent->rate; 685 input_rate = clk_get_rate(c->parent);
511 for (sel = c->pll_table; sel->input_rate != 0; sel++) { 686 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
512 if (sel->input_rate == input_rate && sel->output_rate == rate) { 687 if (sel->input_rate == input_rate && sel->output_rate == rate) {
513 c->mul = sel->n; 688 c->mul = sel->n;
514 c->div = sel->m * sel->p; 689 c->div = sel->m * sel->p;
@@ -620,9 +795,11 @@ static int tegra2_pll_div_clk_enable(struct clk *c)
620{ 795{
621 u32 val; 796 u32 val;
622 u32 new_val; 797 u32 new_val;
798 unsigned long flags;
623 799
624 pr_debug("%s: %s\n", __func__, c->name); 800 pr_debug("%s: %s\n", __func__, c->name);
625 if (c->flags & DIV_U71) { 801 if (c->flags & DIV_U71) {
802 spin_lock_irqsave(&clock_register_lock, flags);
626 val = clk_readl(c->reg); 803 val = clk_readl(c->reg);
627 new_val = val >> c->reg_shift; 804 new_val = val >> c->reg_shift;
628 new_val &= 0xFFFF; 805 new_val &= 0xFFFF;
@@ -632,12 +809,15 @@ static int tegra2_pll_div_clk_enable(struct clk *c)
632 val &= ~(0xFFFF << c->reg_shift); 809 val &= ~(0xFFFF << c->reg_shift);
633 val |= new_val << c->reg_shift; 810 val |= new_val << c->reg_shift;
634 clk_writel(val, c->reg); 811 clk_writel(val, c->reg);
812 spin_unlock_irqrestore(&clock_register_lock, flags);
635 return 0; 813 return 0;
636 } else if (c->flags & DIV_2) { 814 } else if (c->flags & DIV_2) {
637 BUG_ON(!(c->flags & PLLD)); 815 BUG_ON(!(c->flags & PLLD));
816 spin_lock_irqsave(&clock_register_lock, flags);
638 val = clk_readl(c->reg); 817 val = clk_readl(c->reg);
639 val &= ~PLLD_MISC_DIV_RST; 818 val &= ~PLLD_MISC_DIV_RST;
640 clk_writel(val, c->reg); 819 clk_writel(val, c->reg);
820 spin_unlock_irqrestore(&clock_register_lock, flags);
641 return 0; 821 return 0;
642 } 822 }
643 return -EINVAL; 823 return -EINVAL;
@@ -647,9 +827,11 @@ static void tegra2_pll_div_clk_disable(struct clk *c)
647{ 827{
648 u32 val; 828 u32 val;
649 u32 new_val; 829 u32 new_val;
830 unsigned long flags;
650 831
651 pr_debug("%s: %s\n", __func__, c->name); 832 pr_debug("%s: %s\n", __func__, c->name);
652 if (c->flags & DIV_U71) { 833 if (c->flags & DIV_U71) {
834 spin_lock_irqsave(&clock_register_lock, flags);
653 val = clk_readl(c->reg); 835 val = clk_readl(c->reg);
654 new_val = val >> c->reg_shift; 836 new_val = val >> c->reg_shift;
655 new_val &= 0xFFFF; 837 new_val &= 0xFFFF;
@@ -659,11 +841,14 @@ static void tegra2_pll_div_clk_disable(struct clk *c)
659 val &= ~(0xFFFF << c->reg_shift); 841 val &= ~(0xFFFF << c->reg_shift);
660 val |= new_val << c->reg_shift; 842 val |= new_val << c->reg_shift;
661 clk_writel(val, c->reg); 843 clk_writel(val, c->reg);
844 spin_unlock_irqrestore(&clock_register_lock, flags);
662 } else if (c->flags & DIV_2) { 845 } else if (c->flags & DIV_2) {
663 BUG_ON(!(c->flags & PLLD)); 846 BUG_ON(!(c->flags & PLLD));
847 spin_lock_irqsave(&clock_register_lock, flags);
664 val = clk_readl(c->reg); 848 val = clk_readl(c->reg);
665 val |= PLLD_MISC_DIV_RST; 849 val |= PLLD_MISC_DIV_RST;
666 clk_writel(val, c->reg); 850 clk_writel(val, c->reg);
851 spin_unlock_irqrestore(&clock_register_lock, flags);
667 } 852 }
668} 853}
669 854
@@ -672,10 +857,14 @@ static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
672 u32 val; 857 u32 val;
673 u32 new_val; 858 u32 new_val;
674 int divider_u71; 859 int divider_u71;
860 unsigned long parent_rate = clk_get_rate(c->parent);
861 unsigned long flags;
862
675 pr_debug("%s: %s %lu\n", __func__, c->name, rate); 863 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
676 if (c->flags & DIV_U71) { 864 if (c->flags & DIV_U71) {
677 divider_u71 = clk_div71_get_divider(c->parent->rate, rate); 865 divider_u71 = clk_div71_get_divider(parent_rate, rate);
678 if (divider_u71 >= 0) { 866 if (divider_u71 >= 0) {
867 spin_lock_irqsave(&clock_register_lock, flags);
679 val = clk_readl(c->reg); 868 val = clk_readl(c->reg);
680 new_val = val >> c->reg_shift; 869 new_val = val >> c->reg_shift;
681 new_val &= 0xFFFF; 870 new_val &= 0xFFFF;
@@ -689,10 +878,11 @@ static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
689 clk_writel(val, c->reg); 878 clk_writel(val, c->reg);
690 c->div = divider_u71 + 2; 879 c->div = divider_u71 + 2;
691 c->mul = 2; 880 c->mul = 2;
881 spin_unlock_irqrestore(&clock_register_lock, flags);
692 return 0; 882 return 0;
693 } 883 }
694 } else if (c->flags & DIV_2) { 884 } else if (c->flags & DIV_2) {
695 if (c->parent->rate == rate * 2) 885 if (parent_rate == rate * 2)
696 return 0; 886 return 0;
697 } 887 }
698 return -EINVAL; 888 return -EINVAL;
@@ -701,15 +891,16 @@ static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
701static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate) 891static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
702{ 892{
703 int divider; 893 int divider;
894 unsigned long parent_rate = clk_get_rate(c->parent);
704 pr_debug("%s: %s %lu\n", __func__, c->name, rate); 895 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
705 896
706 if (c->flags & DIV_U71) { 897 if (c->flags & DIV_U71) {
707 divider = clk_div71_get_divider(c->parent->rate, rate); 898 divider = clk_div71_get_divider(parent_rate, rate);
708 if (divider < 0) 899 if (divider < 0)
709 return divider; 900 return divider;
710 return c->parent->rate * 2 / (divider + 2); 901 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
711 } else if (c->flags & DIV_2) { 902 } else if (c->flags & DIV_2) {
712 return c->parent->rate / 2; 903 return DIV_ROUND_UP(parent_rate, 2);
713 } 904 }
714 return -EINVAL; 905 return -EINVAL;
715} 906}
@@ -755,9 +946,14 @@ static void tegra2_periph_clk_init(struct clk *c)
755 } 946 }
756 947
757 c->state = ON; 948 c->state = ON;
949
950 if (!c->u.periph.clk_num)
951 return;
952
758 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & 953 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
759 PERIPH_CLK_TO_ENB_BIT(c))) 954 PERIPH_CLK_TO_ENB_BIT(c)))
760 c->state = OFF; 955 c->state = OFF;
956
761 if (!(c->flags & PERIPH_NO_RESET)) 957 if (!(c->flags & PERIPH_NO_RESET))
762 if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) & 958 if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
763 PERIPH_CLK_TO_ENB_BIT(c)) 959 PERIPH_CLK_TO_ENB_BIT(c))
@@ -767,8 +963,20 @@ static void tegra2_periph_clk_init(struct clk *c)
767static int tegra2_periph_clk_enable(struct clk *c) 963static int tegra2_periph_clk_enable(struct clk *c)
768{ 964{
769 u32 val; 965 u32 val;
966 unsigned long flags;
967 int refcount;
770 pr_debug("%s on clock %s\n", __func__, c->name); 968 pr_debug("%s on clock %s\n", __func__, c->name);
771 969
970 if (!c->u.periph.clk_num)
971 return 0;
972
973 spin_lock_irqsave(&clock_register_lock, flags);
974
975 refcount = tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
976
977 if (refcount > 1)
978 goto out;
979
772 clk_writel(PERIPH_CLK_TO_ENB_BIT(c), 980 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
773 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c)); 981 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
774 if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET)) 982 if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET))
@@ -781,34 +989,48 @@ static int tegra2_periph_clk_enable(struct clk *c)
781 val |= 0x3 << 24; 989 val |= 0x3 << 24;
782 clk_writel(val, c->reg); 990 clk_writel(val, c->reg);
783 } 991 }
992
993out:
994 spin_unlock_irqrestore(&clock_register_lock, flags);
995
784 return 0; 996 return 0;
785} 997}
786 998
787static void tegra2_periph_clk_disable(struct clk *c) 999static void tegra2_periph_clk_disable(struct clk *c)
788{ 1000{
1001 unsigned long flags;
1002
789 pr_debug("%s on clock %s\n", __func__, c->name); 1003 pr_debug("%s on clock %s\n", __func__, c->name);
790 1004
791 clk_writel(PERIPH_CLK_TO_ENB_BIT(c), 1005 if (!c->u.periph.clk_num)
792 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c)); 1006 return;
793}
794 1007
795void tegra2_periph_reset_deassert(struct clk *c) 1008 spin_lock_irqsave(&clock_register_lock, flags);
796{ 1009
797 pr_debug("%s on clock %s\n", __func__, c->name); 1010 if (c->refcnt)
798 if (!(c->flags & PERIPH_NO_RESET)) 1011 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
1012
1013 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0)
799 clk_writel(PERIPH_CLK_TO_ENB_BIT(c), 1014 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
800 RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c)); 1015 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1016
1017 spin_unlock_irqrestore(&clock_register_lock, flags);
801} 1018}
802 1019
803void tegra2_periph_reset_assert(struct clk *c) 1020static void tegra2_periph_clk_reset(struct clk *c, bool assert)
804{ 1021{
805 pr_debug("%s on clock %s\n", __func__, c->name); 1022 unsigned long base = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
1023
1024 pr_debug("%s %s on clock %s\n", __func__,
1025 assert ? "assert" : "deassert", c->name);
1026
1027 BUG_ON(!c->u.periph.clk_num);
1028
806 if (!(c->flags & PERIPH_NO_RESET)) 1029 if (!(c->flags & PERIPH_NO_RESET))
807 clk_writel(PERIPH_CLK_TO_ENB_BIT(c), 1030 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
808 RST_DEVICES_SET + PERIPH_CLK_TO_ENB_SET_REG(c)); 1031 base + PERIPH_CLK_TO_ENB_SET_REG(c));
809} 1032}
810 1033
811
812static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p) 1034static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
813{ 1035{
814 u32 val; 1036 u32 val;
@@ -821,12 +1043,12 @@ static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
821 val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT; 1043 val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT;
822 1044
823 if (c->refcnt) 1045 if (c->refcnt)
824 clk_enable_locked(p); 1046 clk_enable(p);
825 1047
826 clk_writel(val, c->reg); 1048 clk_writel(val, c->reg);
827 1049
828 if (c->refcnt && c->parent) 1050 if (c->refcnt && c->parent)
829 clk_disable_locked(c->parent); 1051 clk_disable(c->parent);
830 1052
831 clk_reparent(c, p); 1053 clk_reparent(c, p);
832 return 0; 1054 return 0;
@@ -840,9 +1062,10 @@ static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
840{ 1062{
841 u32 val; 1063 u32 val;
842 int divider; 1064 int divider;
843 pr_debug("%s: %lu\n", __func__, rate); 1065 unsigned long parent_rate = clk_get_rate(c->parent);
1066
844 if (c->flags & DIV_U71) { 1067 if (c->flags & DIV_U71) {
845 divider = clk_div71_get_divider(c->parent->rate, rate); 1068 divider = clk_div71_get_divider(parent_rate, rate);
846 if (divider >= 0) { 1069 if (divider >= 0) {
847 val = clk_readl(c->reg); 1070 val = clk_readl(c->reg);
848 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK; 1071 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
@@ -853,7 +1076,7 @@ static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
853 return 0; 1076 return 0;
854 } 1077 }
855 } else if (c->flags & DIV_U16) { 1078 } else if (c->flags & DIV_U16) {
856 divider = clk_div16_get_divider(c->parent->rate, rate); 1079 divider = clk_div16_get_divider(parent_rate, rate);
857 if (divider >= 0) { 1080 if (divider >= 0) {
858 val = clk_readl(c->reg); 1081 val = clk_readl(c->reg);
859 val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK; 1082 val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
@@ -863,7 +1086,7 @@ static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
863 c->mul = 1; 1086 c->mul = 1;
864 return 0; 1087 return 0;
865 } 1088 }
866 } else if (c->parent->rate <= rate) { 1089 } else if (parent_rate <= rate) {
867 c->div = 1; 1090 c->div = 1;
868 c->mul = 1; 1091 c->mul = 1;
869 return 0; 1092 return 0;
@@ -875,19 +1098,20 @@ static long tegra2_periph_clk_round_rate(struct clk *c,
875 unsigned long rate) 1098 unsigned long rate)
876{ 1099{
877 int divider; 1100 int divider;
1101 unsigned long parent_rate = clk_get_rate(c->parent);
878 pr_debug("%s: %s %lu\n", __func__, c->name, rate); 1102 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
879 1103
880 if (c->flags & DIV_U71) { 1104 if (c->flags & DIV_U71) {
881 divider = clk_div71_get_divider(c->parent->rate, rate); 1105 divider = clk_div71_get_divider(parent_rate, rate);
882 if (divider < 0) 1106 if (divider < 0)
883 return divider; 1107 return divider;
884 1108
885 return c->parent->rate * 2 / (divider + 2); 1109 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
886 } else if (c->flags & DIV_U16) { 1110 } else if (c->flags & DIV_U16) {
887 divider = clk_div16_get_divider(c->parent->rate, rate); 1111 divider = clk_div16_get_divider(parent_rate, rate);
888 if (divider < 0) 1112 if (divider < 0)
889 return divider; 1113 return divider;
890 return c->parent->rate / (divider + 1); 1114 return DIV_ROUND_UP(parent_rate, divider + 1);
891 } 1115 }
892 return -EINVAL; 1116 return -EINVAL;
893} 1117}
@@ -899,6 +1123,71 @@ static struct clk_ops tegra_periph_clk_ops = {
899 .set_parent = &tegra2_periph_clk_set_parent, 1123 .set_parent = &tegra2_periph_clk_set_parent,
900 .set_rate = &tegra2_periph_clk_set_rate, 1124 .set_rate = &tegra2_periph_clk_set_rate,
901 .round_rate = &tegra2_periph_clk_round_rate, 1125 .round_rate = &tegra2_periph_clk_round_rate,
1126 .reset = &tegra2_periph_clk_reset,
1127};
1128
1129/* The SDMMC controllers have extra bits in the clock source register that
1130 * adjust the delay between the clock and data to compenstate for delays
1131 * on the PCB. */
1132void tegra2_sdmmc_tap_delay(struct clk *c, int delay)
1133{
1134 u32 reg;
1135
1136 delay = clamp(delay, 0, 15);
1137 reg = clk_readl(c->reg);
1138 reg &= ~SDMMC_CLK_INT_FB_DLY_MASK;
1139 reg |= SDMMC_CLK_INT_FB_SEL;
1140 reg |= delay << SDMMC_CLK_INT_FB_DLY_SHIFT;
1141 clk_writel(reg, c->reg);
1142}
1143
1144/* External memory controller clock ops */
1145static void tegra2_emc_clk_init(struct clk *c)
1146{
1147 tegra2_periph_clk_init(c);
1148 c->max_rate = clk_get_rate_locked(c);
1149}
1150
1151static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate)
1152{
1153 long new_rate = rate;
1154
1155 new_rate = tegra_emc_round_rate(new_rate);
1156 if (new_rate < 0)
1157 return c->max_rate;
1158
1159 BUG_ON(new_rate != tegra2_periph_clk_round_rate(c, new_rate));
1160
1161 return new_rate;
1162}
1163
1164static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate)
1165{
1166 int ret;
1167 /*
1168 * The Tegra2 memory controller has an interlock with the clock
1169 * block that allows memory shadowed registers to be updated,
1170 * and then transfer them to the main registers at the same
1171 * time as the clock update without glitches.
1172 */
1173 ret = tegra_emc_set_rate(rate);
1174 if (ret < 0)
1175 return ret;
1176
1177 ret = tegra2_periph_clk_set_rate(c, rate);
1178 udelay(1);
1179
1180 return ret;
1181}
1182
1183static struct clk_ops tegra_emc_clk_ops = {
1184 .init = &tegra2_emc_clk_init,
1185 .enable = &tegra2_periph_clk_enable,
1186 .disable = &tegra2_periph_clk_disable,
1187 .set_parent = &tegra2_periph_clk_set_parent,
1188 .set_rate = &tegra2_emc_clk_set_rate,
1189 .round_rate = &tegra2_emc_clk_round_rate,
1190 .reset = &tegra2_periph_clk_reset,
902}; 1191};
903 1192
904/* Clock doubler ops */ 1193/* Clock doubler ops */
@@ -907,6 +1196,10 @@ static void tegra2_clk_double_init(struct clk *c)
907 c->mul = 2; 1196 c->mul = 2;
908 c->div = 1; 1197 c->div = 1;
909 c->state = ON; 1198 c->state = ON;
1199
1200 if (!c->u.periph.clk_num)
1201 return;
1202
910 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & 1203 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
911 PERIPH_CLK_TO_ENB_BIT(c))) 1204 PERIPH_CLK_TO_ENB_BIT(c)))
912 c->state = OFF; 1205 c->state = OFF;
@@ -914,7 +1207,7 @@ static void tegra2_clk_double_init(struct clk *c)
914 1207
915static int tegra2_clk_double_set_rate(struct clk *c, unsigned long rate) 1208static int tegra2_clk_double_set_rate(struct clk *c, unsigned long rate)
916{ 1209{
917 if (rate != 2 * c->parent->rate) 1210 if (rate != 2 * clk_get_rate(c->parent))
918 return -EINVAL; 1211 return -EINVAL;
919 c->mul = 2; 1212 c->mul = 2;
920 c->div = 1; 1213 c->div = 1;
@@ -928,6 +1221,7 @@ static struct clk_ops tegra_clk_double_ops = {
928 .set_rate = &tegra2_clk_double_set_rate, 1221 .set_rate = &tegra2_clk_double_set_rate,
929}; 1222};
930 1223
1224/* Audio sync clock ops */
931static void tegra2_audio_sync_clk_init(struct clk *c) 1225static void tegra2_audio_sync_clk_init(struct clk *c)
932{ 1226{
933 int source; 1227 int source;
@@ -964,12 +1258,12 @@ static int tegra2_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
964 val |= sel->value; 1258 val |= sel->value;
965 1259
966 if (c->refcnt) 1260 if (c->refcnt)
967 clk_enable_locked(p); 1261 clk_enable(p);
968 1262
969 clk_writel(val, c->reg); 1263 clk_writel(val, c->reg);
970 1264
971 if (c->refcnt && c->parent) 1265 if (c->refcnt && c->parent)
972 clk_disable_locked(c->parent); 1266 clk_disable(c->parent);
973 1267
974 clk_reparent(c, p); 1268 clk_reparent(c, p);
975 return 0; 1269 return 0;
@@ -979,33 +1273,153 @@ static int tegra2_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
979 return -EINVAL; 1273 return -EINVAL;
980} 1274}
981 1275
982static int tegra2_audio_sync_clk_set_rate(struct clk *c, unsigned long rate)
983{
984 unsigned long parent_rate;
985 if (!c->parent) {
986 pr_err("%s: clock has no parent\n", __func__);
987 return -EINVAL;
988 }
989 parent_rate = c->parent->rate;
990 if (rate != parent_rate) {
991 pr_err("%s: %s/%ld differs from parent %s/%ld\n",
992 __func__,
993 c->name, rate,
994 c->parent->name, parent_rate);
995 return -EINVAL;
996 }
997 c->rate = parent_rate;
998 return 0;
999}
1000
1001static struct clk_ops tegra_audio_sync_clk_ops = { 1276static struct clk_ops tegra_audio_sync_clk_ops = {
1002 .init = tegra2_audio_sync_clk_init, 1277 .init = tegra2_audio_sync_clk_init,
1003 .enable = tegra2_audio_sync_clk_enable, 1278 .enable = tegra2_audio_sync_clk_enable,
1004 .disable = tegra2_audio_sync_clk_disable, 1279 .disable = tegra2_audio_sync_clk_disable,
1005 .set_rate = tegra2_audio_sync_clk_set_rate,
1006 .set_parent = tegra2_audio_sync_clk_set_parent, 1280 .set_parent = tegra2_audio_sync_clk_set_parent,
1007}; 1281};
1008 1282
1283/* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */
1284
1285static void tegra2_cdev_clk_init(struct clk *c)
1286{
1287 /* We could un-tristate the cdev1 or cdev2 pingroup here; this is
1288 * currently done in the pinmux code. */
1289 c->state = ON;
1290
1291 BUG_ON(!c->u.periph.clk_num);
1292
1293 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1294 PERIPH_CLK_TO_ENB_BIT(c)))
1295 c->state = OFF;
1296}
1297
1298static int tegra2_cdev_clk_enable(struct clk *c)
1299{
1300 BUG_ON(!c->u.periph.clk_num);
1301
1302 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1303 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
1304 return 0;
1305}
1306
1307static void tegra2_cdev_clk_disable(struct clk *c)
1308{
1309 BUG_ON(!c->u.periph.clk_num);
1310
1311 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1312 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1313}
1314
1315static struct clk_ops tegra_cdev_clk_ops = {
1316 .init = &tegra2_cdev_clk_init,
1317 .enable = &tegra2_cdev_clk_enable,
1318 .disable = &tegra2_cdev_clk_disable,
1319};
1320
1321/* shared bus ops */
1322/*
1323 * Some clocks may have multiple downstream users that need to request a
1324 * higher clock rate. Shared bus clocks provide a unique shared_bus_user
1325 * clock to each user. The frequency of the bus is set to the highest
1326 * enabled shared_bus_user clock, with a minimum value set by the
1327 * shared bus.
1328 */
1329static int tegra_clk_shared_bus_update(struct clk *bus)
1330{
1331 struct clk *c;
1332 unsigned long rate = bus->min_rate;
1333
1334 list_for_each_entry(c, &bus->shared_bus_list, u.shared_bus_user.node)
1335 if (c->u.shared_bus_user.enabled)
1336 rate = max(c->u.shared_bus_user.rate, rate);
1337
1338 if (rate == clk_get_rate_locked(bus))
1339 return 0;
1340
1341 return clk_set_rate_locked(bus, rate);
1342};
1343
1344static void tegra_clk_shared_bus_init(struct clk *c)
1345{
1346 unsigned long flags;
1347
1348 c->max_rate = c->parent->max_rate;
1349 c->u.shared_bus_user.rate = c->parent->max_rate;
1350 c->state = OFF;
1351 c->set = true;
1352
1353 spin_lock_irqsave(&c->parent->spinlock, flags);
1354
1355 list_add_tail(&c->u.shared_bus_user.node,
1356 &c->parent->shared_bus_list);
1357
1358 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1359}
1360
1361static int tegra_clk_shared_bus_set_rate(struct clk *c, unsigned long rate)
1362{
1363 unsigned long flags;
1364 int ret;
1365
1366 rate = clk_round_rate(c->parent, rate);
1367 if (rate < 0)
1368 return rate;
1369
1370 spin_lock_irqsave(&c->parent->spinlock, flags);
1371
1372 c->u.shared_bus_user.rate = rate;
1373 ret = tegra_clk_shared_bus_update(c->parent);
1374
1375 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1376
1377 return ret;
1378}
1379
1380static long tegra_clk_shared_bus_round_rate(struct clk *c, unsigned long rate)
1381{
1382 return clk_round_rate(c->parent, rate);
1383}
1384
1385static int tegra_clk_shared_bus_enable(struct clk *c)
1386{
1387 unsigned long flags;
1388 int ret;
1389
1390 spin_lock_irqsave(&c->parent->spinlock, flags);
1391
1392 c->u.shared_bus_user.enabled = true;
1393 ret = tegra_clk_shared_bus_update(c->parent);
1394
1395 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1396
1397 return ret;
1398}
1399
1400static void tegra_clk_shared_bus_disable(struct clk *c)
1401{
1402 unsigned long flags;
1403 int ret;
1404
1405 spin_lock_irqsave(&c->parent->spinlock, flags);
1406
1407 c->u.shared_bus_user.enabled = false;
1408 ret = tegra_clk_shared_bus_update(c->parent);
1409 WARN_ON_ONCE(ret);
1410
1411 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1412}
1413
1414static struct clk_ops tegra_clk_shared_bus_ops = {
1415 .init = tegra_clk_shared_bus_init,
1416 .enable = tegra_clk_shared_bus_enable,
1417 .disable = tegra_clk_shared_bus_disable,
1418 .set_rate = tegra_clk_shared_bus_set_rate,
1419 .round_rate = tegra_clk_shared_bus_round_rate,
1420};
1421
1422
1009/* Clock definitions */ 1423/* Clock definitions */
1010static struct clk tegra_clk_32k = { 1424static struct clk tegra_clk_32k = {
1011 .name = "clk_32k", 1425 .name = "clk_32k",
@@ -1014,7 +1428,7 @@ static struct clk tegra_clk_32k = {
1014 .max_rate = 32768, 1428 .max_rate = 32768,
1015}; 1429};
1016 1430
1017static struct clk_pll_table tegra_pll_s_table[] = { 1431static struct clk_pll_freq_table tegra_pll_s_freq_table[] = {
1018 {32768, 12000000, 366, 1, 1, 0}, 1432 {32768, 12000000, 366, 1, 1, 0},
1019 {32768, 13000000, 397, 1, 1, 0}, 1433 {32768, 13000000, 397, 1, 1, 0},
1020 {32768, 19200000, 586, 1, 1, 0}, 1434 {32768, 19200000, 586, 1, 1, 0},
@@ -1026,16 +1440,19 @@ static struct clk tegra_pll_s = {
1026 .name = "pll_s", 1440 .name = "pll_s",
1027 .flags = PLL_ALT_MISC_REG, 1441 .flags = PLL_ALT_MISC_REG,
1028 .ops = &tegra_pll_ops, 1442 .ops = &tegra_pll_ops,
1029 .reg = 0xf0,
1030 .input_min = 32768,
1031 .input_max = 32768,
1032 .parent = &tegra_clk_32k, 1443 .parent = &tegra_clk_32k,
1033 .cf_min = 0, /* FIXME */
1034 .cf_max = 0, /* FIXME */
1035 .vco_min = 12000000,
1036 .vco_max = 26000000,
1037 .pll_table = tegra_pll_s_table,
1038 .max_rate = 26000000, 1444 .max_rate = 26000000,
1445 .reg = 0xf0,
1446 .u.pll = {
1447 .input_min = 32768,
1448 .input_max = 32768,
1449 .cf_min = 0, /* FIXME */
1450 .cf_max = 0, /* FIXME */
1451 .vco_min = 12000000,
1452 .vco_max = 26000000,
1453 .freq_table = tegra_pll_s_freq_table,
1454 .lock_delay = 300,
1455 },
1039}; 1456};
1040 1457
1041static struct clk_mux_sel tegra_clk_m_sel[] = { 1458static struct clk_mux_sel tegra_clk_m_sel[] = {
@@ -1043,18 +1460,18 @@ static struct clk_mux_sel tegra_clk_m_sel[] = {
1043 { .input = &tegra_pll_s, .value = 1}, 1460 { .input = &tegra_pll_s, .value = 1},
1044 { 0, 0}, 1461 { 0, 0},
1045}; 1462};
1463
1046static struct clk tegra_clk_m = { 1464static struct clk tegra_clk_m = {
1047 .name = "clk_m", 1465 .name = "clk_m",
1048 .flags = ENABLE_ON_INIT, 1466 .flags = ENABLE_ON_INIT,
1049 .ops = &tegra_clk_m_ops, 1467 .ops = &tegra_clk_m_ops,
1050 .inputs = tegra_clk_m_sel, 1468 .inputs = tegra_clk_m_sel,
1051 .reg = 0x1fc, 1469 .reg = 0x1fc,
1052 .reg_mask = (1<<28),
1053 .reg_shift = 28, 1470 .reg_shift = 28,
1054 .max_rate = 26000000, 1471 .max_rate = 26000000,
1055}; 1472};
1056 1473
1057static struct clk_pll_table tegra_pll_c_table[] = { 1474static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
1058 { 0, 0, 0, 0, 0, 0 }, 1475 { 0, 0, 0, 0, 0, 0 },
1059}; 1476};
1060 1477
@@ -1063,15 +1480,18 @@ static struct clk tegra_pll_c = {
1063 .flags = PLL_HAS_CPCON, 1480 .flags = PLL_HAS_CPCON,
1064 .ops = &tegra_pll_ops, 1481 .ops = &tegra_pll_ops,
1065 .reg = 0x80, 1482 .reg = 0x80,
1066 .input_min = 2000000,
1067 .input_max = 31000000,
1068 .parent = &tegra_clk_m, 1483 .parent = &tegra_clk_m,
1069 .cf_min = 1000000,
1070 .cf_max = 6000000,
1071 .vco_min = 20000000,
1072 .vco_max = 1400000000,
1073 .pll_table = tegra_pll_c_table,
1074 .max_rate = 600000000, 1484 .max_rate = 600000000,
1485 .u.pll = {
1486 .input_min = 2000000,
1487 .input_max = 31000000,
1488 .cf_min = 1000000,
1489 .cf_max = 6000000,
1490 .vco_min = 20000000,
1491 .vco_max = 1400000000,
1492 .freq_table = tegra_pll_c_freq_table,
1493 .lock_delay = 300,
1494 },
1075}; 1495};
1076 1496
1077static struct clk tegra_pll_c_out1 = { 1497static struct clk tegra_pll_c_out1 = {
@@ -1084,7 +1504,7 @@ static struct clk tegra_pll_c_out1 = {
1084 .max_rate = 600000000, 1504 .max_rate = 600000000,
1085}; 1505};
1086 1506
1087static struct clk_pll_table tegra_pll_m_table[] = { 1507static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
1088 { 12000000, 666000000, 666, 12, 1, 8}, 1508 { 12000000, 666000000, 666, 12, 1, 8},
1089 { 13000000, 666000000, 666, 13, 1, 8}, 1509 { 13000000, 666000000, 666, 13, 1, 8},
1090 { 19200000, 666000000, 555, 16, 1, 8}, 1510 { 19200000, 666000000, 555, 16, 1, 8},
@@ -1101,15 +1521,18 @@ static struct clk tegra_pll_m = {
1101 .flags = PLL_HAS_CPCON, 1521 .flags = PLL_HAS_CPCON,
1102 .ops = &tegra_pll_ops, 1522 .ops = &tegra_pll_ops,
1103 .reg = 0x90, 1523 .reg = 0x90,
1104 .input_min = 2000000,
1105 .input_max = 31000000,
1106 .parent = &tegra_clk_m, 1524 .parent = &tegra_clk_m,
1107 .cf_min = 1000000,
1108 .cf_max = 6000000,
1109 .vco_min = 20000000,
1110 .vco_max = 1200000000,
1111 .pll_table = tegra_pll_m_table,
1112 .max_rate = 800000000, 1525 .max_rate = 800000000,
1526 .u.pll = {
1527 .input_min = 2000000,
1528 .input_max = 31000000,
1529 .cf_min = 1000000,
1530 .cf_max = 6000000,
1531 .vco_min = 20000000,
1532 .vco_max = 1200000000,
1533 .freq_table = tegra_pll_m_freq_table,
1534 .lock_delay = 300,
1535 },
1113}; 1536};
1114 1537
1115static struct clk tegra_pll_m_out1 = { 1538static struct clk tegra_pll_m_out1 = {
@@ -1122,7 +1545,7 @@ static struct clk tegra_pll_m_out1 = {
1122 .max_rate = 600000000, 1545 .max_rate = 600000000,
1123}; 1546};
1124 1547
1125static struct clk_pll_table tegra_pll_p_table[] = { 1548static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
1126 { 12000000, 216000000, 432, 12, 2, 8}, 1549 { 12000000, 216000000, 432, 12, 2, 8},
1127 { 13000000, 216000000, 432, 13, 2, 8}, 1550 { 13000000, 216000000, 432, 13, 2, 8},
1128 { 19200000, 216000000, 90, 4, 2, 1}, 1551 { 19200000, 216000000, 90, 4, 2, 1},
@@ -1139,15 +1562,18 @@ static struct clk tegra_pll_p = {
1139 .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON, 1562 .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
1140 .ops = &tegra_pll_ops, 1563 .ops = &tegra_pll_ops,
1141 .reg = 0xa0, 1564 .reg = 0xa0,
1142 .input_min = 2000000,
1143 .input_max = 31000000,
1144 .parent = &tegra_clk_m, 1565 .parent = &tegra_clk_m,
1145 .cf_min = 1000000,
1146 .cf_max = 6000000,
1147 .vco_min = 20000000,
1148 .vco_max = 1400000000,
1149 .pll_table = tegra_pll_p_table,
1150 .max_rate = 432000000, 1566 .max_rate = 432000000,
1567 .u.pll = {
1568 .input_min = 2000000,
1569 .input_max = 31000000,
1570 .cf_min = 1000000,
1571 .cf_max = 6000000,
1572 .vco_min = 20000000,
1573 .vco_max = 1400000000,
1574 .freq_table = tegra_pll_p_freq_table,
1575 .lock_delay = 300,
1576 },
1151}; 1577};
1152 1578
1153static struct clk tegra_pll_p_out1 = { 1579static struct clk tegra_pll_p_out1 = {
@@ -1190,11 +1616,9 @@ static struct clk tegra_pll_p_out4 = {
1190 .max_rate = 432000000, 1616 .max_rate = 432000000,
1191}; 1617};
1192 1618
1193static struct clk_pll_table tegra_pll_a_table[] = { 1619static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
1194 { 28800000, 56448000, 49, 25, 1, 1}, 1620 { 28800000, 56448000, 49, 25, 1, 1},
1195 { 28800000, 73728000, 64, 25, 1, 1}, 1621 { 28800000, 73728000, 64, 25, 1, 1},
1196 { 28800000, 11289600, 49, 25, 1, 1},
1197 { 28800000, 12288000, 64, 25, 1, 1},
1198 { 28800000, 24000000, 5, 6, 1, 1}, 1622 { 28800000, 24000000, 5, 6, 1, 1},
1199 { 0, 0, 0, 0, 0, 0 }, 1623 { 0, 0, 0, 0, 0, 0 },
1200}; 1624};
@@ -1204,15 +1628,18 @@ static struct clk tegra_pll_a = {
1204 .flags = PLL_HAS_CPCON, 1628 .flags = PLL_HAS_CPCON,
1205 .ops = &tegra_pll_ops, 1629 .ops = &tegra_pll_ops,
1206 .reg = 0xb0, 1630 .reg = 0xb0,
1207 .input_min = 2000000,
1208 .input_max = 31000000,
1209 .parent = &tegra_pll_p_out1, 1631 .parent = &tegra_pll_p_out1,
1210 .cf_min = 1000000, 1632 .max_rate = 73728000,
1211 .cf_max = 6000000, 1633 .u.pll = {
1212 .vco_min = 20000000, 1634 .input_min = 2000000,
1213 .vco_max = 1400000000, 1635 .input_max = 31000000,
1214 .pll_table = tegra_pll_a_table, 1636 .cf_min = 1000000,
1215 .max_rate = 56448000, 1637 .cf_max = 6000000,
1638 .vco_min = 20000000,
1639 .vco_max = 1400000000,
1640 .freq_table = tegra_pll_a_freq_table,
1641 .lock_delay = 300,
1642 },
1216}; 1643};
1217 1644
1218static struct clk tegra_pll_a_out0 = { 1645static struct clk tegra_pll_a_out0 = {
@@ -1222,14 +1649,25 @@ static struct clk tegra_pll_a_out0 = {
1222 .parent = &tegra_pll_a, 1649 .parent = &tegra_pll_a,
1223 .reg = 0xb4, 1650 .reg = 0xb4,
1224 .reg_shift = 0, 1651 .reg_shift = 0,
1225 .max_rate = 56448000, 1652 .max_rate = 73728000,
1226}; 1653};
1227 1654
1228static struct clk_pll_table tegra_pll_d_table[] = { 1655static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
1656 { 12000000, 216000000, 216, 12, 1, 4},
1657 { 13000000, 216000000, 216, 13, 1, 4},
1658 { 19200000, 216000000, 135, 12, 1, 3},
1659 { 26000000, 216000000, 216, 26, 1, 4},
1660
1661 { 12000000, 594000000, 594, 12, 1, 8},
1662 { 13000000, 594000000, 594, 13, 1, 8},
1663 { 19200000, 594000000, 495, 16, 1, 8},
1664 { 26000000, 594000000, 594, 26, 1, 8},
1665
1229 { 12000000, 1000000000, 1000, 12, 1, 12}, 1666 { 12000000, 1000000000, 1000, 12, 1, 12},
1230 { 13000000, 1000000000, 1000, 13, 1, 12}, 1667 { 13000000, 1000000000, 1000, 13, 1, 12},
1231 { 19200000, 1000000000, 625, 12, 1, 8}, 1668 { 19200000, 1000000000, 625, 12, 1, 8},
1232 { 26000000, 1000000000, 1000, 26, 1, 12}, 1669 { 26000000, 1000000000, 1000, 26, 1, 12},
1670
1233 { 0, 0, 0, 0, 0, 0 }, 1671 { 0, 0, 0, 0, 0, 0 },
1234}; 1672};
1235 1673
@@ -1238,15 +1676,18 @@ static struct clk tegra_pll_d = {
1238 .flags = PLL_HAS_CPCON | PLLD, 1676 .flags = PLL_HAS_CPCON | PLLD,
1239 .ops = &tegra_pll_ops, 1677 .ops = &tegra_pll_ops,
1240 .reg = 0xd0, 1678 .reg = 0xd0,
1241 .input_min = 2000000,
1242 .input_max = 40000000,
1243 .parent = &tegra_clk_m, 1679 .parent = &tegra_clk_m,
1244 .cf_min = 1000000,
1245 .cf_max = 6000000,
1246 .vco_min = 40000000,
1247 .vco_max = 1000000000,
1248 .pll_table = tegra_pll_d_table,
1249 .max_rate = 1000000000, 1680 .max_rate = 1000000000,
1681 .u.pll = {
1682 .input_min = 2000000,
1683 .input_max = 40000000,
1684 .cf_min = 1000000,
1685 .cf_max = 6000000,
1686 .vco_min = 40000000,
1687 .vco_max = 1000000000,
1688 .freq_table = tegra_pll_d_freq_table,
1689 .lock_delay = 1000,
1690 },
1250}; 1691};
1251 1692
1252static struct clk tegra_pll_d_out0 = { 1693static struct clk tegra_pll_d_out0 = {
@@ -1257,7 +1698,7 @@ static struct clk tegra_pll_d_out0 = {
1257 .max_rate = 500000000, 1698 .max_rate = 500000000,
1258}; 1699};
1259 1700
1260static struct clk_pll_table tegra_pll_u_table[] = { 1701static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
1261 { 12000000, 480000000, 960, 12, 2, 0}, 1702 { 12000000, 480000000, 960, 12, 2, 0},
1262 { 13000000, 480000000, 960, 13, 2, 0}, 1703 { 13000000, 480000000, 960, 13, 2, 0},
1263 { 19200000, 480000000, 200, 4, 2, 0}, 1704 { 19200000, 480000000, 200, 4, 2, 0},
@@ -1270,18 +1711,21 @@ static struct clk tegra_pll_u = {
1270 .flags = PLLU, 1711 .flags = PLLU,
1271 .ops = &tegra_pll_ops, 1712 .ops = &tegra_pll_ops,
1272 .reg = 0xc0, 1713 .reg = 0xc0,
1273 .input_min = 2000000,
1274 .input_max = 40000000,
1275 .parent = &tegra_clk_m, 1714 .parent = &tegra_clk_m,
1276 .cf_min = 1000000,
1277 .cf_max = 6000000,
1278 .vco_min = 480000000,
1279 .vco_max = 960000000,
1280 .pll_table = tegra_pll_u_table,
1281 .max_rate = 480000000, 1715 .max_rate = 480000000,
1282}; 1716 .u.pll = {
1283 1717 .input_min = 2000000,
1284static struct clk_pll_table tegra_pll_x_table[] = { 1718 .input_max = 40000000,
1719 .cf_min = 1000000,
1720 .cf_max = 6000000,
1721 .vco_min = 480000000,
1722 .vco_max = 960000000,
1723 .freq_table = tegra_pll_u_freq_table,
1724 .lock_delay = 1000,
1725 },
1726};
1727
1728static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
1285 /* 1 GHz */ 1729 /* 1 GHz */
1286 { 12000000, 1000000000, 1000, 12, 1, 12}, 1730 { 12000000, 1000000000, 1000, 12, 1, 12},
1287 { 13000000, 1000000000, 1000, 13, 1, 12}, 1731 { 13000000, 1000000000, 1000, 13, 1, 12},
@@ -1307,10 +1751,10 @@ static struct clk_pll_table tegra_pll_x_table[] = {
1307 { 26000000, 760000000, 760, 26, 1, 12}, 1751 { 26000000, 760000000, 760, 26, 1, 12},
1308 1752
1309 /* 608 MHz */ 1753 /* 608 MHz */
1310 { 12000000, 608000000, 760, 12, 1, 12}, 1754 { 12000000, 608000000, 608, 12, 1, 12},
1311 { 13000000, 608000000, 760, 13, 1, 12}, 1755 { 13000000, 608000000, 608, 13, 1, 12},
1312 { 19200000, 608000000, 380, 12, 1, 8}, 1756 { 19200000, 608000000, 380, 12, 1, 8},
1313 { 26000000, 608000000, 760, 26, 1, 12}, 1757 { 26000000, 608000000, 608, 26, 1, 12},
1314 1758
1315 /* 456 MHz */ 1759 /* 456 MHz */
1316 { 12000000, 456000000, 456, 12, 1, 12}, 1760 { 12000000, 456000000, 456, 12, 1, 12},
@@ -1332,18 +1776,21 @@ static struct clk tegra_pll_x = {
1332 .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG, 1776 .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG,
1333 .ops = &tegra_pllx_ops, 1777 .ops = &tegra_pllx_ops,
1334 .reg = 0xe0, 1778 .reg = 0xe0,
1335 .input_min = 2000000,
1336 .input_max = 31000000,
1337 .parent = &tegra_clk_m, 1779 .parent = &tegra_clk_m,
1338 .cf_min = 1000000,
1339 .cf_max = 6000000,
1340 .vco_min = 20000000,
1341 .vco_max = 1200000000,
1342 .pll_table = tegra_pll_x_table,
1343 .max_rate = 1000000000, 1780 .max_rate = 1000000000,
1344}; 1781 .u.pll = {
1345 1782 .input_min = 2000000,
1346static struct clk_pll_table tegra_pll_e_table[] = { 1783 .input_max = 31000000,
1784 .cf_min = 1000000,
1785 .cf_max = 6000000,
1786 .vco_min = 20000000,
1787 .vco_max = 1200000000,
1788 .freq_table = tegra_pll_x_freq_table,
1789 .lock_delay = 300,
1790 },
1791};
1792
1793static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
1347 { 12000000, 100000000, 200, 24, 1, 0 }, 1794 { 12000000, 100000000, 200, 24, 1, 0 },
1348 { 0, 0, 0, 0, 0, 0 }, 1795 { 0, 0, 0, 0, 0, 0 },
1349}; 1796};
@@ -1352,23 +1799,49 @@ static struct clk tegra_pll_e = {
1352 .name = "pll_e", 1799 .name = "pll_e",
1353 .flags = PLL_ALT_MISC_REG, 1800 .flags = PLL_ALT_MISC_REG,
1354 .ops = &tegra_plle_ops, 1801 .ops = &tegra_plle_ops,
1355 .input_min = 12000000,
1356 .input_max = 12000000,
1357 .max_rate = 100000000,
1358 .parent = &tegra_clk_m, 1802 .parent = &tegra_clk_m,
1359 .reg = 0xe8, 1803 .reg = 0xe8,
1360 .pll_table = tegra_pll_e_table, 1804 .max_rate = 100000000,
1805 .u.pll = {
1806 .input_min = 12000000,
1807 .input_max = 12000000,
1808 .freq_table = tegra_pll_e_freq_table,
1809 },
1361}; 1810};
1362 1811
1363static struct clk tegra_clk_d = { 1812static struct clk tegra_clk_d = {
1364 .name = "clk_d", 1813 .name = "clk_d",
1365 .flags = PERIPH_NO_RESET, 1814 .flags = PERIPH_NO_RESET,
1366 .ops = &tegra_clk_double_ops, 1815 .ops = &tegra_clk_double_ops,
1367 .clk_num = 90,
1368 .reg = 0x34, 1816 .reg = 0x34,
1369 .reg_shift = 12, 1817 .reg_shift = 12,
1370 .parent = &tegra_clk_m, 1818 .parent = &tegra_clk_m,
1371 .max_rate = 52000000, 1819 .max_rate = 52000000,
1820 .u.periph = {
1821 .clk_num = 90,
1822 },
1823};
1824
1825/* dap_mclk1, belongs to the cdev1 pingroup. */
1826static struct clk tegra_clk_cdev1 = {
1827 .name = "cdev1",
1828 .ops = &tegra_cdev_clk_ops,
1829 .rate = 26000000,
1830 .max_rate = 26000000,
1831 .u.periph = {
1832 .clk_num = 94,
1833 },
1834};
1835
1836/* dap_mclk2, belongs to the cdev2 pingroup. */
1837static struct clk tegra_clk_cdev2 = {
1838 .name = "cdev2",
1839 .ops = &tegra_cdev_clk_ops,
1840 .rate = 26000000,
1841 .max_rate = 26000000,
1842 .u.periph = {
1843 .clk_num = 93,
1844 },
1372}; 1845};
1373 1846
1374/* initialized before peripheral clocks */ 1847/* initialized before peripheral clocks */
@@ -1394,7 +1867,7 @@ static struct clk tegra_clk_audio = {
1394 .name = "audio", 1867 .name = "audio",
1395 .inputs = mux_audio_sync_clk, 1868 .inputs = mux_audio_sync_clk,
1396 .reg = 0x38, 1869 .reg = 0x38,
1397 .max_rate = 24000000, 1870 .max_rate = 73728000,
1398 .ops = &tegra_audio_sync_clk_ops 1871 .ops = &tegra_audio_sync_clk_ops
1399}; 1872};
1400 1873
@@ -1403,10 +1876,12 @@ static struct clk tegra_clk_audio_2x = {
1403 .flags = PERIPH_NO_RESET, 1876 .flags = PERIPH_NO_RESET,
1404 .max_rate = 48000000, 1877 .max_rate = 48000000,
1405 .ops = &tegra_clk_double_ops, 1878 .ops = &tegra_clk_double_ops,
1406 .clk_num = 89,
1407 .reg = 0x34, 1879 .reg = 0x34,
1408 .reg_shift = 8, 1880 .reg_shift = 8,
1409 .parent = &tegra_clk_audio, 1881 .parent = &tegra_clk_audio,
1882 .u.periph = {
1883 .clk_num = 89,
1884 },
1410}; 1885};
1411 1886
1412struct clk_lookup tegra_audio_clk_lookups[] = { 1887struct clk_lookup tegra_audio_clk_lookups[] = {
@@ -1478,17 +1953,26 @@ static struct clk tegra_clk_sclk = {
1478 .inputs = mux_sclk, 1953 .inputs = mux_sclk,
1479 .reg = 0x28, 1954 .reg = 0x28,
1480 .ops = &tegra_super_ops, 1955 .ops = &tegra_super_ops,
1481 .max_rate = 600000000, 1956 .max_rate = 240000000,
1957 .min_rate = 120000000,
1482}; 1958};
1483 1959
1484static struct clk tegra_clk_virtual_cpu = { 1960static struct clk tegra_clk_virtual_cpu = {
1485 .name = "cpu", 1961 .name = "cpu",
1486 .parent = &tegra_clk_cclk, 1962 .parent = &tegra_clk_cclk,
1487 .main = &tegra_pll_x,
1488 .backup = &tegra_clk_m,
1489 .ops = &tegra_cpu_ops, 1963 .ops = &tegra_cpu_ops,
1490 .max_rate = 1000000000, 1964 .max_rate = 1000000000,
1491 .dvfs = &tegra_dvfs_virtual_cpu_dvfs, 1965 .u.cpu = {
1966 .main = &tegra_pll_x,
1967 .backup = &tegra_pll_p,
1968 },
1969};
1970
1971static struct clk tegra_clk_cop = {
1972 .name = "cop",
1973 .parent = &tegra_clk_sclk,
1974 .ops = &tegra_cop_ops,
1975 .max_rate = 240000000,
1492}; 1976};
1493 1977
1494static struct clk tegra_clk_hclk = { 1978static struct clk tegra_clk_hclk = {
@@ -1508,7 +1992,15 @@ static struct clk tegra_clk_pclk = {
1508 .reg = 0x30, 1992 .reg = 0x30,
1509 .reg_shift = 0, 1993 .reg_shift = 0,
1510 .ops = &tegra_bus_ops, 1994 .ops = &tegra_bus_ops,
1511 .max_rate = 108000000, 1995 .max_rate = 120000000,
1996};
1997
1998static struct clk tegra_clk_blink = {
1999 .name = "blink",
2000 .parent = &tegra_clk_32k,
2001 .reg = 0x40,
2002 .ops = &tegra_blink_clk_ops,
2003 .max_rate = 32768,
1512}; 2004};
1513 2005
1514static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = { 2006static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
@@ -1587,6 +2079,23 @@ static struct clk_mux_sel mux_clk_32k[] = {
1587 { 0, 0}, 2079 { 0, 0},
1588}; 2080};
1589 2081
2082static struct clk_mux_sel mux_pclk[] = {
2083 { .input = &tegra_clk_pclk, .value = 0},
2084 { 0, 0},
2085};
2086
2087static struct clk tegra_clk_emc = {
2088 .name = "emc",
2089 .ops = &tegra_emc_clk_ops,
2090 .reg = 0x19c,
2091 .max_rate = 800000000,
2092 .inputs = mux_pllm_pllc_pllp_clkm,
2093 .flags = MUX | DIV_U71 | PERIPH_EMC_ENB,
2094 .u.periph = {
2095 .clk_num = 57,
2096 },
2097};
2098
1590#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \ 2099#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
1591 { \ 2100 { \
1592 .name = _name, \ 2101 .name = _name, \
@@ -1595,19 +2104,32 @@ static struct clk_mux_sel mux_clk_32k[] = {
1595 .con_id = _con, \ 2104 .con_id = _con, \
1596 }, \ 2105 }, \
1597 .ops = &tegra_periph_clk_ops, \ 2106 .ops = &tegra_periph_clk_ops, \
1598 .clk_num = _clk_num, \
1599 .reg = _reg, \ 2107 .reg = _reg, \
1600 .inputs = _inputs, \ 2108 .inputs = _inputs, \
1601 .flags = _flags, \ 2109 .flags = _flags, \
1602 .max_rate = _max, \ 2110 .max_rate = _max, \
2111 .u.periph = { \
2112 .clk_num = _clk_num, \
2113 }, \
2114 }
2115
2116#define SHARED_CLK(_name, _dev, _con, _parent) \
2117 { \
2118 .name = _name, \
2119 .lookup = { \
2120 .dev_id = _dev, \
2121 .con_id = _con, \
2122 }, \
2123 .ops = &tegra_clk_shared_bus_ops, \
2124 .parent = _parent, \
1603 } 2125 }
1604 2126
1605struct clk tegra_periph_clks[] = { 2127struct clk tegra_list_clks[] = {
2128 PERIPH_CLK("apbdma", "tegra-dma", NULL, 34, 0, 108000000, mux_pclk, 0),
1606 PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET), 2129 PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET),
1607 PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0), 2130 PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0),
1608 PERIPH_CLK("i2s1", "i2s.0", NULL, 11, 0x100, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71), 2131 PERIPH_CLK("i2s1", "tegra-i2s.0", NULL, 11, 0x100, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
1609 PERIPH_CLK("i2s2", "i2s.1", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71), 2132 PERIPH_CLK("i2s2", "tegra-i2s.1", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
1610 /* FIXME: spdif has 2 clocks but 1 enable */
1611 PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71), 2133 PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
1612 PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71), 2134 PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71),
1613 PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71), 2135 PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71),
@@ -1620,13 +2142,15 @@ struct clk tegra_periph_clks[] = {
1620 PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), 2142 PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1621 PERIPH_CLK("ide", "ide", NULL, 25, 0x144, 100000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */ 2143 PERIPH_CLK("ide", "ide", NULL, 25, 0x144, 100000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
1622 PERIPH_CLK("ndflash", "tegra_nand", NULL, 13, 0x160, 164000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ 2144 PERIPH_CLK("ndflash", "tegra_nand", NULL, 13, 0x160, 164000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1623 /* FIXME: vfir shares an enable with uartb */
1624 PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), 2145 PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
1625 PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ 2146 PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1626 PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ 2147 PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1627 PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ 2148 PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1628 PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x160, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ 2149 PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x164, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
1629 PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage and process_id */ 2150 PERIPH_CLK("vcp", "tegra-avp", "vcp", 29, 0, 250000000, mux_clk_m, 0),
2151 PERIPH_CLK("bsea", "tegra-avp", "bsea", 62, 0, 250000000, mux_clk_m, 0),
2152 PERIPH_CLK("bsev", "tegra-aes", "bsev", 63, 0, 250000000, mux_clk_m, 0),
2153 PERIPH_CLK("vde", "tegra-avp", "vde", 61, 0x1c8, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
1630 PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* max rate ??? */ 2154 PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* max rate ??? */
1631 /* FIXME: what is la? */ 2155 /* FIXME: what is la? */
1632 PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), 2156 PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
@@ -1641,37 +2165,46 @@ struct clk tegra_periph_clks[] = {
1641 PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, 72000000, mux_pllp_out3, 0), 2165 PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
1642 PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, 72000000, mux_pllp_out3, 0), 2166 PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
1643 PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, 72000000, mux_pllp_out3, 0), 2167 PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
1644 PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, 216000000, mux_pllp_pllc_pllm_clkm, MUX), 2168 PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
1645 PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, 216000000, mux_pllp_pllc_pllm_clkm, MUX), 2169 PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
1646 PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, 216000000, mux_pllp_pllc_pllm_clkm, MUX), 2170 PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
1647 PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, 216000000, mux_pllp_pllc_pllm_clkm, MUX), 2171 PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
1648 PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, 216000000, mux_pllp_pllc_pllm_clkm, MUX), 2172 PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
1649 PERIPH_CLK("3d", "3d", NULL, 24, 0x158, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET), /* scales with voltage and process_id */ 2173 PERIPH_CLK("3d", "3d", NULL, 24, 0x158, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET), /* scales with voltage and process_id */
1650 PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */ 2174 PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
1651 /* FIXME: vi and vi_sensor share an enable */ 2175 PERIPH_CLK("vi", "tegra_camera", "vi", 20, 0x148, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
1652 PERIPH_CLK("vi", "vi", NULL, 20, 0x148, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */ 2176 PERIPH_CLK("vi_sensor", "tegra_camera", "vi_sensor", 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET), /* scales with voltage and process_id */
1653 PERIPH_CLK("vi_sensor", "vi_sensor", NULL, 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET), /* scales with voltage and process_id */
1654 PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */ 2177 PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
1655 PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 250000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */ 2178 PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 250000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
1656 PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, 166000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */ 2179 PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, 166000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
1657 /* FIXME: cve and tvo share an enable */
1658 PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ 2180 PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
1659 PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ 2181 PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
1660 PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, 148500000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ 2182 PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
1661 PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ 2183 PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
1662 PERIPH_CLK("disp1", "tegrafb.0", NULL, 27, 0x138, 190000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */ 2184 PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
1663 PERIPH_CLK("disp2", "tegrafb.1", NULL, 26, 0x13c, 190000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */ 2185 PERIPH_CLK("disp2", "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
1664 PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ 2186 PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
1665 PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ 2187 PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
1666 PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ 2188 PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
1667 PERIPH_CLK("emc", "emc", NULL, 57, 0x19c, 800000000, mux_pllm_pllc_pllp_clkm, MUX | DIV_U71 | PERIPH_EMC_ENB),
1668 PERIPH_CLK("dsi", "dsi", NULL, 48, 0, 500000000, mux_plld, 0), /* scales with voltage */ 2189 PERIPH_CLK("dsi", "dsi", NULL, 48, 0, 500000000, mux_plld, 0), /* scales with voltage */
1669 PERIPH_CLK("csi", "csi", NULL, 52, 0, 72000000, mux_pllp_out3, 0), 2190 PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 72000000, mux_pllp_out3, 0),
1670 PERIPH_CLK("isp", "isp", NULL, 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */ 2191 PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */
1671 PERIPH_CLK("csus", "csus", NULL, 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET), 2192 PERIPH_CLK("csus", "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET),
1672 PERIPH_CLK("pex", NULL, "pex", 70, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET), 2193 PERIPH_CLK("pex", NULL, "pex", 70, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
1673 PERIPH_CLK("afi", NULL, "afi", 72, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET), 2194 PERIPH_CLK("afi", NULL, "afi", 72, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
1674 PERIPH_CLK("pcie_xclk", NULL, "pcie_xclk", 74, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET), 2195 PERIPH_CLK("pcie_xclk", NULL, "pcie_xclk", 74, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
2196
2197 SHARED_CLK("avp.sclk", "tegra-avp", "sclk", &tegra_clk_sclk),
2198 SHARED_CLK("avp.emc", "tegra-avp", "emc", &tegra_clk_emc),
2199 SHARED_CLK("cpu.emc", "cpu", "emc", &tegra_clk_emc),
2200 SHARED_CLK("disp1.emc", "tegradc.0", "emc", &tegra_clk_emc),
2201 SHARED_CLK("disp2.emc", "tegradc.1", "emc", &tegra_clk_emc),
2202 SHARED_CLK("hdmi.emc", "hdmi", "emc", &tegra_clk_emc),
2203 SHARED_CLK("host.emc", "tegra_grhost", "emc", &tegra_clk_emc),
2204 SHARED_CLK("usbd.emc", "fsl-tegra-udc", "emc", &tegra_clk_emc),
2205 SHARED_CLK("usb1.emc", "tegra-ehci.0", "emc", &tegra_clk_emc),
2206 SHARED_CLK("usb2.emc", "tegra-ehci.1", "emc", &tegra_clk_emc),
2207 SHARED_CLK("usb3.emc", "tegra-ehci.2", "emc", &tegra_clk_emc),
1675}; 2208};
1676 2209
1677#define CLK_DUPLICATE(_name, _dev, _con) \ 2210#define CLK_DUPLICATE(_name, _dev, _con) \
@@ -1693,9 +2226,22 @@ struct clk_duplicate tegra_clk_duplicates[] = {
1693 CLK_DUPLICATE("uartc", "tegra_uart.2", NULL), 2226 CLK_DUPLICATE("uartc", "tegra_uart.2", NULL),
1694 CLK_DUPLICATE("uartd", "tegra_uart.3", NULL), 2227 CLK_DUPLICATE("uartd", "tegra_uart.3", NULL),
1695 CLK_DUPLICATE("uarte", "tegra_uart.4", NULL), 2228 CLK_DUPLICATE("uarte", "tegra_uart.4", NULL),
1696 CLK_DUPLICATE("host1x", "tegrafb.0", "host1x"), 2229 CLK_DUPLICATE("usbd", "utmip-pad", NULL),
1697 CLK_DUPLICATE("host1x", "tegrafb.1", "host1x"),
1698 CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL), 2230 CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
2231 CLK_DUPLICATE("usbd", "tegra-otg", NULL),
2232 CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
2233 CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
2234 CLK_DUPLICATE("pwm", "tegra_pwm.0", NULL),
2235 CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL),
2236 CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL),
2237 CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL),
2238 CLK_DUPLICATE("host1x", "tegra_grhost", "host1x"),
2239 CLK_DUPLICATE("2d", "tegra_grhost", "gr2d"),
2240 CLK_DUPLICATE("3d", "tegra_grhost", "gr3d"),
2241 CLK_DUPLICATE("epp", "tegra_grhost", "epp"),
2242 CLK_DUPLICATE("mpe", "tegra_grhost", "mpe"),
2243 CLK_DUPLICATE("cop", "tegra-avp", "cop"),
2244 CLK_DUPLICATE("vde", "tegra-aes", "vde"),
1699}; 2245};
1700 2246
1701#define CLK(dev, con, ck) \ 2247#define CLK(dev, con, ck) \
@@ -1705,68 +2251,70 @@ struct clk_duplicate tegra_clk_duplicates[] = {
1705 .clk = ck, \ 2251 .clk = ck, \
1706 } 2252 }
1707 2253
1708struct clk_lookup tegra_clk_lookups[] = { 2254struct clk *tegra_ptr_clks[] = {
1709 /* external root sources */ 2255 &tegra_clk_32k,
1710 CLK(NULL, "32k_clk", &tegra_clk_32k), 2256 &tegra_pll_s,
1711 CLK(NULL, "pll_s", &tegra_pll_s), 2257 &tegra_clk_m,
1712 CLK(NULL, "clk_m", &tegra_clk_m), 2258 &tegra_pll_m,
1713 CLK(NULL, "pll_m", &tegra_pll_m), 2259 &tegra_pll_m_out1,
1714 CLK(NULL, "pll_m_out1", &tegra_pll_m_out1), 2260 &tegra_pll_c,
1715 CLK(NULL, "pll_c", &tegra_pll_c), 2261 &tegra_pll_c_out1,
1716 CLK(NULL, "pll_c_out1", &tegra_pll_c_out1), 2262 &tegra_pll_p,
1717 CLK(NULL, "pll_p", &tegra_pll_p), 2263 &tegra_pll_p_out1,
1718 CLK(NULL, "pll_p_out1", &tegra_pll_p_out1), 2264 &tegra_pll_p_out2,
1719 CLK(NULL, "pll_p_out2", &tegra_pll_p_out2), 2265 &tegra_pll_p_out3,
1720 CLK(NULL, "pll_p_out3", &tegra_pll_p_out3), 2266 &tegra_pll_p_out4,
1721 CLK(NULL, "pll_p_out4", &tegra_pll_p_out4), 2267 &tegra_pll_a,
1722 CLK(NULL, "pll_a", &tegra_pll_a), 2268 &tegra_pll_a_out0,
1723 CLK(NULL, "pll_a_out0", &tegra_pll_a_out0), 2269 &tegra_pll_d,
1724 CLK(NULL, "pll_d", &tegra_pll_d), 2270 &tegra_pll_d_out0,
1725 CLK(NULL, "pll_d_out0", &tegra_pll_d_out0), 2271 &tegra_pll_u,
1726 CLK(NULL, "pll_u", &tegra_pll_u), 2272 &tegra_pll_x,
1727 CLK(NULL, "pll_x", &tegra_pll_x), 2273 &tegra_pll_e,
1728 CLK(NULL, "pll_e", &tegra_pll_e), 2274 &tegra_clk_cclk,
1729 CLK(NULL, "cclk", &tegra_clk_cclk), 2275 &tegra_clk_sclk,
1730 CLK(NULL, "sclk", &tegra_clk_sclk), 2276 &tegra_clk_hclk,
1731 CLK(NULL, "hclk", &tegra_clk_hclk), 2277 &tegra_clk_pclk,
1732 CLK(NULL, "pclk", &tegra_clk_pclk), 2278 &tegra_clk_d,
1733 CLK(NULL, "clk_d", &tegra_clk_d), 2279 &tegra_clk_cdev1,
1734 CLK(NULL, "cpu", &tegra_clk_virtual_cpu), 2280 &tegra_clk_cdev2,
1735}; 2281 &tegra_clk_virtual_cpu,
2282 &tegra_clk_blink,
2283 &tegra_clk_cop,
2284 &tegra_clk_emc,
2285};
2286
2287static void tegra2_init_one_clock(struct clk *c)
2288{
2289 clk_init(c);
2290 INIT_LIST_HEAD(&c->shared_bus_list);
2291 if (!c->lookup.dev_id && !c->lookup.con_id)
2292 c->lookup.con_id = c->name;
2293 c->lookup.clk = c;
2294 clkdev_add(&c->lookup);
2295}
1736 2296
1737void __init tegra2_init_clocks(void) 2297void __init tegra2_init_clocks(void)
1738{ 2298{
1739 int i; 2299 int i;
1740 struct clk_lookup *cl;
1741 struct clk *c; 2300 struct clk *c;
1742 struct clk_duplicate *cd;
1743
1744 for (i = 0; i < ARRAY_SIZE(tegra_clk_lookups); i++) {
1745 cl = &tegra_clk_lookups[i];
1746 clk_init(cl->clk);
1747 clkdev_add(cl);
1748 }
1749 2301
1750 for (i = 0; i < ARRAY_SIZE(tegra_periph_clks); i++) { 2302 for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
1751 c = &tegra_periph_clks[i]; 2303 tegra2_init_one_clock(tegra_ptr_clks[i]);
1752 cl = &c->lookup;
1753 cl->clk = c;
1754 2304
1755 clk_init(cl->clk); 2305 for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
1756 clkdev_add(cl); 2306 tegra2_init_one_clock(&tegra_list_clks[i]);
1757 }
1758 2307
1759 for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) { 2308 for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
1760 cd = &tegra_clk_duplicates[i]; 2309 c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
1761 c = tegra_get_clock_by_name(cd->name); 2310 if (!c) {
1762 if (c) {
1763 cl = &cd->lookup;
1764 cl->clk = c;
1765 clkdev_add(cl);
1766 } else {
1767 pr_err("%s: Unknown duplicate clock %s\n", __func__, 2311 pr_err("%s: Unknown duplicate clock %s\n", __func__,
1768 cd->name); 2312 tegra_clk_duplicates[i].name);
2313 continue;
1769 } 2314 }
2315
2316 tegra_clk_duplicates[i].lookup.clk = c;
2317 clkdev_add(&tegra_clk_duplicates[i].lookup);
1770 } 2318 }
1771 2319
1772 init_audio_sync_clock_mux(); 2320 init_audio_sync_clock_mux();
@@ -1774,7 +2322,7 @@ void __init tegra2_init_clocks(void)
1774 2322
1775#ifdef CONFIG_PM 2323#ifdef CONFIG_PM
1776static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM + 2324static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM +
1777 PERIPH_CLK_SOURCE_NUM + 3]; 2325 PERIPH_CLK_SOURCE_NUM + 22];
1778 2326
1779void tegra_clk_suspend(void) 2327void tegra_clk_suspend(void)
1780{ 2328{
@@ -1782,6 +2330,29 @@ void tegra_clk_suspend(void)
1782 u32 *ctx = clk_rst_suspend; 2330 u32 *ctx = clk_rst_suspend;
1783 2331
1784 *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK; 2332 *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK;
2333 *ctx++ = clk_readl(tegra_pll_c.reg + PLL_BASE);
2334 *ctx++ = clk_readl(tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
2335 *ctx++ = clk_readl(tegra_pll_a.reg + PLL_BASE);
2336 *ctx++ = clk_readl(tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
2337 *ctx++ = clk_readl(tegra_pll_s.reg + PLL_BASE);
2338 *ctx++ = clk_readl(tegra_pll_s.reg + PLL_MISC(&tegra_pll_s));
2339 *ctx++ = clk_readl(tegra_pll_d.reg + PLL_BASE);
2340 *ctx++ = clk_readl(tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
2341 *ctx++ = clk_readl(tegra_pll_u.reg + PLL_BASE);
2342 *ctx++ = clk_readl(tegra_pll_u.reg + PLL_MISC(&tegra_pll_u));
2343
2344 *ctx++ = clk_readl(tegra_pll_m_out1.reg);
2345 *ctx++ = clk_readl(tegra_pll_a_out0.reg);
2346 *ctx++ = clk_readl(tegra_pll_c_out1.reg);
2347
2348 *ctx++ = clk_readl(tegra_clk_cclk.reg);
2349 *ctx++ = clk_readl(tegra_clk_cclk.reg + SUPER_CLK_DIVIDER);
2350
2351 *ctx++ = clk_readl(tegra_clk_sclk.reg);
2352 *ctx++ = clk_readl(tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
2353 *ctx++ = clk_readl(tegra_clk_pclk.reg);
2354
2355 *ctx++ = clk_readl(tegra_clk_audio.reg);
1785 2356
1786 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC; 2357 for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
1787 off += 4) { 2358 off += 4) {
@@ -1800,6 +2371,8 @@ void tegra_clk_suspend(void)
1800 2371
1801 *ctx++ = clk_readl(MISC_CLK_ENB); 2372 *ctx++ = clk_readl(MISC_CLK_ENB);
1802 *ctx++ = clk_readl(CLK_MASK_ARM); 2373 *ctx++ = clk_readl(CLK_MASK_ARM);
2374
2375 BUG_ON(ctx - clk_rst_suspend != ARRAY_SIZE(clk_rst_suspend));
1803} 2376}
1804 2377
1805void tegra_clk_resume(void) 2378void tegra_clk_resume(void)
@@ -1812,6 +2385,31 @@ void tegra_clk_resume(void)
1812 val |= *ctx++; 2385 val |= *ctx++;
1813 clk_writel(val, OSC_CTRL); 2386 clk_writel(val, OSC_CTRL);
1814 2387
2388 clk_writel(*ctx++, tegra_pll_c.reg + PLL_BASE);
2389 clk_writel(*ctx++, tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
2390 clk_writel(*ctx++, tegra_pll_a.reg + PLL_BASE);
2391 clk_writel(*ctx++, tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
2392 clk_writel(*ctx++, tegra_pll_s.reg + PLL_BASE);
2393 clk_writel(*ctx++, tegra_pll_s.reg + PLL_MISC(&tegra_pll_s));
2394 clk_writel(*ctx++, tegra_pll_d.reg + PLL_BASE);
2395 clk_writel(*ctx++, tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
2396 clk_writel(*ctx++, tegra_pll_u.reg + PLL_BASE);
2397 clk_writel(*ctx++, tegra_pll_u.reg + PLL_MISC(&tegra_pll_u));
2398 udelay(1000);
2399
2400 clk_writel(*ctx++, tegra_pll_m_out1.reg);
2401 clk_writel(*ctx++, tegra_pll_a_out0.reg);
2402 clk_writel(*ctx++, tegra_pll_c_out1.reg);
2403
2404 clk_writel(*ctx++, tegra_clk_cclk.reg);
2405 clk_writel(*ctx++, tegra_clk_cclk.reg + SUPER_CLK_DIVIDER);
2406
2407 clk_writel(*ctx++, tegra_clk_sclk.reg);
2408 clk_writel(*ctx++, tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
2409 clk_writel(*ctx++, tegra_clk_pclk.reg);
2410
2411 clk_writel(*ctx++, tegra_clk_audio.reg);
2412
1815 /* enable all clocks before configuring clock sources */ 2413 /* enable all clocks before configuring clock sources */
1816 clk_writel(0xbffffff9ul, CLK_OUT_ENB); 2414 clk_writel(0xbffffff9ul, CLK_OUT_ENB);
1817 clk_writel(0xfefffff7ul, CLK_OUT_ENB + 4); 2415 clk_writel(0xfefffff7ul, CLK_OUT_ENB + 4);
diff --git a/arch/arm/mach-tegra/tegra2_dvfs.c b/arch/arm/mach-tegra/tegra2_dvfs.c
deleted file mode 100644
index 5529c238dd77..000000000000
--- a/arch/arm/mach-tegra/tegra2_dvfs.c
+++ /dev/null
@@ -1,86 +0,0 @@
1/*
2 * arch/arm/mach-tegra/tegra2_dvfs.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
22#include "clock.h"
23#include "tegra2_dvfs.h"
24
25static struct dvfs_table virtual_cpu_process_0[] = {
26 {314000000, 750},
27 {456000000, 825},
28 {608000000, 900},
29 {760000000, 975},
30 {817000000, 1000},
31 {912000000, 1050},
32 {1000000000, 1100},
33 {0, 0},
34};
35
36static struct dvfs_table virtual_cpu_process_1[] = {
37 {314000000, 750},
38 {456000000, 825},
39 {618000000, 900},
40 {770000000, 975},
41 {827000000, 1000},
42 {922000000, 1050},
43 {1000000000, 1100},
44 {0, 0},
45};
46
47static struct dvfs_table virtual_cpu_process_2[] = {
48 {494000000, 750},
49 {675000000, 825},
50 {817000000, 875},
51 {922000000, 925},
52 {1000000000, 975},
53 {0, 0},
54};
55
56static struct dvfs_table virtual_cpu_process_3[] = {
57 {730000000, 750},
58 {760000000, 775},
59 {845000000, 800},
60 {1000000000, 875},
61 {0, 0},
62};
63
64struct dvfs tegra_dvfs_virtual_cpu_dvfs = {
65 .reg_id = "vdd_cpu",
66 .process_id_table = {
67 {
68 .process_id = 0,
69 .table = virtual_cpu_process_0,
70 },
71 {
72 .process_id = 1,
73 .table = virtual_cpu_process_1,
74 },
75 {
76 .process_id = 2,
77 .table = virtual_cpu_process_2,
78 },
79 {
80 .process_id = 3,
81 .table = virtual_cpu_process_3,
82 },
83 },
84 .process_id_table_length = 4,
85 .cpu = 1,
86};
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
new file mode 100644
index 000000000000..0f7ae6e90b55
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_emc.c
@@ -0,0 +1,178 @@
1/*
2 * Copyright (C) 2011 Google, Inc.
3 *
4 * Author:
5 * Colin Cross <ccross@android.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/clk.h>
20#include <linux/err.h>
21#include <linux/io.h>
22#include <linux/module.h>
23
24#include <mach/iomap.h>
25
26#include "tegra2_emc.h"
27
28#ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE
29static bool emc_enable = true;
30#else
31static bool emc_enable;
32#endif
33module_param(emc_enable, bool, 0644);
34
35static void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE);
36static const struct tegra_emc_table *tegra_emc_table;
37static int tegra_emc_table_size;
38
39static inline void emc_writel(u32 val, unsigned long addr)
40{
41 writel(val, emc + addr);
42}
43
44static inline u32 emc_readl(unsigned long addr)
45{
46 return readl(emc + addr);
47}
48
49static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
50 0x2c, /* RC */
51 0x30, /* RFC */
52 0x34, /* RAS */
53 0x38, /* RP */
54 0x3c, /* R2W */
55 0x40, /* W2R */
56 0x44, /* R2P */
57 0x48, /* W2P */
58 0x4c, /* RD_RCD */
59 0x50, /* WR_RCD */
60 0x54, /* RRD */
61 0x58, /* REXT */
62 0x5c, /* WDV */
63 0x60, /* QUSE */
64 0x64, /* QRST */
65 0x68, /* QSAFE */
66 0x6c, /* RDV */
67 0x70, /* REFRESH */
68 0x74, /* BURST_REFRESH_NUM */
69 0x78, /* PDEX2WR */
70 0x7c, /* PDEX2RD */
71 0x80, /* PCHG2PDEN */
72 0x84, /* ACT2PDEN */
73 0x88, /* AR2PDEN */
74 0x8c, /* RW2PDEN */
75 0x90, /* TXSR */
76 0x94, /* TCKE */
77 0x98, /* TFAW */
78 0x9c, /* TRPAB */
79 0xa0, /* TCLKSTABLE */
80 0xa4, /* TCLKSTOP */
81 0xa8, /* TREFBW */
82 0xac, /* QUSE_EXTRA */
83 0x114, /* FBIO_CFG6 */
84 0xb0, /* ODT_WRITE */
85 0xb4, /* ODT_READ */
86 0x104, /* FBIO_CFG5 */
87 0x2bc, /* CFG_DIG_DLL */
88 0x2c0, /* DLL_XFORM_DQS */
89 0x2c4, /* DLL_XFORM_QUSE */
90 0x2e0, /* ZCAL_REF_CNT */
91 0x2e4, /* ZCAL_WAIT_CNT */
92 0x2a8, /* AUTO_CAL_INTERVAL */
93 0x2d0, /* CFG_CLKTRIM_0 */
94 0x2d4, /* CFG_CLKTRIM_1 */
95 0x2d8, /* CFG_CLKTRIM_2 */
96};
97
98/* Select the closest EMC rate that is higher than the requested rate */
99long tegra_emc_round_rate(unsigned long rate)
100{
101 int i;
102 int best = -1;
103 unsigned long distance = ULONG_MAX;
104
105 if (!tegra_emc_table)
106 return -EINVAL;
107
108 if (!emc_enable)
109 return -EINVAL;
110
111 pr_debug("%s: %lu\n", __func__, rate);
112
113 /*
114 * The EMC clock rate is twice the bus rate, and the bus rate is
115 * measured in kHz
116 */
117 rate = rate / 2 / 1000;
118
119 for (i = 0; i < tegra_emc_table_size; i++) {
120 if (tegra_emc_table[i].rate >= rate &&
121 (tegra_emc_table[i].rate - rate) < distance) {
122 distance = tegra_emc_table[i].rate - rate;
123 best = i;
124 }
125 }
126
127 if (best < 0)
128 return -EINVAL;
129
130 pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate);
131
132 return tegra_emc_table[best].rate * 2 * 1000;
133}
134
135/*
136 * The EMC registers have shadow registers. When the EMC clock is updated
137 * in the clock controller, the shadow registers are copied to the active
138 * registers, allowing glitchless memory bus frequency changes.
139 * This function updates the shadow registers for a new clock frequency,
140 * and relies on the clock lock on the emc clock to avoid races between
141 * multiple frequency changes
142 */
143int tegra_emc_set_rate(unsigned long rate)
144{
145 int i;
146 int j;
147
148 if (!tegra_emc_table)
149 return -EINVAL;
150
151 /*
152 * The EMC clock rate is twice the bus rate, and the bus rate is
153 * measured in kHz
154 */
155 rate = rate / 2 / 1000;
156
157 for (i = 0; i < tegra_emc_table_size; i++)
158 if (tegra_emc_table[i].rate == rate)
159 break;
160
161 if (i >= tegra_emc_table_size)
162 return -EINVAL;
163
164 pr_debug("%s: setting to %lu\n", __func__, rate);
165
166 for (j = 0; j < TEGRA_EMC_NUM_REGS; j++)
167 emc_writel(tegra_emc_table[i].regs[j], emc_reg_addr[j]);
168
169 emc_readl(tegra_emc_table[i].regs[TEGRA_EMC_NUM_REGS - 1]);
170
171 return 0;
172}
173
174void tegra_init_emc(const struct tegra_emc_table *table, int table_size)
175{
176 tegra_emc_table = table;
177 tegra_emc_table_size = table_size;
178}
diff --git a/arch/arm/mach-tegra/tegra2_emc.h b/arch/arm/mach-tegra/tegra2_emc.h
new file mode 100644
index 000000000000..19f08cb31603
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_emc.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2011 Google, Inc.
3 *
4 * Author:
5 * Colin Cross <ccross@android.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#define TEGRA_EMC_NUM_REGS 46
19
20struct tegra_emc_table {
21 unsigned long rate;
22 u32 regs[TEGRA_EMC_NUM_REGS];
23};
24
25int tegra_emc_set_rate(unsigned long rate);
26long tegra_emc_round_rate(unsigned long rate);
27void tegra_init_emc(const struct tegra_emc_table *table, int table_size);
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
index 7b8ad1f98f44..0fcb1eb4214d 100644
--- a/arch/arm/mach-tegra/timer.c
+++ b/arch/arm/mach-tegra/timer.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/err.h>
21#include <linux/sched.h> 22#include <linux/sched.h>
22#include <linux/time.h> 23#include <linux/time.h>
23#include <linux/interrupt.h> 24#include <linux/interrupt.h>
@@ -33,10 +34,15 @@
33 34
34#include <mach/iomap.h> 35#include <mach/iomap.h>
35#include <mach/irqs.h> 36#include <mach/irqs.h>
37#include <mach/suspend.h>
36 38
37#include "board.h" 39#include "board.h"
38#include "clock.h" 40#include "clock.h"
39 41
42#define RTC_SECONDS 0x08
43#define RTC_SHADOW_SECONDS 0x0c
44#define RTC_MILLISECONDS 0x10
45
40#define TIMERUS_CNTR_1US 0x10 46#define TIMERUS_CNTR_1US 0x10
41#define TIMERUS_USEC_CFG 0x14 47#define TIMERUS_USEC_CFG 0x14
42#define TIMERUS_CNTR_FREEZE 0x4c 48#define TIMERUS_CNTR_FREEZE 0x4c
@@ -49,9 +55,11 @@
49#define TIMER_PTV 0x0 55#define TIMER_PTV 0x0
50#define TIMER_PCR 0x4 56#define TIMER_PCR 0x4
51 57
52struct tegra_timer;
53
54static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE); 58static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE);
59static void __iomem *rtc_base = IO_ADDRESS(TEGRA_RTC_BASE);
60
61static struct timespec persistent_ts;
62static u64 persistent_ms, last_persistent_ms;
55 63
56#define timer_writel(value, reg) \ 64#define timer_writel(value, reg) \
57 __raw_writel(value, (u32)timer_reg_base + (reg)) 65 __raw_writel(value, (u32)timer_reg_base + (reg))
@@ -132,6 +140,42 @@ static void notrace tegra_update_sched_clock(void)
132 update_sched_clock(&cd, cyc, (u32)~0); 140 update_sched_clock(&cd, cyc, (u32)~0);
133} 141}
134 142
143/*
144 * tegra_rtc_read - Reads the Tegra RTC registers
145 * Care must be taken that this funciton is not called while the
146 * tegra_rtc driver could be executing to avoid race conditions
147 * on the RTC shadow register
148 */
149u64 tegra_rtc_read_ms(void)
150{
151 u32 ms = readl(rtc_base + RTC_MILLISECONDS);
152 u32 s = readl(rtc_base + RTC_SHADOW_SECONDS);
153 return (u64)s * MSEC_PER_SEC + ms;
154}
155
156/*
157 * read_persistent_clock - Return time from a persistent clock.
158 *
159 * Reads the time from a source which isn't disabled during PM, the
160 * 32k sync timer. Convert the cycles elapsed since last read into
161 * nsecs and adds to a monotonically increasing timespec.
162 * Care must be taken that this funciton is not called while the
163 * tegra_rtc driver could be executing to avoid race conditions
164 * on the RTC shadow register
165 */
166void read_persistent_clock(struct timespec *ts)
167{
168 u64 delta;
169 struct timespec *tsp = &persistent_ts;
170
171 last_persistent_ms = persistent_ms;
172 persistent_ms = tegra_rtc_read_ms();
173 delta = persistent_ms - last_persistent_ms;
174
175 timespec_add_ns(tsp, delta * NSEC_PER_MSEC);
176 *ts = *tsp;
177}
178
135static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id) 179static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
136{ 180{
137 struct clock_event_device *evt = (struct clock_event_device *)dev_id; 181 struct clock_event_device *evt = (struct clock_event_device *)dev_id;
@@ -150,9 +194,22 @@ static struct irqaction tegra_timer_irq = {
150 194
151static void __init tegra_init_timer(void) 195static void __init tegra_init_timer(void)
152{ 196{
197 struct clk *clk;
153 unsigned long rate = clk_measure_input_freq(); 198 unsigned long rate = clk_measure_input_freq();
154 int ret; 199 int ret;
155 200
201 clk = clk_get_sys("timer", NULL);
202 BUG_ON(IS_ERR(clk));
203 clk_enable(clk);
204
205 /*
206 * rtc registers are used by read_persistent_clock, keep the rtc clock
207 * enabled
208 */
209 clk = clk_get_sys("rtc-tegra", NULL);
210 BUG_ON(IS_ERR(clk));
211 clk_enable(clk);
212
156#ifdef CONFIG_HAVE_ARM_TWD 213#ifdef CONFIG_HAVE_ARM_TWD
157 twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600); 214 twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
158#endif 215#endif
@@ -196,10 +253,22 @@ static void __init tegra_init_timer(void)
196 tegra_clockevent.cpumask = cpu_all_mask; 253 tegra_clockevent.cpumask = cpu_all_mask;
197 tegra_clockevent.irq = tegra_timer_irq.irq; 254 tegra_clockevent.irq = tegra_timer_irq.irq;
198 clockevents_register_device(&tegra_clockevent); 255 clockevents_register_device(&tegra_clockevent);
199
200 return;
201} 256}
202 257
203struct sys_timer tegra_timer = { 258struct sys_timer tegra_timer = {
204 .init = tegra_init_timer, 259 .init = tegra_init_timer,
205}; 260};
261
262#ifdef CONFIG_PM
263static u32 usec_config;
264
265void tegra_timer_suspend(void)
266{
267 usec_config = timer_readl(TIMERUS_USEC_CFG);
268}
269
270void tegra_timer_resume(void)
271{
272 timer_writel(usec_config, TIMERUS_USEC_CFG);
273}
274#endif
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
new file mode 100644
index 000000000000..88081bb3ec52
--- /dev/null
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -0,0 +1,795 @@
1/*
2 * arch/arm/mach-tegra/usb_phy.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Erik Gilling <konkers@google.com>
8 * Benoit Goby <benoit@android.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/resource.h>
22#include <linux/delay.h>
23#include <linux/slab.h>
24#include <linux/err.h>
25#include <linux/platform_device.h>
26#include <linux/io.h>
27#include <linux/gpio.h>
28#include <linux/usb/otg.h>
29#include <linux/usb/ulpi.h>
30#include <asm/mach-types.h>
31#include <mach/usb_phy.h>
32#include <mach/iomap.h>
33
34#define ULPI_VIEWPORT 0x170
35
36#define USB_PORTSC1 0x184
37#define USB_PORTSC1_PTS(x) (((x) & 0x3) << 30)
38#define USB_PORTSC1_PSPD(x) (((x) & 0x3) << 26)
39#define USB_PORTSC1_PHCD (1 << 23)
40#define USB_PORTSC1_WKOC (1 << 22)
41#define USB_PORTSC1_WKDS (1 << 21)
42#define USB_PORTSC1_WKCN (1 << 20)
43#define USB_PORTSC1_PTC(x) (((x) & 0xf) << 16)
44#define USB_PORTSC1_PP (1 << 12)
45#define USB_PORTSC1_SUSP (1 << 7)
46#define USB_PORTSC1_PE (1 << 2)
47#define USB_PORTSC1_CCS (1 << 0)
48
49#define USB_SUSP_CTRL 0x400
50#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3)
51#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4)
52#define USB_SUSP_CLR (1 << 5)
53#define USB_PHY_CLK_VALID (1 << 7)
54#define UTMIP_RESET (1 << 11)
55#define UHSIC_RESET (1 << 11)
56#define UTMIP_PHY_ENABLE (1 << 12)
57#define ULPI_PHY_ENABLE (1 << 13)
58#define USB_SUSP_SET (1 << 14)
59#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16)
60
61#define USB1_LEGACY_CTRL 0x410
62#define USB1_NO_LEGACY_MODE (1 << 0)
63#define USB1_VBUS_SENSE_CTL_MASK (3 << 1)
64#define USB1_VBUS_SENSE_CTL_VBUS_WAKEUP (0 << 1)
65#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP \
66 (1 << 1)
67#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD (2 << 1)
68#define USB1_VBUS_SENSE_CTL_A_SESS_VLD (3 << 1)
69
70#define ULPI_TIMING_CTRL_0 0x424
71#define ULPI_OUTPUT_PINMUX_BYP (1 << 10)
72#define ULPI_CLKOUT_PINMUX_BYP (1 << 11)
73
74#define ULPI_TIMING_CTRL_1 0x428
75#define ULPI_DATA_TRIMMER_LOAD (1 << 0)
76#define ULPI_DATA_TRIMMER_SEL(x) (((x) & 0x7) << 1)
77#define ULPI_STPDIRNXT_TRIMMER_LOAD (1 << 16)
78#define ULPI_STPDIRNXT_TRIMMER_SEL(x) (((x) & 0x7) << 17)
79#define ULPI_DIR_TRIMMER_LOAD (1 << 24)
80#define ULPI_DIR_TRIMMER_SEL(x) (((x) & 0x7) << 25)
81
82#define UTMIP_PLL_CFG1 0x804
83#define UTMIP_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
84#define UTMIP_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27)
85
86#define UTMIP_XCVR_CFG0 0x808
87#define UTMIP_XCVR_SETUP(x) (((x) & 0xf) << 0)
88#define UTMIP_XCVR_LSRSLEW(x) (((x) & 0x3) << 8)
89#define UTMIP_XCVR_LSFSLEW(x) (((x) & 0x3) << 10)
90#define UTMIP_FORCE_PD_POWERDOWN (1 << 14)
91#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16)
92#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18)
93#define UTMIP_XCVR_HSSLEW_MSB(x) (((x) & 0x7f) << 25)
94
95#define UTMIP_BIAS_CFG0 0x80c
96#define UTMIP_OTGPD (1 << 11)
97#define UTMIP_BIASPD (1 << 10)
98
99#define UTMIP_HSRX_CFG0 0x810
100#define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10)
101#define UTMIP_IDLE_WAIT(x) (((x) & 0x1f) << 15)
102
103#define UTMIP_HSRX_CFG1 0x814
104#define UTMIP_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1)
105
106#define UTMIP_TX_CFG0 0x820
107#define UTMIP_FS_PREABMLE_J (1 << 19)
108#define UTMIP_HS_DISCON_DISABLE (1 << 8)
109
110#define UTMIP_MISC_CFG0 0x824
111#define UTMIP_DPDM_OBSERVE (1 << 26)
112#define UTMIP_DPDM_OBSERVE_SEL(x) (((x) & 0xf) << 27)
113#define UTMIP_DPDM_OBSERVE_SEL_FS_J UTMIP_DPDM_OBSERVE_SEL(0xf)
114#define UTMIP_DPDM_OBSERVE_SEL_FS_K UTMIP_DPDM_OBSERVE_SEL(0xe)
115#define UTMIP_DPDM_OBSERVE_SEL_FS_SE1 UTMIP_DPDM_OBSERVE_SEL(0xd)
116#define UTMIP_DPDM_OBSERVE_SEL_FS_SE0 UTMIP_DPDM_OBSERVE_SEL(0xc)
117#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22)
118
119#define UTMIP_MISC_CFG1 0x828
120#define UTMIP_PLL_ACTIVE_DLY_COUNT(x) (((x) & 0x1f) << 18)
121#define UTMIP_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 6)
122
123#define UTMIP_DEBOUNCE_CFG0 0x82c
124#define UTMIP_BIAS_DEBOUNCE_A(x) (((x) & 0xffff) << 0)
125
126#define UTMIP_BAT_CHRG_CFG0 0x830
127#define UTMIP_PD_CHRG (1 << 0)
128
129#define UTMIP_SPARE_CFG0 0x834
130#define FUSE_SETUP_SEL (1 << 3)
131
132#define UTMIP_XCVR_CFG1 0x838
133#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0)
134#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2)
135#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4)
136#define UTMIP_XCVR_TERM_RANGE_ADJ(x) (((x) & 0xf) << 18)
137
138#define UTMIP_BIAS_CFG1 0x83c
139#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3)
140
141static DEFINE_SPINLOCK(utmip_pad_lock);
142static int utmip_pad_count;
143
144struct tegra_xtal_freq {
145 int freq;
146 u8 enable_delay;
147 u8 stable_count;
148 u8 active_delay;
149 u8 xtal_freq_count;
150 u16 debounce;
151};
152
153static const struct tegra_xtal_freq tegra_freq_table[] = {
154 {
155 .freq = 12000000,
156 .enable_delay = 0x02,
157 .stable_count = 0x2F,
158 .active_delay = 0x04,
159 .xtal_freq_count = 0x76,
160 .debounce = 0x7530,
161 },
162 {
163 .freq = 13000000,
164 .enable_delay = 0x02,
165 .stable_count = 0x33,
166 .active_delay = 0x05,
167 .xtal_freq_count = 0x7F,
168 .debounce = 0x7EF4,
169 },
170 {
171 .freq = 19200000,
172 .enable_delay = 0x03,
173 .stable_count = 0x4B,
174 .active_delay = 0x06,
175 .xtal_freq_count = 0xBB,
176 .debounce = 0xBB80,
177 },
178 {
179 .freq = 26000000,
180 .enable_delay = 0x04,
181 .stable_count = 0x66,
182 .active_delay = 0x09,
183 .xtal_freq_count = 0xFE,
184 .debounce = 0xFDE8,
185 },
186};
187
188static struct tegra_utmip_config utmip_default[] = {
189 [0] = {
190 .hssync_start_delay = 9,
191 .idle_wait_delay = 17,
192 .elastic_limit = 16,
193 .term_range_adj = 6,
194 .xcvr_setup = 9,
195 .xcvr_lsfslew = 1,
196 .xcvr_lsrslew = 1,
197 },
198 [2] = {
199 .hssync_start_delay = 9,
200 .idle_wait_delay = 17,
201 .elastic_limit = 16,
202 .term_range_adj = 6,
203 .xcvr_setup = 9,
204 .xcvr_lsfslew = 2,
205 .xcvr_lsrslew = 2,
206 },
207};
208
209static inline bool phy_is_ulpi(struct tegra_usb_phy *phy)
210{
211 return (phy->instance == 1);
212}
213
214static int utmip_pad_open(struct tegra_usb_phy *phy)
215{
216 phy->pad_clk = clk_get_sys("utmip-pad", NULL);
217 if (IS_ERR(phy->pad_clk)) {
218 pr_err("%s: can't get utmip pad clock\n", __func__);
219 return PTR_ERR(phy->pad_clk);
220 }
221
222 if (phy->instance == 0) {
223 phy->pad_regs = phy->regs;
224 } else {
225 phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE);
226 if (!phy->pad_regs) {
227 pr_err("%s: can't remap usb registers\n", __func__);
228 clk_put(phy->pad_clk);
229 return -ENOMEM;
230 }
231 }
232 return 0;
233}
234
235static void utmip_pad_close(struct tegra_usb_phy *phy)
236{
237 if (phy->instance != 0)
238 iounmap(phy->pad_regs);
239 clk_put(phy->pad_clk);
240}
241
242static void utmip_pad_power_on(struct tegra_usb_phy *phy)
243{
244 unsigned long val, flags;
245 void __iomem *base = phy->pad_regs;
246
247 clk_enable(phy->pad_clk);
248
249 spin_lock_irqsave(&utmip_pad_lock, flags);
250
251 if (utmip_pad_count++ == 0) {
252 val = readl(base + UTMIP_BIAS_CFG0);
253 val &= ~(UTMIP_OTGPD | UTMIP_BIASPD);
254 writel(val, base + UTMIP_BIAS_CFG0);
255 }
256
257 spin_unlock_irqrestore(&utmip_pad_lock, flags);
258
259 clk_disable(phy->pad_clk);
260}
261
262static int utmip_pad_power_off(struct tegra_usb_phy *phy)
263{
264 unsigned long val, flags;
265 void __iomem *base = phy->pad_regs;
266
267 if (!utmip_pad_count) {
268 pr_err("%s: utmip pad already powered off\n", __func__);
269 return -EINVAL;
270 }
271
272 clk_enable(phy->pad_clk);
273
274 spin_lock_irqsave(&utmip_pad_lock, flags);
275
276 if (--utmip_pad_count == 0) {
277 val = readl(base + UTMIP_BIAS_CFG0);
278 val |= UTMIP_OTGPD | UTMIP_BIASPD;
279 writel(val, base + UTMIP_BIAS_CFG0);
280 }
281
282 spin_unlock_irqrestore(&utmip_pad_lock, flags);
283
284 clk_disable(phy->pad_clk);
285
286 return 0;
287}
288
289static int utmi_wait_register(void __iomem *reg, u32 mask, u32 result)
290{
291 unsigned long timeout = 2000;
292 do {
293 if ((readl(reg) & mask) == result)
294 return 0;
295 udelay(1);
296 timeout--;
297 } while (timeout);
298 return -1;
299}
300
301static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
302{
303 unsigned long val;
304 void __iomem *base = phy->regs;
305
306 if (phy->instance == 0) {
307 val = readl(base + USB_SUSP_CTRL);
308 val |= USB_SUSP_SET;
309 writel(val, base + USB_SUSP_CTRL);
310
311 udelay(10);
312
313 val = readl(base + USB_SUSP_CTRL);
314 val &= ~USB_SUSP_SET;
315 writel(val, base + USB_SUSP_CTRL);
316 }
317
318 if (phy->instance == 2) {
319 val = readl(base + USB_PORTSC1);
320 val |= USB_PORTSC1_PHCD;
321 writel(val, base + USB_PORTSC1);
322 }
323
324 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0)
325 pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
326}
327
328static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
329{
330 unsigned long val;
331 void __iomem *base = phy->regs;
332
333 if (phy->instance == 0) {
334 val = readl(base + USB_SUSP_CTRL);
335 val |= USB_SUSP_CLR;
336 writel(val, base + USB_SUSP_CTRL);
337
338 udelay(10);
339
340 val = readl(base + USB_SUSP_CTRL);
341 val &= ~USB_SUSP_CLR;
342 writel(val, base + USB_SUSP_CTRL);
343 }
344
345 if (phy->instance == 2) {
346 val = readl(base + USB_PORTSC1);
347 val &= ~USB_PORTSC1_PHCD;
348 writel(val, base + USB_PORTSC1);
349 }
350
351 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
352 USB_PHY_CLK_VALID))
353 pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
354}
355
356static int utmi_phy_power_on(struct tegra_usb_phy *phy)
357{
358 unsigned long val;
359 void __iomem *base = phy->regs;
360 struct tegra_utmip_config *config = phy->config;
361
362 val = readl(base + USB_SUSP_CTRL);
363 val |= UTMIP_RESET;
364 writel(val, base + USB_SUSP_CTRL);
365
366 if (phy->instance == 0) {
367 val = readl(base + USB1_LEGACY_CTRL);
368 val |= USB1_NO_LEGACY_MODE;
369 writel(val, base + USB1_LEGACY_CTRL);
370 }
371
372 val = readl(base + UTMIP_TX_CFG0);
373 val &= ~UTMIP_FS_PREABMLE_J;
374 writel(val, base + UTMIP_TX_CFG0);
375
376 val = readl(base + UTMIP_HSRX_CFG0);
377 val &= ~(UTMIP_IDLE_WAIT(~0) | UTMIP_ELASTIC_LIMIT(~0));
378 val |= UTMIP_IDLE_WAIT(config->idle_wait_delay);
379 val |= UTMIP_ELASTIC_LIMIT(config->elastic_limit);
380 writel(val, base + UTMIP_HSRX_CFG0);
381
382 val = readl(base + UTMIP_HSRX_CFG1);
383 val &= ~UTMIP_HS_SYNC_START_DLY(~0);
384 val |= UTMIP_HS_SYNC_START_DLY(config->hssync_start_delay);
385 writel(val, base + UTMIP_HSRX_CFG1);
386
387 val = readl(base + UTMIP_DEBOUNCE_CFG0);
388 val &= ~UTMIP_BIAS_DEBOUNCE_A(~0);
389 val |= UTMIP_BIAS_DEBOUNCE_A(phy->freq->debounce);
390 writel(val, base + UTMIP_DEBOUNCE_CFG0);
391
392 val = readl(base + UTMIP_MISC_CFG0);
393 val &= ~UTMIP_SUSPEND_EXIT_ON_EDGE;
394 writel(val, base + UTMIP_MISC_CFG0);
395
396 val = readl(base + UTMIP_MISC_CFG1);
397 val &= ~(UTMIP_PLL_ACTIVE_DLY_COUNT(~0) | UTMIP_PLLU_STABLE_COUNT(~0));
398 val |= UTMIP_PLL_ACTIVE_DLY_COUNT(phy->freq->active_delay) |
399 UTMIP_PLLU_STABLE_COUNT(phy->freq->stable_count);
400 writel(val, base + UTMIP_MISC_CFG1);
401
402 val = readl(base + UTMIP_PLL_CFG1);
403 val &= ~(UTMIP_XTAL_FREQ_COUNT(~0) | UTMIP_PLLU_ENABLE_DLY_COUNT(~0));
404 val |= UTMIP_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count) |
405 UTMIP_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay);
406 writel(val, base + UTMIP_PLL_CFG1);
407
408 if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
409 val = readl(base + USB_SUSP_CTRL);
410 val &= ~(USB_WAKE_ON_CNNT_EN_DEV | USB_WAKE_ON_DISCON_EN_DEV);
411 writel(val, base + USB_SUSP_CTRL);
412 }
413
414 utmip_pad_power_on(phy);
415
416 val = readl(base + UTMIP_XCVR_CFG0);
417 val &= ~(UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN |
418 UTMIP_FORCE_PDZI_POWERDOWN | UTMIP_XCVR_SETUP(~0) |
419 UTMIP_XCVR_LSFSLEW(~0) | UTMIP_XCVR_LSRSLEW(~0) |
420 UTMIP_XCVR_HSSLEW_MSB(~0));
421 val |= UTMIP_XCVR_SETUP(config->xcvr_setup);
422 val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew);
423 val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew);
424 writel(val, base + UTMIP_XCVR_CFG0);
425
426 val = readl(base + UTMIP_XCVR_CFG1);
427 val &= ~(UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN |
428 UTMIP_FORCE_PDDR_POWERDOWN | UTMIP_XCVR_TERM_RANGE_ADJ(~0));
429 val |= UTMIP_XCVR_TERM_RANGE_ADJ(config->term_range_adj);
430 writel(val, base + UTMIP_XCVR_CFG1);
431
432 val = readl(base + UTMIP_BAT_CHRG_CFG0);
433 val &= ~UTMIP_PD_CHRG;
434 writel(val, base + UTMIP_BAT_CHRG_CFG0);
435
436 val = readl(base + UTMIP_BIAS_CFG1);
437 val &= ~UTMIP_BIAS_PDTRK_COUNT(~0);
438 val |= UTMIP_BIAS_PDTRK_COUNT(0x5);
439 writel(val, base + UTMIP_BIAS_CFG1);
440
441 if (phy->instance == 0) {
442 val = readl(base + UTMIP_SPARE_CFG0);
443 if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE)
444 val &= ~FUSE_SETUP_SEL;
445 else
446 val |= FUSE_SETUP_SEL;
447 writel(val, base + UTMIP_SPARE_CFG0);
448 }
449
450 if (phy->instance == 2) {
451 val = readl(base + USB_SUSP_CTRL);
452 val |= UTMIP_PHY_ENABLE;
453 writel(val, base + USB_SUSP_CTRL);
454 }
455
456 val = readl(base + USB_SUSP_CTRL);
457 val &= ~UTMIP_RESET;
458 writel(val, base + USB_SUSP_CTRL);
459
460 if (phy->instance == 0) {
461 val = readl(base + USB1_LEGACY_CTRL);
462 val &= ~USB1_VBUS_SENSE_CTL_MASK;
463 val |= USB1_VBUS_SENSE_CTL_A_SESS_VLD;
464 writel(val, base + USB1_LEGACY_CTRL);
465
466 val = readl(base + USB_SUSP_CTRL);
467 val &= ~USB_SUSP_SET;
468 writel(val, base + USB_SUSP_CTRL);
469 }
470
471 utmi_phy_clk_enable(phy);
472
473 if (phy->instance == 2) {
474 val = readl(base + USB_PORTSC1);
475 val &= ~USB_PORTSC1_PTS(~0);
476 writel(val, base + USB_PORTSC1);
477 }
478
479 return 0;
480}
481
482static void utmi_phy_power_off(struct tegra_usb_phy *phy)
483{
484 unsigned long val;
485 void __iomem *base = phy->regs;
486
487 utmi_phy_clk_disable(phy);
488
489 if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
490 val = readl(base + USB_SUSP_CTRL);
491 val &= ~USB_WAKEUP_DEBOUNCE_COUNT(~0);
492 val |= USB_WAKE_ON_CNNT_EN_DEV | USB_WAKEUP_DEBOUNCE_COUNT(5);
493 writel(val, base + USB_SUSP_CTRL);
494 }
495
496 val = readl(base + USB_SUSP_CTRL);
497 val |= UTMIP_RESET;
498 writel(val, base + USB_SUSP_CTRL);
499
500 val = readl(base + UTMIP_BAT_CHRG_CFG0);
501 val |= UTMIP_PD_CHRG;
502 writel(val, base + UTMIP_BAT_CHRG_CFG0);
503
504 val = readl(base + UTMIP_XCVR_CFG0);
505 val |= UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN |
506 UTMIP_FORCE_PDZI_POWERDOWN;
507 writel(val, base + UTMIP_XCVR_CFG0);
508
509 val = readl(base + UTMIP_XCVR_CFG1);
510 val |= UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN |
511 UTMIP_FORCE_PDDR_POWERDOWN;
512 writel(val, base + UTMIP_XCVR_CFG1);
513
514 utmip_pad_power_off(phy);
515}
516
517static void utmi_phy_preresume(struct tegra_usb_phy *phy)
518{
519 unsigned long val;
520 void __iomem *base = phy->regs;
521
522 val = readl(base + UTMIP_TX_CFG0);
523 val |= UTMIP_HS_DISCON_DISABLE;
524 writel(val, base + UTMIP_TX_CFG0);
525}
526
527static void utmi_phy_postresume(struct tegra_usb_phy *phy)
528{
529 unsigned long val;
530 void __iomem *base = phy->regs;
531
532 val = readl(base + UTMIP_TX_CFG0);
533 val &= ~UTMIP_HS_DISCON_DISABLE;
534 writel(val, base + UTMIP_TX_CFG0);
535}
536
537static void utmi_phy_restore_start(struct tegra_usb_phy *phy,
538 enum tegra_usb_phy_port_speed port_speed)
539{
540 unsigned long val;
541 void __iomem *base = phy->regs;
542
543 val = readl(base + UTMIP_MISC_CFG0);
544 val &= ~UTMIP_DPDM_OBSERVE_SEL(~0);
545 if (port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW)
546 val |= UTMIP_DPDM_OBSERVE_SEL_FS_K;
547 else
548 val |= UTMIP_DPDM_OBSERVE_SEL_FS_J;
549 writel(val, base + UTMIP_MISC_CFG0);
550 udelay(1);
551
552 val = readl(base + UTMIP_MISC_CFG0);
553 val |= UTMIP_DPDM_OBSERVE;
554 writel(val, base + UTMIP_MISC_CFG0);
555 udelay(10);
556}
557
558static void utmi_phy_restore_end(struct tegra_usb_phy *phy)
559{
560 unsigned long val;
561 void __iomem *base = phy->regs;
562
563 val = readl(base + UTMIP_MISC_CFG0);
564 val &= ~UTMIP_DPDM_OBSERVE;
565 writel(val, base + UTMIP_MISC_CFG0);
566 udelay(10);
567}
568
569static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
570{
571 int ret;
572 unsigned long val;
573 void __iomem *base = phy->regs;
574 struct tegra_ulpi_config *config = phy->config;
575
576 gpio_direction_output(config->reset_gpio, 0);
577 msleep(5);
578 gpio_direction_output(config->reset_gpio, 1);
579
580 clk_enable(phy->clk);
581 msleep(1);
582
583 val = readl(base + USB_SUSP_CTRL);
584 val |= UHSIC_RESET;
585 writel(val, base + USB_SUSP_CTRL);
586
587 val = readl(base + ULPI_TIMING_CTRL_0);
588 val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP;
589 writel(val, base + ULPI_TIMING_CTRL_0);
590
591 val = readl(base + USB_SUSP_CTRL);
592 val |= ULPI_PHY_ENABLE;
593 writel(val, base + USB_SUSP_CTRL);
594
595 val = 0;
596 writel(val, base + ULPI_TIMING_CTRL_1);
597
598 val |= ULPI_DATA_TRIMMER_SEL(4);
599 val |= ULPI_STPDIRNXT_TRIMMER_SEL(4);
600 val |= ULPI_DIR_TRIMMER_SEL(4);
601 writel(val, base + ULPI_TIMING_CTRL_1);
602 udelay(10);
603
604 val |= ULPI_DATA_TRIMMER_LOAD;
605 val |= ULPI_STPDIRNXT_TRIMMER_LOAD;
606 val |= ULPI_DIR_TRIMMER_LOAD;
607 writel(val, base + ULPI_TIMING_CTRL_1);
608
609 /* Fix VbusInvalid due to floating VBUS */
610 ret = otg_io_write(phy->ulpi, 0x40, 0x08);
611 if (ret) {
612 pr_err("%s: ulpi write failed\n", __func__);
613 return ret;
614 }
615
616 ret = otg_io_write(phy->ulpi, 0x80, 0x0B);
617 if (ret) {
618 pr_err("%s: ulpi write failed\n", __func__);
619 return ret;
620 }
621
622 val = readl(base + USB_PORTSC1);
623 val |= USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN;
624 writel(val, base + USB_PORTSC1);
625
626 val = readl(base + USB_SUSP_CTRL);
627 val |= USB_SUSP_CLR;
628 writel(val, base + USB_SUSP_CTRL);
629 udelay(100);
630
631 val = readl(base + USB_SUSP_CTRL);
632 val &= ~USB_SUSP_CLR;
633 writel(val, base + USB_SUSP_CTRL);
634
635 return 0;
636}
637
638static void ulpi_phy_power_off(struct tegra_usb_phy *phy)
639{
640 unsigned long val;
641 void __iomem *base = phy->regs;
642 struct tegra_ulpi_config *config = phy->config;
643
644 /* Clear WKCN/WKDS/WKOC wake-on events that can cause the USB
645 * Controller to immediately bring the ULPI PHY out of low power
646 */
647 val = readl(base + USB_PORTSC1);
648 val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN);
649 writel(val, base + USB_PORTSC1);
650
651 gpio_direction_output(config->reset_gpio, 0);
652 clk_disable(phy->clk);
653}
654
655struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
656 void *config, enum tegra_usb_phy_mode phy_mode)
657{
658 struct tegra_usb_phy *phy;
659 struct tegra_ulpi_config *ulpi_config;
660 unsigned long parent_rate;
661 int i;
662 int err;
663
664 phy = kmalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL);
665 if (!phy)
666 return ERR_PTR(-ENOMEM);
667
668 phy->instance = instance;
669 phy->regs = regs;
670 phy->config = config;
671 phy->mode = phy_mode;
672
673 if (!phy->config) {
674 if (phy_is_ulpi(phy)) {
675 pr_err("%s: ulpi phy configuration missing", __func__);
676 err = -EINVAL;
677 goto err0;
678 } else {
679 phy->config = &utmip_default[instance];
680 }
681 }
682
683 phy->pll_u = clk_get_sys(NULL, "pll_u");
684 if (IS_ERR(phy->pll_u)) {
685 pr_err("Can't get pll_u clock\n");
686 err = PTR_ERR(phy->pll_u);
687 goto err0;
688 }
689 clk_enable(phy->pll_u);
690
691 parent_rate = clk_get_rate(clk_get_parent(phy->pll_u));
692 for (i = 0; i < ARRAY_SIZE(tegra_freq_table); i++) {
693 if (tegra_freq_table[i].freq == parent_rate) {
694 phy->freq = &tegra_freq_table[i];
695 break;
696 }
697 }
698 if (!phy->freq) {
699 pr_err("invalid pll_u parent rate %ld\n", parent_rate);
700 err = -EINVAL;
701 goto err1;
702 }
703
704 if (phy_is_ulpi(phy)) {
705 ulpi_config = config;
706 phy->clk = clk_get_sys(NULL, ulpi_config->clk);
707 if (IS_ERR(phy->clk)) {
708 pr_err("%s: can't get ulpi clock\n", __func__);
709 err = -ENXIO;
710 goto err1;
711 }
712 tegra_gpio_enable(ulpi_config->reset_gpio);
713 gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b");
714 gpio_direction_output(ulpi_config->reset_gpio, 0);
715 phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
716 phy->ulpi->io_priv = regs + ULPI_VIEWPORT;
717 } else {
718 err = utmip_pad_open(phy);
719 if (err < 0)
720 goto err1;
721 }
722
723 return phy;
724
725err1:
726 clk_disable(phy->pll_u);
727 clk_put(phy->pll_u);
728err0:
729 kfree(phy);
730 return ERR_PTR(err);
731}
732
733int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
734{
735 if (phy_is_ulpi(phy))
736 return ulpi_phy_power_on(phy);
737 else
738 return utmi_phy_power_on(phy);
739}
740
741void tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
742{
743 if (phy_is_ulpi(phy))
744 ulpi_phy_power_off(phy);
745 else
746 utmi_phy_power_off(phy);
747}
748
749void tegra_usb_phy_preresume(struct tegra_usb_phy *phy)
750{
751 if (!phy_is_ulpi(phy))
752 utmi_phy_preresume(phy);
753}
754
755void tegra_usb_phy_postresume(struct tegra_usb_phy *phy)
756{
757 if (!phy_is_ulpi(phy))
758 utmi_phy_postresume(phy);
759}
760
761void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy,
762 enum tegra_usb_phy_port_speed port_speed)
763{
764 if (!phy_is_ulpi(phy))
765 utmi_phy_restore_start(phy, port_speed);
766}
767
768void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy)
769{
770 if (!phy_is_ulpi(phy))
771 utmi_phy_restore_end(phy);
772}
773
774void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy)
775{
776 if (!phy_is_ulpi(phy))
777 utmi_phy_clk_disable(phy);
778}
779
780void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy)
781{
782 if (!phy_is_ulpi(phy))
783 utmi_phy_clk_enable(phy);
784}
785
786void tegra_usb_phy_close(struct tegra_usb_phy *phy)
787{
788 if (phy_is_ulpi(phy))
789 clk_put(phy->clk);
790 else
791 utmip_pad_close(phy);
792 clk_disable(phy->pll_u);
793 clk_put(phy->pll_u);
794 kfree(phy);
795}