Merge branch 'for-linus' of git://android.kernel.org/kernel/tegra

* 'for-linus' of git://android.kernel.org/kernel/tegra:
[ARM] tegra: add MAINTAINERS entry
[ARM] tegra: harmony: Add harmony board file
[ARM] tegra: add pinmux support
[ARM] tegra: add GPIO support
[ARM] tegra: Add timer support
[ARM] tegra: SMP support
[ARM] tegra: Add clock support
[ARM] tegra: Add IRQ support
[ARM] tegra: initial tegra support

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